Arthur Heymans has uploaded a new change for review. ( https://review.coreboot.org/19552 )
Change subject: [NOTFORMERGE]mb/lenovo/t400: Quick and dirty dock hotplug support ......................................................................
[NOTFORMERGE]mb/lenovo/t400: Quick and dirty dock hotplug support
Change-Id: I9676880540fe9e4c84c6fd47b8c85e76f54a8a68 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/cpu/x86/lapic/Makefile.inc M src/lib/Makefile.inc M src/mainboard/lenovo/t400/Makefile.inc M src/mainboard/lenovo/t400/acpi/dock.asl M src/southbridge/intel/i82801ix/i82801ix.h M src/southbridge/intel/i82801ix/smihandler.c 6 files changed, 62 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/52/19552/1
diff --git a/src/cpu/x86/lapic/Makefile.inc b/src/cpu/x86/lapic/Makefile.inc index 9df2c5f..9f3baba 100644 --- a/src/cpu/x86/lapic/Makefile.inc +++ b/src/cpu/x86/lapic/Makefile.inc @@ -3,6 +3,7 @@ ramstage-y += secondary.S romstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c ramstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c +smm-$(CONFIG_UDELAY_LAPIC) += apic_timer.c bootblock-y += boot_cpu.c verstage-y += boot_cpu.c romstage-y += boot_cpu.c diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 8f92b29..5de92a8 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -118,6 +118,7 @@ ramstage-y += malloc.c smm-$(CONFIG_SMM_TSEG) += malloc.c ramstage-y += delay.c +smm-y += delay.c ramstage-y += fallback_boot.c ramstage-y += compute_ip_checksum.c ramstage-y += cbfs.c diff --git a/src/mainboard/lenovo/t400/Makefile.inc b/src/mainboard/lenovo/t400/Makefile.inc index 3aa94b5..23a7fa2 100644 --- a/src/mainboard/lenovo/t400/Makefile.inc +++ b/src/mainboard/lenovo/t400/Makefile.inc @@ -13,6 +13,7 @@ ## GNU General Public License for more details. ##
+smm-$(CONFIG_HAVE_SMI_HANDLER) += dock.c romstage-y += dock.c
ramstage-y += dock.c diff --git a/src/mainboard/lenovo/t400/acpi/dock.asl b/src/mainboard/lenovo/t400/acpi/dock.asl index 36bf4bc..d8cacae 100644 --- a/src/mainboard/lenovo/t400/acpi/dock.asl +++ b/src/mainboard/lenovo/t400/acpi/dock.asl @@ -14,8 +14,17 @@ * GNU General Public License for more details. */
+#include "smi.h" + Scope (_SB) { + OperationRegion (DLPC, SystemIO, 0x164c, 1) + Field(DLPC, ByteAcc, NoLock, Preserve) + { + , 3, + DSTA, 1, + } + Device(DOCK) { Name(_HID, "ACPI0003") @@ -25,19 +34,14 @@ Method(_DCK, 1, NotSerialized) { if (Arg0) { + Sleep(250) /* connect dock */ - Store (1, \GP28) - _SB.PCI0.LPCB.EC.TLED(0x08) - _SB.PCI0.LPCB.EC.TLED(0x89) - Store (1, _SB.PCI0.LPCB.EC.DKR1) + TRAP(SMI_DOCK_CONNECT) } else { /* disconnect dock */ - Store (0, \GP28) - _SB.PCI0.LPCB.EC.TLED(0x08) - _SB.PCI0.LPCB.EC.TLED(0x09) - Store (0, _SB.PCI0.LPCB.EC.DKR1) + TRAP(SMI_DOCK_DISCONNECT) } - Xor(Arg0, _SB.PCI0.LPCB.EC.DKR1, Local0) + Xor(Arg0, DSTA, Local0) Return (Local0) }
diff --git a/src/southbridge/intel/i82801ix/i82801ix.h b/src/southbridge/intel/i82801ix/i82801ix.h index af4efcd..836fd2e 100644 --- a/src/southbridge/intel/i82801ix/i82801ix.h +++ b/src/southbridge/intel/i82801ix/i82801ix.h @@ -61,6 +61,9 @@ #define PM_LV5 0x17 #define PM_LV6 0x18 #define GPE0_STS 0x20 +#define GPE0_EN 0x2c +#define PME_B0_EN (1 << 13) +#define PME_EN (1 << 11) #define SMI_EN 0x30 #define PERIODIC_EN (1 << 14) #define TCO_EN (1 << 13) @@ -120,6 +123,12 @@ #define D31F0_C4TIMING_CNT 0xaa #define D31F0_GPIO_ROUT 0xb8 #define D31F0_RCBA 0xf0 + +#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) @@ -227,6 +236,7 @@ } #define LPC_IS_MOBILE(dev) lpc_is_mobile(pci_read_config16(dev, PCI_DEVICE_ID))
+void gpi_route_interrupt(u8 gpi, u8 mode); #if defined(__PRE_RAM__) void enable_smbus(void); int smbus_read_byte(unsigned device, unsigned address); diff --git a/src/southbridge/intel/i82801ix/smihandler.c b/src/southbridge/intel/i82801ix/smihandler.c index 7ad00ed..b29a6d9 100644 --- a/src/southbridge/intel/i82801ix/smihandler.c +++ b/src/southbridge/intel/i82801ix/smihandler.c @@ -39,6 +39,42 @@ void *tcg = (void *)0x0; void *smi1 = (void *)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), D31F0_GPIO_ROUT); + gpi_rout &= ~(3 << (2 * gpi)); + gpi_rout |= ((mode & 3) << (2 * gpi)); + pci_write_config32(PCI_DEV(0, 0x1f, 0), D31F0_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