eric patch
[coreboot.git] / src / southbridge / intel / esb6300 / esb6300_lpc.c
1 /*
2  * (C) 2004 Linux Networx
3  */
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pci_ids.h>
8 #include <device/pci_ops.h>
9 #include <pc80/mc146818rtc.h>
10 #include <pc80/isa-dma.h>
11 #include <arch/io.h>
12 #include "esb6300.h"
13
14 #define ACPI_BAR 0x40
15 #define GPIO_BAR 0x58
16
17 #define NMI_OFF 0
18 #define MAINBOARD_POWER_OFF 0
19 #define MAINBOARD_POWER_ON  1
20
21 #ifndef MAINBOARD_POWER_ON_AFTER_FAIL
22 #define MAINBOARD_POWER_ON_AFTER_FAIL MAINBOARD_POWER_ON
23 #endif
24
25 #define ALL             (0xff << 24)
26 #define NONE            (0)
27 #define DISABLED        (1 << 16)
28 #define ENABLED         (0 << 16)
29 #define TRIGGER_EDGE    (0 << 15)
30 #define TRIGGER_LEVEL   (1 << 15)
31 #define POLARITY_HIGH   (0 << 13)
32 #define POLARITY_LOW    (1 << 13)
33 #define PHYSICAL_DEST   (0 << 11)
34 #define LOGICAL_DEST    (1 << 11)
35 #define ExtINT          (7 << 8)
36 #define NMI             (4 << 8)
37 #define SMI             (2 << 8)
38 #define INT             (1 << 8)
39
40 static void setup_ioapic(device_t dev)
41 {
42         int i;
43         unsigned long value_low, value_high;
44         unsigned long ioapic_base = 0xfec00000;
45         volatile unsigned long *l;
46         unsigned interrupts;
47
48         l = (unsigned long *) ioapic_base;
49
50         l[0] = 0x01;
51         interrupts = (l[04] >> 16) & 0xff;
52         for (i = 0; i < interrupts; i++) {
53                 l[0] = (i * 2) + 0x10;
54                 l[4] = DISABLED;
55                 value_low = l[4];
56                 l[0] = (i * 2) + 0x11;
57                 l[4] = NONE; /* Should this be an address? */
58                 value_high = l[4];
59                 if (value_low == 0xffffffff) {
60                         printk_warning("%d IO APIC not responding.\n",
61                                 dev_path(dev));
62                         return;
63                 }
64         }
65
66         /* Put the ioapic in virtual wire mode */
67         l[0] = 0 + 0x10;
68         l[4] = ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT;
69 }
70
71 #define SERIRQ_CNTL 0x64
72 static void esb6300_enable_serial_irqs(device_t dev)
73 {
74         /* set packet length and toggle silent mode bit */
75         pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
76         pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
77 }
78
79 #define PCI_DMA_CFG 0x90
80 static void esb6300_pci_dma_cfg(device_t dev)
81 {
82         /* Set PCI DMA CFG to lpc I/F DMA */
83         pci_write_config16(dev, PCI_DMA_CFG, 0xfcff);
84 }
85
86 #define LPC_EN 0xe6
87 static void esb6300_enable_lpc(device_t dev)
88 {
89         /* lpc i/f enable */
90         pci_write_config8(dev, LPC_EN, 0x0d);
91 }
92
93 typedef struct southbridge_intel_esb6300_config config_t;
94
95 static void set_esb6300_gpio_use_sel(
96         device_t dev, struct resource *res, config_t *config)
97 {
98         uint32_t gpio_use_sel, gpio_use_sel2;
99         int i;
100
101 //      gpio_use_sel  = 0x1B003100;
102 //      gpio_use_sel2 = 0x03000000;
103         gpio_use_sel  = 0x1BBC31C0;
104         gpio_use_sel2 = 0x03000FE1;
105 #if 0
106         for(i = 0; i < 64; i++) {
107                 int val;
108                 switch(config->gpio[i] & ESB6300_GPIO_USE_MASK) {
109                 case ESB6300_GPIO_USE_AS_NATIVE: val = 0; break;
110                 case ESB6300_GPIO_USE_AS_GPIO:   val = 1; break;
111                 default:
112                         continue;
113                 }
114                 /* The caller is responsible for not playing with unimplemented bits */
115                 if (i < 32) {
116                         gpio_use_sel  &= ~( 1 << i);
117                         gpio_use_sel  |= (val << i);
118                 } else {
119                         gpio_use_sel2 &= ~( 1 << (i - 32));
120                         gpio_use_sel2 |= (val << (i - 32));
121                 }
122         }
123 #endif
124         outl(gpio_use_sel,  res->base + 0x00);
125         outl(gpio_use_sel2, res->base + 0x30);
126 }
127
128 static void set_esb6300_gpio_direction(
129         device_t dev, struct resource *res, config_t *config)
130 {
131         uint32_t gpio_io_sel, gpio_io_sel2;
132         int i;
133
134 //      gpio_io_sel  = 0x0000ffff;
135 //      gpio_io_sel2 = 0x00000000;
136         gpio_io_sel  = 0x1900ffff;
137         gpio_io_sel2 = 0x00000fe1;
138 #if 0
139         for(i = 0; i < 64; i++) {
140                 int val;
141                 switch(config->gpio[i] & ESB6300_GPIO_SEL_MASK) {
142                 case ESB6300_GPIO_SEL_OUTPUT: val = 0; break;
143                 case ESB6300_GPIO_SEL_INPUT:  val = 1; break;
144                 default: 
145                         continue;
146                 }
147                 /* The caller is responsible for not playing with unimplemented bits */
148                 if (i < 32) {
149                         gpio_io_sel  &= ~( 1 << i);
150                         gpio_io_sel  |= (val << i);
151                 } else {
152                         gpio_io_sel2 &= ~( 1 << (i - 32));
153                         gpio_io_sel2 |= (val << (i - 32));
154                 }
155         }
156 #endif
157         outl(gpio_io_sel,  res->base + 0x04);
158         outl(gpio_io_sel2, res->base + 0x34);
159 }
160
161 static void set_esb6300_gpio_level(
162         device_t dev, struct resource *res, config_t *config)
163 {
164         uint32_t gpio_lvl, gpio_lvl2;
165         uint32_t gpio_blink;
166         int i;
167
168 //      gpio_lvl   = 0x1b3f0000;
169 //      gpio_blink = 0x00040000;
170 //      gpio_lvl2  = 0x00000fff;
171         gpio_lvl   = 0x19370000;
172         gpio_blink = 0x00000000;
173         gpio_lvl2  = 0x00000fff;
174 #if 0
175         for(i = 0; i < 64; i++) {
176                 int val, blink;
177                 switch(config->gpio[i] & ESB6300_GPIO_LVL_MASK) {
178                 case ESB6300_GPIO_LVL_LOW:   val = 0; blink = 0; break;
179                 case ESB6300_GPIO_LVL_HIGH:  val = 1; blink = 0; break;
180                 case ESB6300_GPIO_LVL_BLINK: val = 1; blink = 1; break;
181                 default: 
182                         continue;
183                 }
184                 /* The caller is responsible for not playing with unimplemented bits */
185                 if (i < 32) {
186                         gpio_lvl   &= ~(   1 << i);
187                         gpio_blink &= ~(   1 << i);
188                         gpio_lvl   |= (  val << i);
189                         gpio_blink |= (blink << i);
190                 } else {
191                         gpio_lvl2  &= ~( 1 << (i - 32));
192                         gpio_lvl2  |= (val << (i - 32));
193                 }
194         }
195 #endif
196         outl(gpio_lvl,   res->base + 0x0c);
197         outl(gpio_blink, res->base + 0x18);
198         outl(gpio_lvl2,  res->base + 0x38);
199 }
200
201 static void set_esb6300_gpio_inv(
202         device_t dev, struct resource *res, config_t *config)
203 {
204         uint32_t gpio_inv;
205         int i;
206
207         gpio_inv   = 0x00003100;
208 #if 0
209         for(i = 0; i < 32; i++) {
210                 int val;
211                 switch(config->gpio[i] & ESB6300_GPIO_INV_MASK) {
212                 case ESB6300_GPIO_INV_OFF: val = 0; break;
213                 case ESB6300_GPIO_INV_ON:  val = 1; break;
214                 default: 
215                         continue;
216                 }
217                 gpio_inv &= ~( 1 << i);
218                 gpio_inv |= (val << i);
219         }
220 #endif
221         outl(gpio_inv,   res->base + 0x2c);
222 }
223
224 static void esb6300_pirq_init(device_t dev)
225 {
226         config_t *config;
227
228         /* Get the chip configuration */
229         config = dev->chip_info;
230
231         if(config->pirq_a_d) {
232                 pci_write_config32(dev, 0x60, config->pirq_a_d);
233         }
234         if(config->pirq_e_h) {
235                 pci_write_config32(dev, 0x68, config->pirq_e_h);
236         }
237 }
238
239
240 static void esb6300_gpio_init(device_t dev)
241 {
242         struct resource *res;
243         config_t *config;
244
245         /* Skip if I don't have any configuration */
246         if (!dev->chip_info) {
247                 return;
248         }
249         /* The programmer is responsible for ensuring
250          * a valid gpio configuration.
251          */
252
253         /* Get the chip configuration */
254         config = dev->chip_info;
255         /* Find the GPIO bar */
256         res = find_resource(dev, GPIO_BAR);
257         if (!res) {
258                 return; 
259         }
260
261         /* Set the use selects */
262         set_esb6300_gpio_use_sel(dev, res, config);
263
264         /* Set the IO direction */
265         set_esb6300_gpio_direction(dev, res, config);
266
267         /* Setup the input inverters */
268         set_esb6300_gpio_inv(dev, res, config);
269
270         /* Set the value on the GPIO output pins */
271         set_esb6300_gpio_level(dev, res, config);
272
273 }
274
275
276 static void lpc_init(struct device *dev)
277 {
278         uint8_t byte;
279         uint32_t value;
280         int pwr_on=MAINBOARD_POWER_ON_AFTER_FAIL;
281
282         /* sata settings */
283         pci_write_config32(dev, 0x58, 0x00001181);
284
285         /* IO APIC initialization */
286         value = pci_read_config32(dev, 0xd0);
287         value |= (1 << 8)|(1<<7);
288         value |= (6 << 0)|(1<<13)|(1<<11);
289         pci_write_config32(dev, 0xd0, value);
290         setup_ioapic(dev);
291
292         /* disable reset timer */
293         pci_write_config8(dev, 0xd4, 0x02);
294
295         /* cmos ram 2nd 128 */
296         pci_write_config8(dev, 0xd8, 0x04);
297
298         /* comm 2 */
299         pci_write_config8(dev, 0xe0, 0x10);
300
301         /* fwh sellect */
302         pci_write_config32(dev, 0xe8, 0x00112233);
303
304         /* fwh decode */
305         pci_write_config8(dev, 0xf0, 0x0f);
306
307         /* av disable, sata controller */
308         pci_write_config8(dev, 0xf2, 0xc0);
309
310         /* undocumented */
311         pci_write_config8(dev, 0xa0, 0x20);
312         pci_write_config8(dev, 0xad, 0x03);
313         pci_write_config8(dev, 0xbb, 0x09);
314
315         /* apic1 rout */
316         pci_write_config8(dev, 0xf4, 0x40);
317
318         /* undocumented */
319         pci_write_config8(dev, 0xa0, 0x20);
320         pci_write_config8(dev, 0xad, 0x03);
321         pci_write_config8(dev, 0xbb, 0x09);
322         
323         esb6300_enable_serial_irqs(dev);
324
325         esb6300_pci_dma_cfg(dev);
326
327         esb6300_enable_lpc(dev);
328
329         get_option(&pwr_on, "power_on_after_fail");
330         byte = pci_read_config8(dev, 0xa4);
331         byte &= 0xfe;
332         if (!pwr_on) {
333                 byte |= 1;
334         }
335         pci_write_config8(dev, 0xa4, byte);
336         printk_info("set power %s after power fail\n", pwr_on?"on":"off");
337
338         /* Set up the PIRQ */
339         esb6300_pirq_init(dev);
340         
341         /* Set the state of the gpio lines */
342         esb6300_gpio_init(dev);
343
344         /* Initialize the real time clock */
345         rtc_init(0);
346
347         /* Initialize isa dma */
348         isa_dma_init();
349 }
350
351 static void esb6300_lpc_read_resources(device_t dev)
352 {
353         struct resource *res;
354
355         /* Get the normal pci resources of this device */
356         pci_dev_read_resources(dev);
357
358         /* Add the ACPI BAR */
359         res = pci_get_resource(dev, ACPI_BAR);
360
361         /* Add the GPIO BAR */
362         res = pci_get_resource(dev, GPIO_BAR);
363
364         /* Add an extra subtractive resource for both memory and I/O */
365         res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
366         res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
367
368         res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
369         res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
370 }
371
372 static void esb6300_lpc_enable_resources(device_t dev)
373 {
374         uint8_t acpi_cntl, gpio_cntl;
375
376         /* Enable the normal pci resources */
377         pci_dev_enable_resources(dev);
378
379         /* Enable the ACPI bar */
380         acpi_cntl = pci_read_config8(dev, 0x44);
381         acpi_cntl |= (1 << 4);
382         pci_write_config8(dev, 0x44, acpi_cntl);
383         
384         /* Enable the GPIO bar */
385         gpio_cntl = pci_read_config8(dev, 0x5c);
386         gpio_cntl |= (1 << 4);
387         pci_write_config8(dev, 0x5c, gpio_cntl);
388
389         enable_childrens_resources(dev);
390 }
391
392 static struct pci_operations lops_pci = {
393         .set_subsystem = 0,
394 };
395
396 static struct device_operations lpc_ops  = {
397         .read_resources   = esb6300_lpc_read_resources,
398         .set_resources    = pci_dev_set_resources,
399         .enable_resources = esb6300_lpc_enable_resources,
400         .init             = lpc_init,
401         .scan_bus         = scan_static_bus,
402         .enable           = esb6300_enable,
403         .ops_pci          = &lops_pci,
404 };
405
406 static struct pci_driver lpc_driver __pci_driver = {
407         .ops    = &lpc_ops,
408         .vendor = PCI_VENDOR_ID_INTEL,
409         .device = PCI_DEVICE_ID_INTEL_6300ESB_ISA,
410 };