diff options
-rw-r--r-- | src/ec/lenovo/pmh7/Makefile.inc | 2 | ||||
-rw-r--r-- | src/ec/lenovo/pmh7/pmh7.c | 4 | ||||
-rw-r--r-- | src/mainboard/lenovo/t60/dock.c | 37 | ||||
-rw-r--r-- | src/mainboard/lenovo/t60/dock.h | 3 | ||||
-rw-r--r-- | src/mainboard/lenovo/t60/mainboard.c | 11 | ||||
-rw-r--r-- | src/mainboard/lenovo/t60/mainboard_smi.c | 8 | ||||
-rw-r--r-- | src/mainboard/lenovo/t60/romstage.c | 21 |
7 files changed, 66 insertions, 20 deletions
diff --git a/src/ec/lenovo/pmh7/Makefile.inc b/src/ec/lenovo/pmh7/Makefile.inc index 4c891b25ab..e441980def 100644 --- a/src/ec/lenovo/pmh7/Makefile.inc +++ b/src/ec/lenovo/pmh7/Makefile.inc @@ -1 +1,3 @@ driver-y += pmh7.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += pmh7.c +romstage-y += pmh7.c diff --git a/src/ec/lenovo/pmh7/pmh7.c b/src/ec/lenovo/pmh7/pmh7.c index 30460c9021..844e233e9f 100644 --- a/src/ec/lenovo/pmh7/pmh7.c +++ b/src/ec/lenovo/pmh7/pmh7.c @@ -91,6 +91,8 @@ void pmh7_register_write(int reg, int val) outb(val, EC_LENOVO_PMH7_DATA); } +#ifndef __PRE_RAM__ +#ifndef __SMM__ static void enable_dev(device_t dev) { struct ec_lenovo_pmh7_config *conf = dev->chip_info; @@ -115,3 +117,5 @@ struct chip_operations ec_lenovo_pmh7_ops = { CHIP_NAME("Lenovo Power Management Hardware Hub 7") .enable_dev = enable_dev, }; +#endif +#endif diff --git a/src/mainboard/lenovo/t60/dock.c b/src/mainboard/lenovo/t60/dock.c index 6642bb3759..5cd8997355 100644 --- a/src/mainboard/lenovo/t60/dock.c +++ b/src/mainboard/lenovo/t60/dock.c @@ -28,8 +28,11 @@ #include "dock.h" #include "superio/nsc/pc87384/pc87384.h" #include "ec/acpi/ec.h" +#include "ec/lenovo/pmh7/pmh7.h" #include "southbridge/intel/i82801gx/i82801gx.h" +#define DLPC_CONTROL 0x164c + static void dlpc_write_register(int reg, int value) { outb(reg, 0x164e); @@ -102,12 +105,15 @@ int dlpc_init(void) /* Select DLPC module */ dlpc_write_register(0x07, 0x19); - /* DLPC Base Address 0x164c */ - dlpc_write_register(0x60, 0x16); - dlpc_write_register(0x61, 0x4c); + /* DLPC Base Address */ + dlpc_write_register(0x60, (DLPC_CONTROL >> 8) & 0xff); + dlpc_write_register(0x61, DLPC_CONTROL & 0xff); /* Activate DLPC */ dlpc_write_register(0x30, 0x01); + /* Reset docking state */ + outb(0x00, DLPC_CONTROL); + dlpc_gpio_init(); return 0; } @@ -127,7 +133,7 @@ static int dock_superio_init(void) /* set GPIO pins to Serial/Parallel Port * functions */ - dock_write_register(0x22, 0xeb); + dock_write_register(0x22, 0xa9); dock_write_register(0x07, PC87384_GPIO); dock_write_register(0x60, 0x16); @@ -179,16 +185,16 @@ int dock_connect(void) { int timeout = 1000; - outb(0x07, 0x164c); + outb(0x07, DLPC_CONTROL); timeout = 1000; - while(!(inb(0x164c) & 8) && timeout--) + while(!(inb(DLPC_CONTROL) & 8) && timeout--) udelay(1000); if (!timeout) { /* docking failed, disable DLPC switch */ - outb(0x00, 0x164c); + outb(0x00, DLPC_CONTROL); dlpc_write_register(0x30, 0x00); return 1; } @@ -206,14 +212,25 @@ int dock_connect(void) void dock_disconnect(void) { /* disconnect LPC bus */ - outb(0x00, 0x164c); + outb(0x00, DLPC_CONTROL); /* Assert PLTRST and DLPCPD */ outb(0xfc, 0x1680); } int dock_present(void) { - outb(0x61, 0x15ec); - return inb(0x15ee) & 1; + return pmh7_register_read(0x61) & 1; +} + +int legacy_io_present(void) +{ + return !(inb(DEFAULT_GPIOBASE + 0x0c) & 0x40); } +void legacy_io_init(void) +{ + /* Enable Power for Ultrabay slot */ + pmh7_ultrabay_power_enable(1); + udelay(100000); + dock_superio_init(); +} diff --git a/src/mainboard/lenovo/t60/dock.h b/src/mainboard/lenovo/t60/dock.h index 9d35d9faf5..631f007488 100644 --- a/src/mainboard/lenovo/t60/dock.h +++ b/src/mainboard/lenovo/t60/dock.h @@ -24,4 +24,7 @@ extern int dock_connect(void); extern void dock_disconnect(void); extern int dock_present(void); extern int dlpc_init(void); + +extern int legacy_io_present(void); +extern void legacy_io_init(void); #endif diff --git a/src/mainboard/lenovo/t60/mainboard.c b/src/mainboard/lenovo/t60/mainboard.c index 2b8c5fe4b1..8456992044 100644 --- a/src/mainboard/lenovo/t60/mainboard.c +++ b/src/mainboard/lenovo/t60/mainboard.c @@ -38,6 +38,7 @@ static void mainboard_enable(device_t dev) { + struct southbridge_intel_i82801gx_config *config; device_t dev0, idedev; u8 defaults_loaded = 0; @@ -50,8 +51,14 @@ static void mainboard_enable(device_t dev) ec_write(0x0c, 0xc7); idedev = dev_find_slot(0, PCI_DEVFN(0x1f,1)); - if (idedev && idedev->chip_info && h8_ultrabay_device_present()) { - struct southbridge_intel_i82801gx_config *config = idedev->chip_info; + + if (!(inb(DEFAULT_GPIOBASE + 0x0c) & 0x40)) { + /* legacy I/O connected */ + pmh7_ultrabay_power_enable(1); + ec_write(0x0c, 0x84); + } else if (idedev && idedev->chip_info && + h8_ultrabay_device_present()) { + config = idedev->chip_info; config->ide_enable_primary = 1; pmh7_ultrabay_power_enable(1); ec_write(0x0c, 0x84); diff --git a/src/mainboard/lenovo/t60/mainboard_smi.c b/src/mainboard/lenovo/t60/mainboard_smi.c index 4a0b5062c9..eb282564af 100644 --- a/src/mainboard/lenovo/t60/mainboard_smi.c +++ b/src/mainboard/lenovo/t60/mainboard_smi.c @@ -75,7 +75,13 @@ int mainboard_io_trap_handler(int smif) switch (smif) { case SMI_DOCK_CONNECT: - dlpc_init(); + /* If there's an legacy I/O module present, we're not + * allowed to connect the Docking LPC Bus, as both Super I/O + * chips are using 0x2e as base address. + */ + if (legacy_io_present()) + break; + if (!dock_connect()) { /* set dock LED to indicate status */ ec_write(0x0c, 0x08); diff --git a/src/mainboard/lenovo/t60/romstage.c b/src/mainboard/lenovo/t60/romstage.c index 252ae40023..7ed776830e 100644 --- a/src/mainboard/lenovo/t60/romstage.c +++ b/src/mainboard/lenovo/t60/romstage.c @@ -210,7 +210,7 @@ static void early_ich7_init(void) void main(unsigned long bist) { u32 reg32; - int boot_mode = 0; + int boot_mode = 0, dock_err; const u8 spd_addrmap[2 * DIMM_SOCKETS] = { 0x50, 0x52, 0x51, 0x53 }; if (bist == 0) @@ -223,15 +223,21 @@ void main(unsigned long bist) ich7_enable_lpc(); + /* We want early GPIO setup, to be able to detect legacy I/O module */ + pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIOBASE, DEFAULT_GPIOBASE | 1); + /* Enable GPIOs */ + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x4c /* GC */ , 0x10); + setup_ich7_gpios(); - /* dock_init initializes the DLPC switch on - * thinpad side, so this is required even - * if we're undocked. - */ - if (!dlpc_init() && dock_present()) { + dock_err = dlpc_init(); + + /* We prefer Legacy I/O module over docking */ + if (legacy_io_present()) { + legacy_io_init(); + early_superio_config(); + } else if (!dock_err && dock_present()) { dock_connect(); early_superio_config(); - /* Set up the console */ } #if CONFIG_USBDEBUG @@ -239,6 +245,7 @@ void main(unsigned long bist) early_usbdebug_init(); #endif + /* Setup the console */ console_init(); /* Halt if there was a built in self test failure */ |