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