summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ec/lenovo/pmh7/Makefile.inc2
-rw-r--r--src/ec/lenovo/pmh7/pmh7.c4
-rw-r--r--src/mainboard/lenovo/t60/dock.c37
-rw-r--r--src/mainboard/lenovo/t60/dock.h3
-rw-r--r--src/mainboard/lenovo/t60/mainboard.c11
-rw-r--r--src/mainboard/lenovo/t60/mainboard_smi.c8
-rw-r--r--src/mainboard/lenovo/t60/romstage.c21
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 */