Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/302
-gerrit
commit 9af508bde564d9e72c3184c35efe1c87e14697c3 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Wed Oct 19 13:31:39 2011 +0300
Cleaning i82801 LPC codes
Replace ioapic initialisation with global setup_ioapic() or setup_ioapic_NOVECTORS(). Unify handling of ACPI BARs.
Select IOAPIC as the southbridge has one and now requires that arch/x86/lib/ioapic.c is compiled in.
Change-Id: I8ad80fdd0913995471269f33293c4a4b8cf1de83 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- src/southbridge/intel/i82801ax/Kconfig | 1 + src/southbridge/intel/i82801ax/lpc.c | 39 ++++++++------ src/southbridge/intel/i82801bx/Kconfig | 1 + src/southbridge/intel/i82801bx/lpc.c | 39 ++++++++------ src/southbridge/intel/i82801cx/Kconfig | 1 + src/southbridge/intel/i82801cx/lpc.c | 40 +++++--------- src/southbridge/intel/i82801dx/i82801dx.h | 1 + src/southbridge/intel/i82801dx/lpc.c | 46 +++++++++-------- src/southbridge/intel/i82801ex/i82801ex.h | 9 +++ src/southbridge/intel/i82801ex/lpc.c | 81 +++++++++++++++++++---------- src/southbridge/intel/i82801gx/i82801gx.h | 1 + src/southbridge/intel/i82801gx/lpc.c | 59 +++++++++++---------- 12 files changed, 180 insertions(+), 138 deletions(-)
diff --git a/src/southbridge/intel/i82801ax/Kconfig b/src/southbridge/intel/i82801ax/Kconfig index 70734a7..71ae016 100644 --- a/src/southbridge/intel/i82801ax/Kconfig +++ b/src/southbridge/intel/i82801ax/Kconfig @@ -19,6 +19,7 @@
config SOUTHBRIDGE_INTEL_I82801AX bool + select IOAPIC select HAVE_HARD_RESET select USE_WATCHDOG_ON_BOOT
diff --git a/src/southbridge/intel/i82801ax/lpc.c b/src/southbridge/intel/i82801ax/lpc.c index c9404ed..e1ab141 100644 --- a/src/southbridge/intel/i82801ax/lpc.c +++ b/src/southbridge/intel/i82801ax/lpc.c @@ -70,17 +70,30 @@ typedef struct southbridge_intel_i82801ax_config config_t; * Use the defined IRQ values above or set mainboard * specific IRQ values in your devicetree.cb. */ -static void i82801ax_enable_apic(struct device *dev) -{ - u32 reg32; - volatile u32 *ioapic_index = (volatile u32 *)IO_APIC_ADDR; - volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10); +
+/** + * enable_acpi(dev) + * + * @dev PCI device with ACPI and PM BAR's + */ +static void i82801ax_enable_acpi(struct device *dev) +{ /* Set ACPI base address (I/O space). */ pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
/* Enable ACPI I/O range decode and ACPI power management. */ pci_write_config8(dev, ACPI_CNTL, ACPI_EN); +} + +/** + * enable_ioapic() + * + * @dev PCI device with I/O APIC control registers + */ +static void i82801ax_enable_ioapic(struct device *dev) +{ + u32 reg32;
reg32 = pci_read_config32(dev, GEN_CNTL); reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */ @@ -90,18 +103,7 @@ static void i82801ax_enable_apic(struct device *dev) pci_write_config32(dev, GEN_CNTL, reg32); printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
- *ioapic_index = 0; - *ioapic_data = (1 << 25); - - *ioapic_index = 0; - reg32 = *ioapic_data; - printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32); - if (reg32 != (1 << 25)) - die("APIC Error\n"); - - /* TODO: From i82801ca, needed/useful on other ICH? */ - *ioapic_index = 3; /* Select Boot Configuration register. */ - *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */ + setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02); }
static void i82801ax_enable_serial_irqs(struct device *dev) @@ -219,8 +221,9 @@ static void lpc_init(struct device *dev) /* Set the value for PCI command register. */ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+ i82801ax_enable_acpi(dev); /* IO APIC initialization. */ - i82801ax_enable_apic(dev); + i82801ax_enable_ioapic(dev);
i82801ax_enable_serial_irqs(dev);
diff --git a/src/southbridge/intel/i82801bx/Kconfig b/src/southbridge/intel/i82801bx/Kconfig index 00cb5bf..3d725d4 100644 --- a/src/southbridge/intel/i82801bx/Kconfig +++ b/src/southbridge/intel/i82801bx/Kconfig @@ -19,6 +19,7 @@
config SOUTHBRIDGE_INTEL_I82801BX bool + select IOAPIC select HAVE_HARD_RESET select USE_WATCHDOG_ON_BOOT
diff --git a/src/southbridge/intel/i82801bx/lpc.c b/src/southbridge/intel/i82801bx/lpc.c index 0ff44e6..e2550d7 100644 --- a/src/southbridge/intel/i82801bx/lpc.c +++ b/src/southbridge/intel/i82801bx/lpc.c @@ -72,17 +72,29 @@ typedef struct southbridge_intel_i82801bx_config config_t; * Use the defined IRQ values above or set mainboard * specific IRQ values in your devicetree.cb. */ -static void i82801bx_enable_apic(struct device *dev) -{ - uint32_t reg32; - volatile uint32_t *ioapic_index = (volatile uint32_t *)IO_APIC_ADDR; - volatile uint32_t *ioapic_data = (volatile uint32_t *)(IO_APIC_ADDR + 0x10);
+/** + * enable_acpi(dev) + * + * @dev PCI device with ACPI and PM BAR's + */ +static void i82801bx_enable_acpi(struct device *dev) +{ /* Set ACPI base address (I/O space). */ pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
/* Enable ACPI I/O range decode and ACPI power management. */ pci_write_config8(dev, ACPI_CNTL, ACPI_EN); +} + +/** + * enable_ioapic() + * + * @dev PCI device with I/O APIC control registers + */ +static void i82801bx_enable_ioapic(struct device *dev) +{ + u32 reg32;
reg32 = pci_read_config32(dev, GEN_CNTL); reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */ @@ -92,18 +104,7 @@ static void i82801bx_enable_apic(struct device *dev) pci_write_config32(dev, GEN_CNTL, reg32); printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
- *ioapic_index = 0; - *ioapic_data = (1 << 25); - - *ioapic_index = 0; - reg32 = *ioapic_data; - printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32); - if (reg32 != (1 << 25)) - die("APIC Error\n"); - - /* TODO: From i82801ca, needed/useful on other ICH? */ - *ioapic_index = 3; /* Select Boot Configuration register. */ - *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */ + setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02); }
static void i82801bx_enable_serial_irqs(struct device *dev) @@ -237,8 +238,10 @@ static void lpc_init(struct device *dev) /* Set the value for PCI command register. */ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+ i82801bx_enable_acpi(dev); + /* IO APIC initialization. */ - i82801bx_enable_apic(dev); + i82801bx_enable_ioapic(dev);
i82801bx_enable_serial_irqs(dev);
diff --git a/src/southbridge/intel/i82801cx/Kconfig b/src/southbridge/intel/i82801cx/Kconfig index a0c775d..7534cbb 100644 --- a/src/southbridge/intel/i82801cx/Kconfig +++ b/src/southbridge/intel/i82801cx/Kconfig @@ -1,2 +1,3 @@ config SOUTHBRIDGE_INTEL_I82801CX bool + select IOAPIC diff --git a/src/southbridge/intel/i82801cx/lpc.c b/src/southbridge/intel/i82801cx/lpc.c index a1ffb8f..5bce979 100644 --- a/src/southbridge/intel/i82801cx/lpc.c +++ b/src/southbridge/intel/i82801cx/lpc.c @@ -24,34 +24,24 @@ #define MAINBOARD_POWER_ON 1
-static void i82801cx_enable_ioapic( struct device *dev) +/** + * enable_ioapic() + * + * @dev PCI device with I/O APIC control registers + */ +static void i82801cx_enable_ioapic(struct device *dev) { - uint32_t dword; - volatile uint32_t* ioapic_index = (volatile uint32_t*)IO_APIC_ADDR; - volatile uint32_t* ioapic_data = (volatile uint32_t*)(IO_APIC_ADDR + 0x10); - - dword = pci_read_config32(dev, GEN_CNTL); - dword |= (3 << 7); /* enable ioapic & disable SMBus interrupts */ - dword |= (1 <<13); /* coprocessor error enable */ - dword |= (1 << 1); /* delay transaction enable */ - dword |= (1 << 2); /* DMA collection buf enable */ - pci_write_config32(dev, GEN_CNTL, dword); - printk(BIOS_DEBUG, "ioapic southbridge enabled %x\n",dword); - - // Must program the APIC's ID before using it - - *ioapic_index = 0; // Select APIC ID register - *ioapic_data = (2<<24); - - // Hang if the ID didn't take (chip not present?) - *ioapic_index = 0; - dword = *ioapic_data; - printk(BIOS_DEBUG, "Southbridge apic id = %x\n", (dword>>24) & 0xF); - if(dword != (2<<24)) - die(""); - - *ioapic_index = 3; // Select Boot Configuration register - *ioapic_data = 1; // Use Processor System Bus to deliver interrupts + u32 reg32; + + reg32 = pci_read_config32(dev, GEN_CNTL); + reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */ + reg32 |= (3 << 7); /* IOAPIC enable (APIC_EN) */ + reg32 |= (1 << 2); /* DMA collection buffer enable (DCB_EN) */ + reg32 |= (1 << 1); /* Delayed transaction enable (DTE) */ + pci_write_config32(dev, GEN_CNTL, reg32); + printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32); + + setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02); }
// This is how interrupts are received from the Super I/O chip diff --git a/src/southbridge/intel/i82801dx/i82801dx.h b/src/southbridge/intel/i82801dx/i82801dx.h index a38c793..2484eb1 100644 --- a/src/southbridge/intel/i82801dx/i82801dx.h +++ b/src/southbridge/intel/i82801dx/i82801dx.h @@ -86,6 +86,7 @@ extern void i82801dx_enable(device_t dev); #define PMBASE_ADDR 0x0400 #define DEFAULT_PMBASE PMBASE_ADDR #define ACPI_CNTL 0x44 +#define ACPI_EN (1 << 4) #define BIOS_CNTL 0x4E #define GPIO_BASE 0x58 #define GPIO_CNTL 0x5C diff --git a/src/southbridge/intel/i82801dx/lpc.c b/src/southbridge/intel/i82801dx/lpc.c index 768e700..eb05881 100644 --- a/src/southbridge/intel/i82801dx/lpc.c +++ b/src/southbridge/intel/i82801dx/lpc.c @@ -36,37 +36,38 @@
typedef struct southbridge_intel_i82801dx_config config_t;
-static void i82801dx_enable_ioapic(struct device *dev) +/** + * enable_acpi(dev) + * + * @dev PCI device with ACPI and PM BAR's + */ +static void i82801dx_enable_acpi(struct device *dev) { - u32 reg32; - volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR); - volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10); - /* Set ACPI base address (I/O space). */ pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
- /* Enable ACPI I/O and power management. */ - pci_write_config8(dev, ACPI_CNTL, 0x10); + /* Enable ACPI I/O range decode and ACPI power management. */ + pci_write_config8(dev, ACPI_CNTL, ACPI_EN); +} + +/** + * enable_ioapic() + * + * @dev PCI device with I/O APIC control registers + */ +static void i82801dx_enable_ioapic(struct device *dev) +{ + u32 reg32;
reg32 = pci_read_config32(dev, GEN_CNTL); - reg32 |= (3 << 7); /* Enable IOAPIC */ - reg32 |= (1 << 13); /* Coprocessor error enable */ - reg32 |= (1 << 1); /* Delayed transaction enable */ - reg32 |= (1 << 2); /* DMA collection buffer enable */ + reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */ + reg32 |= (3 << 7); /* IOAPIC enable (APIC_EN) */ + reg32 |= (1 << 2); /* DMA collection buffer enable (DCB_EN) */ + reg32 |= (1 << 1); /* Delayed transaction enable (DTE) */ pci_write_config32(dev, GEN_CNTL, reg32); printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
- *ioapic_index = 0; - *ioapic_data = (1 << 25); - - *ioapic_index = 0; - reg32 = *ioapic_data; - printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32); - if (reg32 != (1 << 25)) - die("APIC Error\n"); - - *ioapic_index = 3; /* Select Boot Configuration register. */ - *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */ + setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02); }
static void i82801dx_enable_serial_irqs(struct device *dev) @@ -267,6 +268,7 @@ static void lpc_init(struct device *dev) /* Set the value for PCI command register. */ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+ i82801dx_enable_acpi(dev); /* IO APIC initialization. */ i82801dx_enable_ioapic(dev);
diff --git a/src/southbridge/intel/i82801ex/i82801ex.h b/src/southbridge/intel/i82801ex/i82801ex.h index 67fecdd..22a29f3 100644 --- a/src/southbridge/intel/i82801ex/i82801ex.h +++ b/src/southbridge/intel/i82801ex/i82801ex.h @@ -12,4 +12,13 @@ extern void i82801ex_enable(device_t dev); #define RTC_CONF 0xd8 #define GEN_PMCON_3 0xa4
+ +#define PMBASE 0x40 +#define ACPI_CNTL 0x44 +#define ACPI_EN (1 << 4) +#define GPIO_BASE 0x58 +#define GPIO_CNTL 0x5C +#define GPIO_EN (1 << 4) + + #endif /* I82801EX_H */ diff --git a/src/southbridge/intel/i82801ex/lpc.c b/src/southbridge/intel/i82801ex/lpc.c index 998360c..659728a 100644 --- a/src/southbridge/intel/i82801ex/lpc.c +++ b/src/southbridge/intel/i82801ex/lpc.c @@ -12,8 +12,6 @@ #include <arch/ioapic.h> #include "i82801ex.h"
-#define ACPI_BAR 0x40 -#define GPIO_BAR 0x58
#define NMI_OFF 0 #define MAINBOARD_POWER_OFF 0 @@ -23,6 +21,53 @@ #define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON #endif
+typedef struct southbridge_intel_i82801ex_config config_t; + +/** + * enable_acpi(dev) + * + * @dev PCI device with ACPI and PM BAR's + */ +static void i82801ex_enable_acpi(struct device *dev) +{ + u8 gpio_cntl; +#if 0 + /* many i82801's set pmbase here */ + /* Set ACPI base address (I/O space). */ + pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1)); +#endif + + /* Enable ACPI I/O range decode and ACPI power management. */ + pci_write_config8(dev, ACPI_CNTL, ACPI_EN); + + /* Enable the GPIO bar */ + gpio_cntl = pci_read_config8(dev, GPIO_CNTL); + gpio_cntl |= GPIO_EN; + pci_write_config8(dev, GPIO_CNTL, gpio_cntl); +} + +/** + * enable_ioapic() + * + * @dev PCI device with I/O APIC configuration registers + */ +static void i82801ex_enable_ioapic(struct device *dev) +{ + u32 reg32; + + reg32 = pci_read_config32(dev, GEN_CNTL); + reg32 |= (3 << 7); /* IOAPIC enable (APIC_EN) */ + reg32 |= (1 << 1); /* Delayed transaction enable (DTE) */ + pci_write_config32(dev, GEN_CNTL, reg32); + printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32); + + reg32 = pci_read_config32(dev, GEN_STS); + reg32 |= (1<<1); + pci_write_config32(dev, GEN_STS, reg32); + + setup_ioapic(IO_APIC_ADDR, 0); /* Don't rename IO APIC ID. */ +} + #define SERIRQ_CNTL 0x64 static void i82801ex_enable_serial_irqs(device_t dev) { @@ -45,7 +90,6 @@ static void i82801ex_enable_lpc(device_t dev) pci_write_config8(dev, LPC_EN, 0x0d); }
-typedef struct southbridge_intel_i82801ex_config config_t;
static void set_i82801ex_gpio_use_sel( device_t dev, struct resource *res, config_t *config) @@ -193,7 +237,7 @@ static void i82801ex_gpio_init(device_t dev) /* Get the chip configuration */ config = dev->chip_info; /* Find the GPIO bar */ - res = find_resource(dev, GPIO_BAR); + res = find_resource(dev, GPIO_BASE); if (!res) { return; } @@ -239,18 +283,10 @@ static void enable_hpet(struct device *dev) static void lpc_init(struct device *dev) { uint8_t byte; - uint32_t value; int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- /* IO APIC initialization */ - value = pci_read_config32(dev, 0xd0); - value |= (1 << 8)|(1<<7)|(1<<1); - pci_write_config32(dev, 0xd0, value); - value = pci_read_config32(dev, 0xd4); - value |= (1<<1); - pci_write_config32(dev, 0xd4, value); - setup_ioapic(IO_APIC_ADDR, 0); // Don't rename IO APIC ID. - + i82801ex_enable_ioapic(dev); + i82801ex_enable_serial_irqs(dev);
i82801ex_pci_dma_cfg(dev); @@ -295,10 +331,10 @@ static void i82801ex_lpc_read_resources(device_t dev) pci_dev_read_resources(dev);
/* Add the ACPI BAR */ - res = pci_get_resource(dev, ACPI_BAR); + res = pci_get_resource(dev, PMBASE);
/* Add the GPIO BAR */ - res = pci_get_resource(dev, GPIO_BAR); + res = pci_get_resource(dev, GPIO_BASE);
/* Add an extra subtractive resource for both memory and I/O. */ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0)); @@ -321,20 +357,11 @@ static void i82801ex_lpc_read_resources(device_t dev)
static void i82801ex_lpc_enable_resources(device_t dev) { - uint8_t acpi_cntl, gpio_cntl; - /* Enable the normal pci resources */ pci_dev_enable_resources(dev);
- /* Enable the ACPI bar */ - acpi_cntl = pci_read_config8(dev, 0x44); - acpi_cntl |= (1 << 4); - pci_write_config8(dev, 0x44, acpi_cntl); - - /* Enable the GPIO bar */ - gpio_cntl = pci_read_config8(dev, 0x5c); - gpio_cntl |= (1 << 4); - pci_write_config8(dev, 0x5c, gpio_cntl); + /* Enable ACPI and GPIO BARs */ + i82801ex_enable_acpi(dev); }
static struct pci_operations lops_pci = { diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h index 2ceb215..55fd883 100644 --- a/src/southbridge/intel/i82801gx/i82801gx.h +++ b/src/southbridge/intel/i82801gx/i82801gx.h @@ -82,6 +82,7 @@ void enable_usbdebug(unsigned int port);
#define PMBASE 0x40 #define ACPI_CNTL 0x44 +#define ACPI_EN (1 << 7) /* NOTE: was 1<<4 until ICH7 */ #define BIOS_CNTL 0xDC #define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ #define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ diff --git a/src/southbridge/intel/i82801gx/lpc.c b/src/southbridge/intel/i82801gx/lpc.c index ab3c915..acc25d1 100644 --- a/src/southbridge/intel/i82801gx/lpc.c +++ b/src/southbridge/intel/i82801gx/lpc.c @@ -39,37 +39,38 @@
typedef struct southbridge_intel_i82801gx_config config_t;
-static void i82801gx_enable_apic(struct device *dev) +/** + * enable_acpi(dev) + * + * @dev PCI device with ACPI and PM BAR's + */ +static void i82801gx_enable_acpi(struct device *dev) { - int i; - u32 reg32; - volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR); - volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10); +#if 0 + /* many i82801's set pmbase here */ + /* Set ACPI base address (I/O space). */ + pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1)); +#endif
- /* Enable ACPI I/O and power management. - * Set SCI IRQ to IRQ9 + /* Enable ACPI I/O range decode and ACPI power management. + * Select SCI IRQ as IRQ9. */ - pci_write_config8(dev, ACPI_CNTL, 0x80); - - *ioapic_index = 0; - *ioapic_data = (1 << 25); - - *ioapic_index = 0; - reg32 = *ioapic_data; - printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", (reg32 >> 24) & 0x0f); - if (reg32 != (1 << 25)) - die("APIC Error\n"); - - printk(BIOS_SPEW, "Dumping IOAPIC registers\n"); - for (i=0; i<3; i++) { - *ioapic_index = i; - printk(BIOS_SPEW, " reg 0x%04x:", i); - reg32 = *ioapic_data; - printk(BIOS_SPEW, " 0x%08x\n", reg32); - } + pci_write_config8(dev, ACPI_CNTL, ACPI_EN); +}
- *ioapic_index = 3; /* Select Boot Configuration register. */ - *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */ +/** + * enable_ioapic() + * + * @dev PCI device with I/O APIC configuration registers + */ +static void i82801gx_enable_ioapic(struct device *dev) +{ + u32 reg32 = 0xABADBEEF; + + /* FIXME:use OIC register @ 0x3155 */ + printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32); + + setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02); }
static void i82801gx_enable_serial_irqs(struct device *dev) @@ -417,8 +418,10 @@ static void lpc_init(struct device *dev) /* Set the value for PCI command register. */ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+ i82801gx_enable_acpi(dev); + /* IO APIC initialization. */ - i82801gx_enable_apic(dev); + i82801gx_enable_ioapic(dev);
i82801gx_enable_serial_irqs(dev);