2 * (C) 2004 Linux Networx
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>
12 #include <arch/ioapic.h>
19 #define MAINBOARD_POWER_OFF 0
20 #define MAINBOARD_POWER_ON 1
22 #ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
23 #define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
26 #define SERIRQ_CNTL 0x64
27 static void esb6300_enable_serial_irqs(device_t dev)
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));
34 #define PCI_DMA_CFG 0x90
35 static void esb6300_pci_dma_cfg(device_t dev)
37 /* Set PCI DMA CFG to lpc I/F DMA */
38 pci_write_config16(dev, PCI_DMA_CFG, 0xfcff);
42 static void esb6300_enable_lpc(device_t dev)
45 pci_write_config8(dev, LPC_EN, 0x0d);
48 typedef struct southbridge_intel_esb6300_config config_t;
50 static void set_esb6300_gpio_use_sel(
51 device_t dev, struct resource *res, config_t *config)
53 uint32_t gpio_use_sel, gpio_use_sel2;
55 // gpio_use_sel = 0x1B003100;
56 // gpio_use_sel2 = 0x03000000;
57 gpio_use_sel = 0x1BBC31C0;
58 gpio_use_sel2 = 0x03000FE1;
61 for(i = 0; i < 64; i++) {
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;
69 /* The caller is responsible for not playing with unimplemented bits */
71 gpio_use_sel &= ~( 1 << i);
72 gpio_use_sel |= (val << i);
74 gpio_use_sel2 &= ~( 1 << (i - 32));
75 gpio_use_sel2 |= (val << (i - 32));
79 outl(gpio_use_sel, res->base + 0x00);
80 outl(gpio_use_sel2, res->base + 0x30);
83 static void set_esb6300_gpio_direction(
84 device_t dev, struct resource *res, config_t *config)
86 uint32_t gpio_io_sel, gpio_io_sel2;
88 // gpio_io_sel = 0x0000ffff;
89 // gpio_io_sel2 = 0x00000000;
90 gpio_io_sel = 0x1900ffff;
91 gpio_io_sel2 = 0x00000fe1;
94 for(i = 0; i < 64; i++) {
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;
102 /* The caller is responsible for not playing with unimplemented bits */
104 gpio_io_sel &= ~( 1 << i);
105 gpio_io_sel |= (val << i);
107 gpio_io_sel2 &= ~( 1 << (i - 32));
108 gpio_io_sel2 |= (val << (i - 32));
112 outl(gpio_io_sel, res->base + 0x04);
113 outl(gpio_io_sel2, res->base + 0x34);
116 static void set_esb6300_gpio_level(
117 device_t dev, struct resource *res, config_t *config)
119 uint32_t gpio_lvl, gpio_lvl2;
122 // gpio_lvl = 0x1b3f0000;
123 // gpio_blink = 0x00040000;
124 // gpio_lvl2 = 0x00000fff;
125 gpio_lvl = 0x19370000;
126 gpio_blink = 0x00000000;
127 gpio_lvl2 = 0x00000fff;
130 for(i = 0; i < 64; i++) {
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;
139 /* The caller is responsible for not playing with unimplemented bits */
141 gpio_lvl &= ~( 1 << i);
142 gpio_blink &= ~( 1 << i);
143 gpio_lvl |= ( val << i);
144 gpio_blink |= (blink << i);
146 gpio_lvl2 &= ~( 1 << (i - 32));
147 gpio_lvl2 |= (val << (i - 32));
151 outl(gpio_lvl, res->base + 0x0c);
152 outl(gpio_blink, res->base + 0x18);
153 outl(gpio_lvl2, res->base + 0x38);
156 static void set_esb6300_gpio_inv(
157 device_t dev, struct resource *res, config_t *config)
161 gpio_inv = 0x00003100;
164 for(i = 0; i < 32; i++) {
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;
172 gpio_inv &= ~( 1 << i);
173 gpio_inv |= (val << i);
176 outl(gpio_inv, res->base + 0x2c);
179 static void esb6300_pirq_init(device_t dev)
183 /* Get the chip configuration */
184 config = dev->chip_info;
186 if(config->pirq_a_d) {
187 pci_write_config32(dev, 0x60, config->pirq_a_d);
189 if(config->pirq_e_h) {
190 pci_write_config32(dev, 0x68, config->pirq_e_h);
195 static void esb6300_gpio_init(device_t dev)
197 struct resource *res;
200 /* Skip if I don't have any configuration */
201 if (!dev->chip_info) {
204 /* The programmer is responsible for ensuring
205 * a valid gpio configuration.
208 /* Get the chip configuration */
209 config = dev->chip_info;
210 /* Find the GPIO bar */
211 res = find_resource(dev, GPIO_BAR);
216 /* Set the use selects */
217 set_esb6300_gpio_use_sel(dev, res, config);
219 /* Set the IO direction */
220 set_esb6300_gpio_direction(dev, res, config);
222 /* Setup the input inverters */
223 set_esb6300_gpio_inv(dev, res, config);
225 /* Set the value on the GPIO output pins */
226 set_esb6300_gpio_level(dev, res, config);
231 static void lpc_init(struct device *dev)
235 int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
238 pci_write_config32(dev, 0x58, 0x00001181);
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(0xfec00000, 0); // don't rename IO APIC ID
247 /* disable reset timer */
248 pci_write_config8(dev, 0xd4, 0x02);
250 /* cmos ram 2nd 128 */
251 pci_write_config8(dev, 0xd8, 0x04);
254 pci_write_config8(dev, 0xe0, 0x10);
257 pci_write_config32(dev, 0xe8, 0x00112233);
260 pci_write_config8(dev, 0xf0, 0x0f);
262 /* av disable, sata controller */
263 pci_write_config8(dev, 0xf2, 0xc0);
266 pci_write_config8(dev, 0xa0, 0x20);
267 pci_write_config8(dev, 0xad, 0x03);
268 pci_write_config8(dev, 0xbb, 0x09);
271 pci_write_config8(dev, 0xf4, 0x40);
274 pci_write_config8(dev, 0xa0, 0x20);
275 pci_write_config8(dev, 0xad, 0x03);
276 pci_write_config8(dev, 0xbb, 0x09);
278 esb6300_enable_serial_irqs(dev);
280 esb6300_pci_dma_cfg(dev);
282 esb6300_enable_lpc(dev);
284 get_option(&pwr_on, "power_on_after_fail");
285 byte = pci_read_config8(dev, 0xa4);
290 pci_write_config8(dev, 0xa4, byte);
291 printk(BIOS_INFO, "set power %s after power fail\n", pwr_on?"on":"off");
293 /* Set up the PIRQ */
294 esb6300_pirq_init(dev);
296 /* Set the state of the gpio lines */
297 esb6300_gpio_init(dev);
299 /* Initialize the real time clock */
302 /* Initialize isa dma */
306 static void esb6300_lpc_read_resources(device_t dev)
308 struct resource *res;
310 /* Get the normal pci resources of this device */
311 pci_dev_read_resources(dev);
313 /* Add the ACPI BAR */
314 res = pci_get_resource(dev, ACPI_BAR);
316 /* Add the GPIO BAR */
317 res = pci_get_resource(dev, GPIO_BAR);
319 /* Add an extra subtractive resource for both memory and I/O. */
320 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
323 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
324 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
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;
332 res = new_resource(dev, 3); /* IOAPIC */
333 res->base = 0xfec00000;
334 res->size = 0x00001000;
335 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
338 static void esb6300_lpc_enable_resources(device_t dev)
340 uint8_t acpi_cntl, gpio_cntl;
342 /* Enable the normal pci resources */
343 pci_dev_enable_resources(dev);
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);
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);
356 static struct pci_operations lops_pci = {
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,
365 .scan_bus = scan_static_bus,
366 .enable = esb6300_enable,
367 .ops_pci = &lops_pci,
370 static const struct pci_driver lpc_driver __pci_driver = {
372 .vendor = PCI_VENDOR_ID_INTEL,
373 .device = PCI_DEVICE_ID_INTEL_6300ESB_LPC,