2 * This file is part of the coreboot project.
4 * Copyright (C) 2004 Linux Networx
5 * Copyright (C) 2008 Arastra, Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 /* This code is based on src/southbridge/intel/esb6300/esb6300_lpc.c */
24 #include <console/console.h>
25 #include <device/device.h>
26 #include <device/pci.h>
27 #include <device/pci_ids.h>
28 #include <device/pci_ops.h>
29 #include <pc80/mc146818rtc.h>
30 #include <pc80/isa-dma.h>
38 #define SERIRQ_CNTL 0x64
40 #define GEN_PMCON_1 0xA0
41 #define GEN_PMCON_2 0xA2
42 #define GEN_PMCON_3 0xA4
45 #define MAINBOARD_POWER_OFF 0
46 #define MAINBOARD_POWER_ON 1
48 #ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
49 #define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
52 #define ALL (0xff << 24)
54 #define DISABLED (1 << 16)
55 #define ENABLED (0 << 16)
56 #define TRIGGER_EDGE (0 << 15)
57 #define TRIGGER_LEVEL (1 << 15)
58 #define POLARITY_HIGH (0 << 13)
59 #define POLARITY_LOW (1 << 13)
60 #define PHYSICAL_DEST (0 << 11)
61 #define LOGICAL_DEST (1 << 11)
62 #define ExtINT (7 << 8)
67 static void setup_ioapic(device_t dev)
70 u32 value_low, value_high;
71 u32 ioapic_base = 0xfec00000;
77 res = find_resource(dev, RCBA);
81 *((u8 *)(res->base + 0x31ff)) |= (1 << 0);
83 l = (u32 *) ioapic_base;
86 interrupts = (l[04] >> 16) & 0xff;
87 for (i = 0; i < interrupts; i++) {
88 l[0] = (i * 2) + 0x10;
91 l[0] = (i * 2) + 0x11;
92 l[4] = NONE; /* Should this be an address? */
94 if (value_low == 0xffffffff) {
95 printk_warning("%d IO APIC not responding.\n",
101 /* Put the APIC in virtual wire mode */
103 l[4] = ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT;
106 static void i3100_enable_serial_irqs(device_t dev)
108 /* set packet length and toggle silent mode bit */
109 pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
110 pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
113 typedef struct southbridge_intel_i3100_config config_t;
115 static void set_i3100_gpio_use_sel(
116 device_t dev, struct resource *res, config_t *config)
118 u32 gpio_use_sel, gpio_use_sel2;
121 gpio_use_sel = inl(res->base + 0x00) | 0x0000c603;
122 gpio_use_sel2 = inl(res->base + 0x30) | 0x00000100;
123 for (i = 0; i < 64; i++) {
125 switch (config->gpio[i] & I3100_GPIO_USE_MASK) {
126 case I3100_GPIO_USE_AS_NATIVE:
129 case I3100_GPIO_USE_AS_GPIO:
135 /* The caller is responsible for not playing with unimplemented bits */
137 gpio_use_sel &= ~(1 << i);
138 gpio_use_sel |= (val << i);
140 gpio_use_sel2 &= ~(1 << (i - 32));
141 gpio_use_sel2 |= (val << (i - 32));
144 outl(gpio_use_sel, res->base + 0x00);
145 outl(gpio_use_sel2, res->base + 0x30);
148 static void set_i3100_gpio_direction(
149 device_t dev, struct resource *res, config_t *config)
151 u32 gpio_io_sel, gpio_io_sel2;
154 gpio_io_sel = inl(res->base + 0x04);
155 gpio_io_sel2 = inl(res->base + 0x34);
156 for (i = 0; i < 64; i++) {
158 switch (config->gpio[i] & I3100_GPIO_SEL_MASK) {
159 case I3100_GPIO_SEL_OUTPUT:
162 case I3100_GPIO_SEL_INPUT:
168 /* The caller is responsible for not playing with unimplemented bits */
170 gpio_io_sel &= ~(1 << i);
171 gpio_io_sel |= (val << i);
173 gpio_io_sel2 &= ~(1 << (i - 32));
174 gpio_io_sel2 |= (val << (i - 32));
177 outl(gpio_io_sel, res->base + 0x04);
178 outl(gpio_io_sel2, res->base + 0x34);
181 static void set_i3100_gpio_level(
182 device_t dev, struct resource *res, config_t *config)
184 u32 gpio_lvl, gpio_lvl2;
188 gpio_lvl = inl(res->base + 0x0c);
189 gpio_blink = inl(res->base + 0x18);
190 gpio_lvl2 = inl(res->base + 0x38);
191 for (i = 0; i < 64; i++) {
193 switch (config->gpio[i] & I3100_GPIO_LVL_MASK) {
194 case I3100_GPIO_LVL_LOW:
198 case I3100_GPIO_LVL_HIGH:
202 case I3100_GPIO_LVL_BLINK:
209 /* The caller is responsible for not playing with unimplemented bits */
211 gpio_lvl &= ~(1 << i);
212 gpio_blink &= ~(1 << i);
213 gpio_lvl |= (val << i);
214 gpio_blink |= (blink << i);
216 gpio_lvl2 &= ~(1 << (i - 32));
217 gpio_lvl2 |= (val << (i - 32));
220 outl(gpio_lvl, res->base + 0x0c);
221 outl(gpio_blink, res->base + 0x18);
222 outl(gpio_lvl2, res->base + 0x38);
225 static void set_i3100_gpio_inv(
226 device_t dev, struct resource *res, config_t *config)
231 gpio_inv = inl(res->base + 0x2c);
232 for (i = 0; i < 32; i++) {
234 switch (config->gpio[i] & I3100_GPIO_INV_MASK) {
235 case I3100_GPIO_INV_OFF:
238 case I3100_GPIO_INV_ON:
244 gpio_inv &= ~(1 << i);
245 gpio_inv |= (val << i);
247 outl(gpio_inv, res->base + 0x2c);
250 static void i3100_pirq_init(device_t dev)
254 /* Get the chip configuration */
255 config = dev->chip_info;
257 if(config->pirq_a_d) {
258 pci_write_config32(dev, 0x60, config->pirq_a_d);
260 if(config->pirq_e_h) {
261 pci_write_config32(dev, 0x68, config->pirq_e_h);
265 static void i3100_power_options(device_t dev) {
268 int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
271 /* Which state do we want to goto after g3 (power restored)?
275 get_option(&pwr_on, "power_on_after_fail");
276 reg8 = pci_read_config8(dev, GEN_PMCON_3);
283 /* avoid #S4 assertions */
285 /* minimum asssertion is 1 to 2 RTCCLK */
287 pci_write_config8(dev, GEN_PMCON_3, reg8);
288 printk_info("set power %s after power fail\n", pwr_on ? "on" : "off");
290 /* Set up NMI on errors. */
292 /* Higher Nibble must be 0 */
294 /* IOCHK# NMI Enable */
296 /* PCI SERR# Enable */
297 // reg8 &= ~(1 << 2);
298 /* PCI SERR# Disable for now */
303 nmi_option = NMI_OFF;
304 get_option(&nmi_option, "nmi");
307 printk_info ("NMI sources enabled.\n");
310 /* Can't mask NMI from PCI-E and NMI_NOW */
311 printk_info ("NMI sources disabled.\n");
316 // Enable CPU_SLP# and Intel Speedstep, set SMI# rate down
317 reg16 = pci_read_config16(dev, GEN_PMCON_1);
318 reg16 &= ~((3 << 0) | (1 << 10));
319 reg16 |= (1 << 3) | (1 << 5);
321 // reg16 |= (1 << 2);
322 pci_write_config16(dev, GEN_PMCON_1, reg16);
324 // Set the board's GPI routing.
325 // i82801gx_gpi_routing(dev);
328 static void i3100_gpio_init(device_t dev)
330 struct resource *res;
333 /* Skip if I don't have any configuration */
334 if (!dev->chip_info) {
337 /* The programmer is responsible for ensuring
338 * a valid gpio configuration.
341 /* Get the chip configuration */
342 config = dev->chip_info;
343 /* Find the GPIO bar */
344 res = find_resource(dev, GPIO_BAR);
349 /* Set the use selects */
350 set_i3100_gpio_use_sel(dev, res, config);
352 /* Set the IO direction */
353 set_i3100_gpio_direction(dev, res, config);
355 /* Setup the input inverters */
356 set_i3100_gpio_inv(dev, res, config);
358 /* Set the value on the GPIO output pins */
359 set_i3100_gpio_level(dev, res, config);
364 static void lpc_init(struct device *dev)
368 /* Decode 0xffc00000 - 0xffffffff to fwh idsel 0 */
369 pci_write_config32(dev, 0xd0, 0x00000000);
371 i3100_enable_serial_irqs(dev);
373 /* Set up the PIRQ */
374 i3100_pirq_init(dev);
376 /* Setup power options */
377 i3100_power_options(dev);
379 /* Set the state of the gpio lines */
380 i3100_gpio_init(dev);
382 /* Initialize the real time clock */
385 /* Initialize isa dma */
389 static void i3100_lpc_read_resources(device_t dev)
391 struct resource *res;
393 /* Get the normal pci resources of this device */
394 pci_dev_read_resources(dev);
396 /* Add the ACPI BAR */
397 res = pci_get_resource(dev, ACPI_BAR);
399 /* Add the GPIO BAR */
400 res = pci_get_resource(dev, GPIO_BAR);
402 /* Add an extra subtractive resource for both memory and I/O */
403 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
404 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
406 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
407 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
409 /* Add resource for RCBA */
410 res = new_resource(dev, RCBA);
412 res->limit = 0xffffc000;
415 res->flags = IORESOURCE_MEM;
418 static void i3100_lpc_enable_resources(device_t dev)
420 u8 acpi_cntl, gpio_cntl;
422 /* Enable the normal pci resources */
423 pci_dev_enable_resources(dev);
425 /* Enable the ACPI bar */
426 acpi_cntl = pci_read_config8(dev, 0x44);
427 acpi_cntl |= (1 << 7);
428 pci_write_config8(dev, 0x44, acpi_cntl);
430 /* Enable the GPIO bar */
431 gpio_cntl = pci_read_config8(dev, 0x4c);
432 gpio_cntl |= (1 << 4);
433 pci_write_config8(dev, 0x4c, gpio_cntl);
435 /* Enable the RCBA */
436 pci_write_config32(dev, RCBA, pci_read_config32(dev, RCBA) | (1 << 0));
438 enable_childrens_resources(dev);
441 static struct pci_operations lops_pci = {
445 static struct device_operations lpc_ops = {
446 .read_resources = i3100_lpc_read_resources,
447 .set_resources = pci_dev_set_resources,
448 .enable_resources = i3100_lpc_enable_resources,
450 .scan_bus = scan_static_bus,
451 .enable = i3100_enable,
452 .ops_pci = &lops_pci,
455 static struct pci_driver lpc_driver __pci_driver = {
457 .vendor = PCI_VENDOR_ID_INTEL,
458 .device = PCI_DEVICE_ID_INTEL_3100_LPC,
461 static struct pci_driver lpc_driver_ep80579 __pci_driver = {
463 .vendor = PCI_VENDOR_ID_INTEL,
464 .device = PCI_DEVICE_ID_INTEL_EP80579_LPC,