summaryrefslogtreecommitdiff
path: root/src/southbridge/intel/i82801gx/i82801gx_lpc.c
diff options
context:
space:
mode:
authorStefan Reinauer <stepan@coresystems.de>2009-07-21 21:50:34 +0000
committerStefan Reinauer <stepan@openbios.org>2009-07-21 21:50:34 +0000
commit573f7d40be086b35b25d242818ae0e9c26d05022 (patch)
tree831bf36c8294b2dd1362af4e6de3b3f0df0fff50 /src/southbridge/intel/i82801gx/i82801gx_lpc.c
parent71a3d96bc487f66c84ac869a1215b8a4a4499bf2 (diff)
downloadcoreboot-573f7d40be086b35b25d242818ae0e9c26d05022.tar.xz
Intel ICH7 updates
- code restructuring (move ich7 out of i945) - ACPI fixes - major SMI handler updates - make sure SMBus lives where we expect it - try to get usb debug working Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Peter Stuge <peter@stuge.se> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4456 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/southbridge/intel/i82801gx/i82801gx_lpc.c')
-rw-r--r--src/southbridge/intel/i82801gx/i82801gx_lpc.c90
1 files changed, 72 insertions, 18 deletions
diff --git a/src/southbridge/intel/i82801gx/i82801gx_lpc.c b/src/southbridge/intel/i82801gx/i82801gx_lpc.c
index ca2b409321..f42471f3ef 100644
--- a/src/southbridge/intel/i82801gx/i82801gx_lpc.c
+++ b/src/southbridge/intel/i82801gx/i82801gx_lpc.c
@@ -27,17 +27,12 @@
#include <pc80/i8259.h>
#include <arch/io.h>
#include "i82801gx.h"
+#include "i82801gx_power.h"
-#include "../../../northbridge/intel/i945/ich7.h"
+#define NMI_OFF 0
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-#define NMI_OFF 0
+#define ENABLE_ACPI_MODE_IN_COREBOOT 0
+#define TEST_SMM_FLASH_LOCKDOWN 0
typedef struct southbridge_intel_i82801gx_config config_t;
@@ -78,7 +73,9 @@ static void i82801gx_enable_apic(struct device *dev)
volatile u32 *ioapic_index = (volatile u32 *)0xfec00000;
volatile u32 *ioapic_data = (volatile u32 *)0xfec00010;
- /* Enable ACPI I/O and power management. */
+ /* Enable ACPI I/O and power management.
+ * Set SCI IRQ to IRQ9
+ */
pci_write_config8(dev, ACPI_CNTL, 0x80);
*ioapic_index = 0;
@@ -109,6 +106,27 @@ static void i82801gx_enable_serial_irqs(struct device *dev)
(1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
}
+/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
+ * 0x00 - 0000 = Reserved
+ * 0x01 - 0001 = Reserved
+ * 0x02 - 0010 = Reserved
+ * 0x03 - 0011 = IRQ3
+ * 0x04 - 0100 = IRQ4
+ * 0x05 - 0101 = IRQ5
+ * 0x06 - 0110 = IRQ6
+ * 0x07 - 0111 = IRQ7
+ * 0x08 - 1000 = Reserved
+ * 0x09 - 1001 = IRQ9
+ * 0x0A - 1010 = IRQ10
+ * 0x0B - 1011 = IRQ11
+ * 0x0C - 1100 = IRQ12
+ * 0x0D - 1101 = Reserved
+ * 0x0E - 1110 = IRQ14
+ * 0x0F - 1111 = IRQ15
+ * PIRQ[n]_ROUT[7] - PIRQ Routing Control
+ * 0x80 - The PIRQ is not routed.
+ */
+
static void i82801gx_pirq_init(device_t dev)
{
device_t irq_dev;
@@ -180,10 +198,14 @@ static void i82801gx_gpi_routing(device_t dev)
pci_write_config32(dev, 0xb8, reg32);
}
+extern u8 acpi_slp_type;
+
static void i82801gx_power_options(device_t dev)
{
u8 reg8;
- u16 reg16;
+ u16 reg16, pmbase;
+ u32 reg32;
+ char *state;
int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
int nmi_option;
@@ -195,16 +217,28 @@ static void i82801gx_power_options(device_t dev)
get_option(&pwr_on, "power_on_after_fail");
reg8 = pci_read_config8(dev, GEN_PMCON_3);
reg8 &= 0xfe;
- if (pwr_on) {
- reg8 &= ~1;
- } else {
+ switch (pwr_on) {
+ case MAINBOARD_POWER_OFF:
reg8 |= 1;
+ state = "off";
+ break;
+ case MAINBOARD_POWER_ON:
+ reg8 &= ~1;
+ state = "on";
+ break;
+ case MAINBOARD_POWER_KEEP:
+ reg8 &= ~1;
+ state = "state keep";
+ break;
+ default:
+ state = "undefined";
}
+
reg8 |= (3 << 4); /* avoid #S4 assertions */
reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */
pci_write_config8(dev, GEN_PMCON_3, reg8);
- printk_info("Set power %s after power failure.\n", pwr_on ? "on" : "off");
+ printk_info("Set power %s after power failure.\n", state);
/* Set up NMI on errors. */
reg8 = inb(0x61);
@@ -226,15 +260,27 @@ static void i82801gx_power_options(device_t dev)
}
outb(reg8, 0x70);
- // Enable CPU_SLP# and Intel Speedstep, set SMI# rate down
+ /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
reg16 = pci_read_config16(dev, GEN_PMCON_1);
reg16 &= ~((3 << 0) | (1 << 10));
reg16 |= (1 << 3) | (1 << 5);
- reg16 |= (1 << 2); // CLKRUN_EN
+ reg16 |= (1 << 2); // CLKRUN_EN
pci_write_config16(dev, GEN_PMCON_1, reg16);
// Set the board's GPI routing.
i82801gx_gpi_routing(dev);
+
+ /* Set up power management block and determine sleep mode */
+ pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
+ reg32 = inl(pmbase + 0x04); // PM1_CNT
+#if HAVE_ACPI_RESUME
+ acpi_slp_type = (((reg32 >> 10) & 7) == 5) ? 3 : 0;
+ printk_debug("PM1_CNT: 0x%08x --> acpi_sleep_type: %x\n",
+ reg32, acpi_slp_type);
+#endif
+ reg32 |= (1 << 1); // enable C3->C0 transition on bus master
+ reg32 |= 1; // SCI_EN
+ outl(reg32, pmbase + 0x04);
}
static void i82801gx_configure_cstates(device_t dev)
@@ -273,9 +319,10 @@ static void enable_hpet(void)
{
u32 reg32;
- /* Leave HPET at default address, but enable it */
+ /* Move HPET to default address 0xfed00000 and enable it */
reg32 = RCBA32(0x3404);
reg32 |= (1 << 7); // HPET Address Enable
+ reg32 &= ~(3 << 0);
RCBA32(0x3404) = reg32;
}
@@ -467,6 +514,13 @@ static struct device_operations device_ops = {
.ops_pci = &pci_ops,
};
+/* 82801GH (ICH7 DH) */
+static const struct pci_driver ich7_dh_lpc __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27b0,
+};
+
/* 82801GB/GR (ICH7/ICH7R) */
static const struct pci_driver ich7_ich7r_lpc __pci_driver = {
.ops = &device_ops,