Sven Schnelle (svens@stackframe.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/597
-gerrit
commit 53fe1f939c9f1b5ac8787c61f7c2fb285c3933fc Author: Sven Schnelle svens@stackframe.org Date: Tue Jan 10 14:44:12 2012 +0100
X60: fix docking
Fix ordering of power/reset/undock procedure to prevent crashes seen with the old code. Also call dlpc_init() only once.
Change-Id: I27d1f42e845fcccde40e6ca5af4a7762edab5d36 Signed-off-by: Sven Schnelle svens@stackframe.org --- src/mainboard/lenovo/x60/dock.c | 33 +++++++++++++++++++---------- src/mainboard/lenovo/x60/mainboard_smi.c | 5 ++- src/mainboard/lenovo/x60/romstage.c | 4 +- 3 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/src/mainboard/lenovo/x60/dock.c b/src/mainboard/lenovo/x60/dock.c index eed00a1..37d5b76 100644 --- a/src/mainboard/lenovo/x60/dock.c +++ b/src/mainboard/lenovo/x60/dock.c @@ -107,6 +107,15 @@ int dlpc_init(void) /* Activate DLPC */ dlpc_write_register(0x30, 0x01);
+ dlpc_gpio_init(); + + return 0; +} + +int dock_connect(void) +{ + int timeout = 1000; + outb(0x07, 0x164c);
timeout = 1000; @@ -121,26 +130,18 @@ int dlpc_init(void) return 1; }
- dlpc_gpio_init(); - - return 0; -} - -int dock_connect(void) -{ - int timeout = 1000; - /* Assert D_PLTRST# */ outb(0xfe, 0x1680); udelay(100000); /* Deassert D_PLTRST# */ outb(0xff, 0x1680);
- udelay(1000); + udelay(100000);
/* startup 14.318MHz Clock */ dock_write_register(0x29, 0x06); /* wait until clock is settled */ + timeout = 1000; while(!(dock_read_register(0x29) & 0x08) && timeout--) udelay(1000);
@@ -243,12 +244,20 @@ int dock_connect(void)
void dock_disconnect(void) { - /* disable Ultrabay and USB Power */ - outb(0x00, 0x1628); + printk(BIOS_DEBUG, "%s enter\n", __func__); /* disconnect LPC bus */ outb(0x00, 0x164c); + udelay(10000); + /* Assert PLTRST and DLPCPD */ outb(0xfc, 0x1680); + udelay(10000); + + /* disable Ultrabay and USB Power */ + outb(0x00, 0x1628); + udelay(10000); + + printk(BIOS_DEBUG, "%s finish\n", __func__); }
int dock_present(void) diff --git a/src/mainboard/lenovo/x60/mainboard_smi.c b/src/mainboard/lenovo/x60/mainboard_smi.c index 34f1d36..bd1333a 100644 --- a/src/mainboard/lenovo/x60/mainboard_smi.c +++ b/src/mainboard/lenovo/x60/mainboard_smi.c @@ -28,6 +28,7 @@ #include <ec/acpi/ec.h> #include <pc80/mc146818rtc.h> #include <ec/lenovo/h8/h8.h> +#include <delay.h> #include "dock.h" #include "smi.h"
@@ -72,8 +73,8 @@ int mainboard_io_trap_handler(int smif) switch (smif) { case SMI_DOCK_CONNECT: ec_clr_bit(0x03, 2); - dlpc_init(); - if (!dlpc_init() && !dock_connect()) { + udelay(250000); + if (!dock_connect()) { ec_set_bit(0x03, 2); /* set dock LED to indicate status */ ec_write(0x0c, 0x09); diff --git a/src/mainboard/lenovo/x60/romstage.c b/src/mainboard/lenovo/x60/romstage.c index 44cde72..ee080ea 100644 --- a/src/mainboard/lenovo/x60/romstage.c +++ b/src/mainboard/lenovo/x60/romstage.c @@ -229,12 +229,12 @@ void main(unsigned long bist)
ich7_enable_lpc();
- + dlpc_init(); /* dock_init initializes the DLPC switch on * thinpad side, so this is required even * if we're undocked. */ - if (!dlpc_init() && dock_present()) { + if (dock_present()) { dock_connect(); early_superio_config(); /* Set up the console */