Kyösti Mälkki ([email protected]) 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 <[email protected]>
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 <[email protected]>
---
 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,

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to