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>
Reviewed-on: http://review.coreboot.org/597
Tested-by: build bot (Jenkins)
This commit is contained in:
Sven Schnelle
2012-01-10 14:44:12 +01:00
parent fc4e7333e0
commit 483ec41e6f
3 changed files with 26 additions and 16 deletions

View File

@@ -107,6 +107,15 @@ int dlpc_init(void)
/* Activate DLPC */ /* Activate DLPC */
dlpc_write_register(0x30, 0x01); dlpc_write_register(0x30, 0x01);
dlpc_gpio_init();
return 0;
}
int dock_connect(void)
{
int timeout = 1000;
outb(0x07, 0x164c); outb(0x07, 0x164c);
timeout = 1000; timeout = 1000;
@@ -121,26 +130,18 @@ int dlpc_init(void)
return 1; return 1;
} }
dlpc_gpio_init();
return 0;
}
int dock_connect(void)
{
int timeout = 1000;
/* Assert D_PLTRST# */ /* Assert D_PLTRST# */
outb(0xfe, 0x1680); outb(0xfe, 0x1680);
udelay(100000); udelay(100000);
/* Deassert D_PLTRST# */ /* Deassert D_PLTRST# */
outb(0xff, 0x1680); outb(0xff, 0x1680);
udelay(1000); udelay(100000);
/* startup 14.318MHz Clock */ /* startup 14.318MHz Clock */
dock_write_register(0x29, 0x06); dock_write_register(0x29, 0x06);
/* wait until clock is settled */ /* wait until clock is settled */
timeout = 1000;
while(!(dock_read_register(0x29) & 0x08) && timeout--) while(!(dock_read_register(0x29) & 0x08) && timeout--)
udelay(1000); udelay(1000);
@@ -243,12 +244,20 @@ int dock_connect(void)
void dock_disconnect(void) void dock_disconnect(void)
{ {
/* disable Ultrabay and USB Power */ printk(BIOS_DEBUG, "%s enter\n", __func__);
outb(0x00, 0x1628);
/* disconnect LPC bus */ /* disconnect LPC bus */
outb(0x00, 0x164c); outb(0x00, 0x164c);
udelay(10000);
/* Assert PLTRST and DLPCPD */ /* Assert PLTRST and DLPCPD */
outb(0xfc, 0x1680); 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) int dock_present(void)

View File

@@ -28,6 +28,7 @@
#include <ec/acpi/ec.h> #include <ec/acpi/ec.h>
#include <pc80/mc146818rtc.h> #include <pc80/mc146818rtc.h>
#include <ec/lenovo/h8/h8.h> #include <ec/lenovo/h8/h8.h>
#include <delay.h>
#include "dock.h" #include "dock.h"
#include "smi.h" #include "smi.h"
@@ -72,8 +73,8 @@ int mainboard_io_trap_handler(int smif)
switch (smif) { switch (smif) {
case SMI_DOCK_CONNECT: case SMI_DOCK_CONNECT:
ec_clr_bit(0x03, 2); ec_clr_bit(0x03, 2);
dlpc_init(); udelay(250000);
if (!dlpc_init() && !dock_connect()) { if (!dock_connect()) {
ec_set_bit(0x03, 2); ec_set_bit(0x03, 2);
/* set dock LED to indicate status */ /* set dock LED to indicate status */
ec_write(0x0c, 0x09); ec_write(0x0c, 0x09);

View File

@@ -229,12 +229,12 @@ void main(unsigned long bist)
ich7_enable_lpc(); ich7_enable_lpc();
dlpc_init();
/* dock_init initializes the DLPC switch on /* dock_init initializes the DLPC switch on
* thinpad side, so this is required even * thinpad side, so this is required even
* if we're undocked. * if we're undocked.
*/ */
if (!dlpc_init() && dock_present()) { if (dock_present()) {
dock_connect(); dock_connect();
early_superio_config(); early_superio_config();
/* Set up the console */ /* Set up the console */