[coreboot] Patch set updated for coreboot: addfa92 Cleaning i82801 LPC codes
Kyösti Mälkki (kyosti.malkki@gmail.com)
gerrit at coreboot.org
Thu Oct 20 07:43:35 CEST 2011
Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/302
-gerrit
commit addfa92f182facd135c906393c65953d78e09cbd
Author: Kyösti Mälkki <kyosti.malkki at 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.
Enable device resources during dev->ops->enable() and
not during dev->ops->init().
Change-Id: I8ad80fdd0913995471269f33293c4a4b8cf1de83
Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
src/southbridge/intel/i82801ax/Kconfig | 1 +
src/southbridge/intel/i82801ax/lpc.c | 59 ++++++++++------
src/southbridge/intel/i82801bx/Kconfig | 1 +
src/southbridge/intel/i82801bx/lpc.c | 58 +++++++++------
src/southbridge/intel/i82801cx/Kconfig | 1 +
src/southbridge/intel/i82801cx/lpc.c | 107 ++++++++++++++++-------------
src/southbridge/intel/i82801dx/i82801dx.h | 1 +
src/southbridge/intel/i82801dx/lpc.c | 68 +++++++++++--------
src/southbridge/intel/i82801ex/i82801ex.h | 9 +++
src/southbridge/intel/i82801ex/lpc.c | 82 +++++++++++++++-------
src/southbridge/intel/i82801gx/i82801gx.h | 1 +
src/southbridge/intel/i82801gx/lpc.c | 77 ++++++++++++---------
12 files changed, 285 insertions(+), 180 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..b2391af 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);
+}
+
+/**
+ * general_cntl()
+ *
+ * @dev PCI device with I/O APIC control registers
+ */
+static void i82801ax_general_cntl(struct device *dev)
+{
+ u32 reg32;
reg32 = pci_read_config32(dev, GEN_CNTL);
reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */
@@ -88,20 +101,8 @@ static void i82801ax_enable_apic(struct device *dev)
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);
+ printk(BIOS_DEBUG, "Southbridge GEN_CNTL 0x%08x\n", reg32);
- *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. */
}
static void i82801ax_enable_serial_irqs(struct device *dev)
@@ -216,11 +217,8 @@ static void i82801ax_lpc_decode_en(device_t dev)
static void lpc_init(struct device *dev)
{
- /* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
-
/* IO APIC initialization. */
- i82801ax_enable_apic(dev);
+ setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02);
i82801ax_enable_serial_irqs(dev);
@@ -272,10 +270,25 @@ static void i82801ax_lpc_read_resources(device_t dev)
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}
+static void i82801ax_lpc_enable_resources(device_t dev)
+{
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable ACPI and GPIO BARs */
+ i82801ax_enable_acpi(dev);
+
+ /* Set features ( most important: IOAPIC ) */
+ i82801ax_general_cntl(dev);
+
+ /* Set the value for PCI command register. */
+ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+}
+
static struct device_operations lpc_ops = {
.read_resources = i82801ax_lpc_read_resources,
.set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
+ .enable_resources = i82801ax_lpc_enable_resources,
.init = lpc_init,
.scan_bus = scan_static_bus,
.enable = i82801ax_enable,
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..2a937b6 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);
+}
+
+/**
+ * general_cntl()
+ *
+ * @dev PCI device with I/O APIC control registers
+ */
+static void i82801bx_general_cntl(struct device *dev)
+{
+ u32 reg32;
reg32 = pci_read_config32(dev, GEN_CNTL);
reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */
@@ -90,20 +102,8 @@ static void i82801bx_enable_apic(struct device *dev)
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);
+ printk(BIOS_DEBUG, "Southbridge GEN_CNTL 0x%08x\n", reg32);
- *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. */
}
static void i82801bx_enable_serial_irqs(struct device *dev)
@@ -234,11 +234,8 @@ static void lpc_init(struct device *dev)
{
uint16_t ich_model = pci_read_config16(dev, PCI_DEVICE_ID);
- /* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
-
/* IO APIC initialization. */
- i82801bx_enable_apic(dev);
+ setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02);
i82801bx_enable_serial_irqs(dev);
@@ -290,10 +287,25 @@ static void i82801bx_lpc_read_resources(device_t dev)
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}
+static void i82801bx_lpc_enable_resources(device_t dev)
+{
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable ACPI and GPIO BARs */
+ i82801bx_enable_acpi(dev);
+
+ /* Set features ( most important: IOAPIC ) */
+ i82801bx_general_cntl(dev);
+
+ /* Set the value for PCI command register. */
+ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+}
+
static struct device_operations lpc_ops = {
.read_resources = i82801bx_lpc_read_resources,
.set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
+ .enable_resources = i82801bx_lpc_enable_resources,
.init = lpc_init,
.scan_bus = scan_static_bus,
.enable = i82801bx_enable,
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..3cab202 100644
--- a/src/southbridge/intel/i82801cx/lpc.c
+++ b/src/southbridge/intel/i82801cx/lpc.c
@@ -24,34 +24,43 @@
#define MAINBOARD_POWER_ON 1
-static void i82801cx_enable_ioapic( struct device *dev)
+/**
+ * enable_acpi(dev)
+ *
+ * @dev PCI device with ACPI and PM BAR's
+ */
+static void i82801cx_enable_acpi(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
+ // Set ACPI base address to 0x1100 (I/O space)
+ pci_write_config32(dev, PMBASE, 0x00001101);
+
+ // Enable ACPI I/O and power management
+ pci_write_config8(dev, ACPI_CNTL, 0x10);
+
+ // Set GPIO base address to 0x1180 (I/O space)
+ pci_write_config32(dev, GPIO_BASE, 0x00001181);
+
+ // Enable GPIO
+ pci_write_config8(dev, GPIO_CNTL, 0x10);
+}
+
+/**
+ * general_cntl()
+ *
+ * @dev PCI device with I/O APIC control registers
+ */
+static void i82801cx_general_cntl(struct device *dev)
+{
+ 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, "Southbridge GEN_CNTL 0x%08x\n", reg32);
+
}
// This is how interrupts are received from the Super I/O chip
@@ -118,20 +127,6 @@ static void i82801cx_rtc_init(struct device *dev)
static void i82801cx_1f0_misc(struct device *dev)
{
- // Prevent LPC disabling, enable parity errors, and SERR# (System Error)
- pci_write_config16(dev, PCI_COMMAND, 0x014f);
-
- // Set ACPI base address to 0x1100 (I/O space)
- pci_write_config32(dev, PMBASE, 0x00001101);
-
- // Enable ACPI I/O and power management
- pci_write_config8(dev, ACPI_CNTL, 0x10);
-
- // Set GPIO base address to 0x1180 (I/O space)
- pci_write_config32(dev, GPIO_BASE, 0x00001181);
-
- // Enable GPIO
- pci_write_config8(dev, GPIO_CNTL, 0x10);
// Route PIRQA to IRQ11, PIRQB to IRQ3, PIRQC to IRQ5, PIRQD to IRQ10
pci_write_config32(dev, PIRQA_ROUT, 0x0A05030B);
@@ -160,8 +155,9 @@ static void lpc_init(struct device *dev)
int pwr_on=-1;
int nmi_option;
+ i82801cx_general_cntl(dev);
/* IO APIC initialization */
- i82801cx_enable_ioapic(dev);
+ setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02);
i82801cx_enable_serial_irqs(dev);
@@ -229,13 +225,28 @@ static void i82801cx_lpc_read_resources(device_t dev)
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}
+static void i82801cx_lpc_enable_resources(device_t dev)
+{
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable ACPI and GPIO BARs */
+ i82801cx_enable_acpi(dev);
+
+ /* Set features ( most important: IOAPIC ) */
+ i82801cx_general_cntl(dev);
+
+ /* Prevent LPC disabling, enable parity errors, and SERR# (System Error) */
+ pci_write_config16(dev, PCI_COMMAND, 0x014f);
+}
+
static struct device_operations lpc_ops = {
- .read_resources = i82801cx_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = 0,
+ .read_resources = i82801cx_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = i82801cx_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = 0,
};
static const struct pci_driver lpc_driver __pci_driver = {
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..16b5abe 100644
--- a/src/southbridge/intel/i82801dx/lpc.c
+++ b/src/southbridge/intel/i82801dx/lpc.c
@@ -36,37 +36,37 @@
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);
+}
+
+/**
+ * general_cntl()
+ *
+ * @dev PCI device with I/O APIC control registers
+ */
+static void i82801dx_general_cntl(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");
+ printk(BIOS_DEBUG, "Southbridge GEN_CNTL 0x%08x\n", reg32);
- *ioapic_index = 3; /* Select Boot Configuration register. */
- *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
}
static void i82801dx_enable_serial_irqs(struct device *dev)
@@ -264,11 +264,8 @@ static void enable_hpet(struct device *dev)
static void lpc_init(struct device *dev)
{
- /* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
-
/* IO APIC initialization. */
- i82801dx_enable_ioapic(dev);
+ setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02);
i82801dx_enable_serial_irqs(dev);
@@ -323,10 +320,25 @@ static void i82801dx_lpc_read_resources(device_t dev)
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}
+static void i82801dx_lpc_enable_resources(device_t dev)
+{
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable ACPI and GPIO BARs */
+ i82801dx_enable_acpi(dev);
+
+ /* Set features ( most important: IOAPIC ) */
+ i82801dx_general_cntl(dev);
+
+ /* Set the value for PCI command register. */
+ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+}
+
static struct device_operations lpc_ops = {
.read_resources = i82801dx_lpc_read_resources,
.set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
+ .enable_resources = i82801dx_lpc_enable_resources,
.init = lpc_init,
.scan_bus = scan_static_bus,
.enable = i82801dx_enable,
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..1ec0f23 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,52 @@
#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);
+}
+
+/**
+ * general_cntl()
+ *
+ * @dev PCI device with I/O APIC configuration registers
+ */
+static void i82801ex_general_cntl(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, "Southbridge GEN_CNTL 0x%08x\n", reg32);
+
+ reg32 = pci_read_config32(dev, GEN_STS);
+ reg32 |= (1<<1);
+ pci_write_config32(dev, GEN_STS, reg32);
+
+}
+
#define SERIRQ_CNTL 0x64
static void i82801ex_enable_serial_irqs(device_t dev)
{
@@ -45,7 +89,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 +236,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 +282,11 @@ 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.
-
+ /* IO APIC initialization. */
+ setup_ioapic(IO_APIC_ADDR, 0); /* No APIC ID ?? */
+
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,14 @@ 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 ACPI and GPIO BARs */
+ i82801ex_enable_acpi(dev);
- /* Enable the GPIO bar */
- gpio_cntl = pci_read_config8(dev, 0x5c);
- gpio_cntl |= (1 << 4);
- pci_write_config8(dev, 0x5c, gpio_cntl);
+ /* Set features ( most important: IOAPIC ) */
+ i82801ex_general_cntl(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..0bbcd97 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);
+}
+
+/**
+ * general_cntl()
+ *
+ * @dev PCI device with I/O APIC configuration registers
+ */
+static void i82801gx_general_cntl(struct device *dev)
+{
+ u32 reg32 = 0xABADBEEF;
+
+ /* FIXME: Who sets OIC register @ 0x3155 ??
+ */
+ printk(BIOS_DEBUG, "Southbridge OIC 0x%08x.\n", reg32);
- *ioapic_index = 3; /* Select Boot Configuration register. */
- *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
}
static void i82801gx_enable_serial_irqs(struct device *dev)
@@ -414,11 +415,8 @@ static void lpc_init(struct device *dev)
{
printk(BIOS_DEBUG, "i82801gx: lpc_init\n");
- /* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
-
/* IO APIC initialization. */
- i82801gx_enable_apic(dev);
+ setup_ioapic_NOVECTORS(IO_APIC_ADDR, 0x02);
i82801gx_enable_serial_irqs(dev);
@@ -498,6 +496,21 @@ static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
}
}
+static void i82801gx_lpc_enable_resources(device_t dev)
+{
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable ACPI and GPIO BARs */
+ i82801gx_enable_acpi(dev);
+
+ /* Set features ( most important: IOAPIC ) */
+ i82801gx_general_cntl(dev);
+
+ /* Set the value for PCI command register. */
+ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+}
+
static struct pci_operations pci_ops = {
.set_subsystem = set_subsystem,
};
@@ -505,7 +518,7 @@ static struct pci_operations pci_ops = {
static struct device_operations device_ops = {
.read_resources = i82801gx_lpc_read_resources,
.set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
+ .enable_resources = i82801gx_lpc_enable_resources,
.init = lpc_init,
.scan_bus = scan_static_bus,
.enable = i82801gx_enable,
More information about the coreboot
mailing list