summaryrefslogtreecommitdiff
path: root/src/southbridge/intel
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2014-12-29 11:32:27 +0200
committerKyösti Mälkki <kyosti.malkki@gmail.com>2015-04-28 07:59:13 +0200
commitb85a87b7d6f9f12d5c71c32741c8af731ed6be7e (patch)
tree67553a9c683557ead346dc1c7b155d3eac475090 /src/southbridge/intel
parent189f3ba974df8f1b305cfa421a151fe069fc1a6f (diff)
downloadcoreboot-b85a87b7d6f9f12d5c71c32741c8af731ed6be7e.tar.xz
intel SMI handlers: Refactor GPI SMI/SCI routing
Move the GPI interrupt routing selection between SMI/SCI from mainboards to southbridge. There is speculation if this is all just legacy APM stuff that could be removed with a followup. Change-Id: Iab14cf347584513793f417febc47f0559e17f5a5 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Signed-off-by: Nicolas Reinecke <nr@das-labor.org> Reviewed-on: http://review.coreboot.org/7967 Tested-by: build bot (Jenkins) Reviewed-by: Alexander Couzens <lynxis@fe80.eu>
Diffstat (limited to 'src/southbridge/intel')
-rw-r--r--src/southbridge/intel/bd82x6x/lpc.c2
-rw-r--r--src/southbridge/intel/bd82x6x/pch.h6
-rw-r--r--src/southbridge/intel/bd82x6x/smihandler.c36
-rw-r--r--src/southbridge/intel/fsp_bd82x6x/lpc.c2
-rw-r--r--src/southbridge/intel/i82801gx/i82801gx.h7
-rw-r--r--src/southbridge/intel/i82801gx/lpc.c2
-rw-r--r--src/southbridge/intel/i82801gx/smihandler.c36
-rw-r--r--src/southbridge/intel/ibexpeak/lpc.c2
-rw-r--r--src/southbridge/intel/ibexpeak/pch.h6
-rw-r--r--src/southbridge/intel/ibexpeak/smihandler.c36
-rw-r--r--src/southbridge/intel/lynxpoint/lpc.c2
11 files changed, 132 insertions, 5 deletions
diff --git a/src/southbridge/intel/bd82x6x/lpc.c b/src/southbridge/intel/bd82x6x/lpc.c
index d8f98c1692..b2071371f1 100644
--- a/src/southbridge/intel/bd82x6x/lpc.c
+++ b/src/southbridge/intel/bd82x6x/lpc.c
@@ -167,7 +167,7 @@ static void pch_gpi_routing(device_t dev)
reg32 |= (config->gpi14_routing & 0x03) << 28;
reg32 |= (config->gpi15_routing & 0x03) << 30;
- pci_write_config32(dev, 0xb8, reg32);
+ pci_write_config32(dev, GPIO_ROUT, reg32);
}
static void pch_power_options(device_t dev)
diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h
index 4ec29035d1..a76bf365b6 100644
--- a/src/southbridge/intel/bd82x6x/pch.h
+++ b/src/southbridge/intel/bd82x6x/pch.h
@@ -70,6 +70,7 @@ int pch_silicon_revision(void);
int pch_silicon_type(void);
int pch_silicon_supported(int type, int rev);
void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue);
+void gpi_route_interrupt(u8 gpi, u8 mode);
#if CONFIG_ELOG
void pch_log_state(void);
#endif
@@ -146,7 +147,12 @@ early_usb_init (const struct southbridge_usb_port *portmap);
#define BIOS_CNTL 0xDC
#define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */
#define GPIO_CNTL 0x4C /* LPC GPIO Control Register */
+
#define GPIO_ROUT 0xb8
+#define GPI_DISABLE 0x00
+#define GPI_IS_SMI 0x01
+#define GPI_IS_SCI 0x02
+#define GPI_IS_NMI 0x03
#define PIRQA_ROUT 0x60
#define PIRQB_ROUT 0x61
diff --git a/src/southbridge/intel/bd82x6x/smihandler.c b/src/southbridge/intel/bd82x6x/smihandler.c
index f69c1f4dd8..7ecbd81e92 100644
--- a/src/southbridge/intel/bd82x6x/smihandler.c
+++ b/src/southbridge/intel/bd82x6x/smihandler.c
@@ -75,6 +75,42 @@ void tseg_relocate(void **ptr)
}
#endif
+static void alt_gpi_mask(u16 clr, u16 set)
+{
+ u16 alt_gp = inw(pmbase + ALT_GP_SMI_EN);
+ alt_gp &= ~clr;
+ alt_gp |= set;
+ outw(alt_gp, pmbase + ALT_GP_SMI_EN);
+}
+
+static void gpe0_mask(u32 clr, u32 set)
+{
+ u32 gpe0 = inl(pmbase + GPE0_EN);
+ gpe0 &= ~clr;
+ gpe0 |= set;
+ outl(gpe0, pmbase + GPE0_EN);
+}
+
+void gpi_route_interrupt(u8 gpi, u8 mode)
+{
+ u32 gpi_rout;
+ if (gpi >= 16)
+ return;
+
+ alt_gpi_mask(1 << gpi, 0);
+ gpe0_mask(1 << (gpi+16), 0);
+
+ gpi_rout = pci_read_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT);
+ gpi_rout &= ~(3 << (2 * gpi));
+ gpi_rout |= ((mode & 3) << (2 * gpi));
+ pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT, gpi_rout);
+
+ if (mode == GPI_IS_SCI)
+ gpe0_mask(0, 1 << (gpi+16));
+ else if (mode == GPI_IS_SMI)
+ alt_gpi_mask(0, 1 << gpi);
+}
+
/**
* @brief read and clear PM1_STS
* @return PM1_STS register
diff --git a/src/southbridge/intel/fsp_bd82x6x/lpc.c b/src/southbridge/intel/fsp_bd82x6x/lpc.c
index f9961f95ba..6b95d0874a 100644
--- a/src/southbridge/intel/fsp_bd82x6x/lpc.c
+++ b/src/southbridge/intel/fsp_bd82x6x/lpc.c
@@ -185,7 +185,7 @@ static void pch_gpi_routing(device_t dev)
reg32 |= (config->gpi14_routing & 0x03) << 28;
reg32 |= (config->gpi15_routing & 0x03) << 30;
- pci_write_config32(dev, 0xb8, reg32);
+ pci_write_config32(dev, GPIO_ROUT, reg32);
}
static void pch_power_options(device_t dev)
diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h
index 462484100d..815768bbca 100644
--- a/src/southbridge/intel/i82801gx/i82801gx.h
+++ b/src/southbridge/intel/i82801gx/i82801gx.h
@@ -45,6 +45,7 @@
#if !defined(__PRE_RAM__)
#include "chip.h"
extern void i82801gx_enable(device_t dev);
+void gpi_route_interrupt(u8 gpi, u8 mode);
#else
void enable_smbus(void);
int smbus_read_byte(unsigned device, unsigned address);
@@ -78,6 +79,12 @@ int southbridge_detect_s3_resume(void);
#define GEN_PMCON_2 0xa2
#define GEN_PMCON_3 0xa4
+#define GPIO_ROUT 0xb8
+#define GPI_DISABLE 0x00
+#define GPI_IS_SMI 0x01
+#define GPI_IS_SCI 0x02
+#define GPI_IS_NMI 0x03
+
/* GEN_PMCON_3 bits */
#define RTC_BATTERY_DEAD (1 << 2)
#define RTC_POWER_FAILED (1 << 1)
diff --git a/src/southbridge/intel/i82801gx/lpc.c b/src/southbridge/intel/i82801gx/lpc.c
index b8edfe3fd9..2e3182bd2f 100644
--- a/src/southbridge/intel/i82801gx/lpc.c
+++ b/src/southbridge/intel/i82801gx/lpc.c
@@ -158,7 +158,7 @@ static void i82801gx_gpi_routing(device_t dev)
reg32 |= (config->gpi14_routing & 0x03) << 28;
reg32 |= (config->gpi15_routing & 0x03) << 30;
- pci_write_config32(dev, 0xb8, reg32);
+ pci_write_config32(dev, GPIO_ROUT, reg32);
}
static void i82801gx_power_options(device_t dev)
diff --git a/src/southbridge/intel/i82801gx/smihandler.c b/src/southbridge/intel/i82801gx/smihandler.c
index e83c722f0b..6db08319d6 100644
--- a/src/southbridge/intel/i82801gx/smihandler.c
+++ b/src/southbridge/intel/i82801gx/smihandler.c
@@ -50,6 +50,42 @@ u8 smm_initialized = 0;
*/
global_nvs_t *gnvs = (global_nvs_t *)0x0;
+static void alt_gpi_mask(u16 clr, u16 set)
+{
+ u16 alt_gp = inw(pmbase + ALT_GP_SMI_EN);
+ alt_gp &= ~clr;
+ alt_gp |= set;
+ outw(alt_gp, pmbase + ALT_GP_SMI_EN);
+}
+
+static void gpe0_mask(u32 clr, u32 set)
+{
+ u32 gpe0 = inl(pmbase + GPE0_EN);
+ gpe0 &= ~clr;
+ gpe0 |= set;
+ outl(gpe0, pmbase + GPE0_EN);
+}
+
+void gpi_route_interrupt(u8 gpi, u8 mode)
+{
+ u32 gpi_rout;
+ if (gpi >= 16)
+ return;
+
+ alt_gpi_mask(1 << gpi, 0);
+ gpe0_mask(1 << (gpi+16), 0);
+
+ gpi_rout = pci_read_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT);
+ gpi_rout &= ~(3 << (2 * gpi));
+ gpi_rout |= ((mode & 3) << (2 * gpi));
+ pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT, gpi_rout);
+
+ if (mode == GPI_IS_SCI)
+ gpe0_mask(0, 1 << (gpi+16));
+ else if (mode == GPI_IS_SMI)
+ alt_gpi_mask(0, 1 << gpi);
+}
+
/**
* @brief read and clear PM1_STS
* @return PM1_STS register
diff --git a/src/southbridge/intel/ibexpeak/lpc.c b/src/southbridge/intel/ibexpeak/lpc.c
index db73b0add8..9550a9e974 100644
--- a/src/southbridge/intel/ibexpeak/lpc.c
+++ b/src/southbridge/intel/ibexpeak/lpc.c
@@ -166,7 +166,7 @@ static void pch_gpi_routing(device_t dev)
reg32 |= (config->gpi14_routing & 0x03) << 28;
reg32 |= (config->gpi15_routing & 0x03) << 30;
- pci_write_config32(dev, 0xb8, reg32);
+ pci_write_config32(dev, GPIO_ROUT, reg32);
}
static void pch_power_options(device_t dev)
diff --git a/src/southbridge/intel/ibexpeak/pch.h b/src/southbridge/intel/ibexpeak/pch.h
index 12e9345bf7..23eb6cd923 100644
--- a/src/southbridge/intel/ibexpeak/pch.h
+++ b/src/southbridge/intel/ibexpeak/pch.h
@@ -71,6 +71,7 @@ int pch_silicon_revision(void);
int pch_silicon_type(void);
int pch_silicon_supported(int type, int rev);
void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue);
+void gpi_route_interrupt(u8 gpi, u8 mode);
#if CONFIG_ELOG
void pch_log_state(void);
#endif
@@ -133,7 +134,12 @@ void southbridge_configure_default_intmap(void);
#define BIOS_CNTL 0xDC
#define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */
#define GPIO_CNTL 0x4C /* LPC GPIO Control Register */
+
#define GPIO_ROUT 0xb8
+#define GPI_DISABLE 0x00
+#define GPI_IS_SMI 0x01
+#define GPI_IS_SCI 0x02
+#define GPI_IS_NMI 0x03
#define PIRQA_ROUT 0x60
#define PIRQB_ROUT 0x61
diff --git a/src/southbridge/intel/ibexpeak/smihandler.c b/src/southbridge/intel/ibexpeak/smihandler.c
index 019e6db276..bfe5f5d0af 100644
--- a/src/southbridge/intel/ibexpeak/smihandler.c
+++ b/src/southbridge/intel/ibexpeak/smihandler.c
@@ -75,6 +75,42 @@ void tseg_relocate(void **ptr)
}
#endif
+static void alt_gpi_mask(u16 clr, u16 set)
+{
+ u16 alt_gp = inw(pmbase + ALT_GP_SMI_EN);
+ alt_gp &= ~clr;
+ alt_gp |= set;
+ outw(alt_gp, pmbase + ALT_GP_SMI_EN);
+}
+
+static void gpe0_mask(u32 clr, u32 set)
+{
+ u32 gpe0 = inl(pmbase + GPE0_EN);
+ gpe0 &= ~clr;
+ gpe0 |= set;
+ outl(gpe0, pmbase + GPE0_EN);
+}
+
+void gpi_route_interrupt(u8 gpi, u8 mode)
+{
+ u32 gpi_rout;
+ if (gpi >= 16)
+ return;
+
+ alt_gpi_mask(1 << gpi, 0);
+ gpe0_mask(1 << (gpi+16), 0);
+
+ gpi_rout = pci_read_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT);
+ gpi_rout &= ~(3 << (2 * gpi));
+ gpi_rout |= ((mode & 3) << (2 * gpi));
+ pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT, gpi_rout);
+
+ if (mode == GPI_IS_SCI)
+ gpe0_mask(0, 1 << (gpi+16));
+ else if (mode == GPI_IS_SMI)
+ alt_gpi_mask(0, 1 << gpi);
+}
+
/**
* @brief read and clear PM1_STS
* @return PM1_STS register
diff --git a/src/southbridge/intel/lynxpoint/lpc.c b/src/southbridge/intel/lynxpoint/lpc.c
index d753bea776..d83ec0a1f2 100644
--- a/src/southbridge/intel/lynxpoint/lpc.c
+++ b/src/southbridge/intel/lynxpoint/lpc.c
@@ -175,7 +175,7 @@ static void pch_gpi_routing(device_t dev)
reg32 |= (config->gpi14_routing & 0x03) << 28;
reg32 |= (config->gpi15_routing & 0x03) << 30;
- pci_write_config32(dev, 0xb8, reg32);
+ pci_write_config32(dev, GPIO_ROUT, reg32);
}
static void pch_power_options(device_t dev)