[coreboot-gerrit] Change in coreboot[master]: mb/lenovo/t400: Improve docking code

Patrick Rudolph (Code Review) gerrit at coreboot.org
Thu Nov 1 11:01:05 CET 2018


Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/29418


Change subject: mb/lenovo/t400: Improve docking code
......................................................................

mb/lenovo/t400: Improve docking code

* Remove dead code
* Add support for types 2504 and 2505
* Print dock info at romstage entry
* Improve dock disconnect for type 2505
* Move defines into dock.h for future ACPI code
* Reduce timeouts according to spec to decrease boot time on error
* Fix no docking detection (reduces boot time by 1 second)
* Configure GPIO LDN before reading GPIOs

Tested on Lenovo T500 with docking 2504 and 2505.

Change-Id: Ic4510ffadc67da95961cecd51a6d8ed856b3ac99
Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
M src/mainboard/lenovo/t400/dock.c
M src/mainboard/lenovo/t400/dock.h
M src/mainboard/lenovo/t400/romstage.c
3 files changed, 79 insertions(+), 41 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/29418/1

diff --git a/src/mainboard/lenovo/t400/dock.c b/src/mainboard/lenovo/t400/dock.c
index 0c6db0b..fa33337 100644
--- a/src/mainboard/lenovo/t400/dock.c
+++ b/src/mainboard/lenovo/t400/dock.c
@@ -34,10 +34,8 @@
 	u8 mode;
 };
 
-static int poll_clk_stable(pnp_devfn_t dev)
+static int poll_clk_stable(pnp_devfn_t dev, int timeout)
 {
-	int timeout = 1000;
-
 	/* Enable 14.318MHz CLK on CLKIN */
 	pnp_write_config(dev, 0x29, 0xa0);
 	while(!(pnp_read_config(dev, 0x29) & 0x10) && timeout--)
@@ -69,20 +67,10 @@
 static const pnp_devfn_t l_dlpc = PNP_DEV(0x164e, PC87382_DOCK);
 static const pnp_devfn_t l_gpio = PNP_DEV(0x164e, PC87382_GPIO);
 
-#define DLPC_CONTROL	0x164c
-#define DLPC_GPIO_BASE	0x1680
-
-#define DLPC_GPDO0		(DLPC_GPIO_BASE + 0x0)
-#define DLPC_GPDI0		(DLPC_GPIO_BASE + 0x1)
-#define		D_PLTRST	0x01
-#define		D_LPCPD		0x02
-
-#define DLPC_GPDO2		(DLPC_GPIO_BASE + 0x8)
-#define DLPC_GPDI2		(DLPC_GPIO_BASE + 0x9)
-
 static int pc87382_init(pnp_devfn_t dlpc, u16 dlpc_base)
 {
-	int timeout = 1000;
+	/* Maximum 3300 LCLKs at 14.318MHz */
+	int timeout = 230;
 
 	/* Enable LPC bridge LDN. */
 	pnp_set_logical_device(dlpc);
@@ -93,7 +81,7 @@
 	outb(0x00, dlpc_base);
 	outb(0x07, dlpc_base);
 	while (!(inb(dlpc_base) & 8) && timeout--)
-		udelay(1000);
+		udelay(1);
 	if (!timeout)
 		return 1;
 
@@ -106,8 +94,10 @@
 
 	/* Disconnect LPC bus */
 	u16 dlpc_base = pnp_read_iobase(dlpc, PNP_IDX_IO0);
-	outb(0x00, dlpc_base);
-	pnp_set_enable(dlpc, 0);
+	if (dlpc_base) {
+		outb(0x00, dlpc_base);
+		pnp_set_enable(dlpc, 0);
+	}
 }
 
 static const struct pin_config local_gpio[] = {
@@ -115,18 +105,26 @@
 	{0x04, 4},	{0x20, 4},	{0x21, 4},	{0x23, 4},
 };
 
-static int pc87382_connect(void)
+/* Enable internal clock and configure GPIO LDN */
+int pc87382_early(void)
 {
-	u8 reg;
-
-	if (poll_clk_stable(l_gpio) != 0)
+	/* Wake-up time is 33 msec (maximum). */
+	if (poll_clk_stable(l_gpio, 33) != 0)
 		return 1;
 
+	/* Set up GPIOs */
 	if (gpio_init(l_gpio, DLPC_GPIO_BASE,
 		local_gpio, ARRAY_SIZE(local_gpio)) != 0) {
 		return 1;
 	}
 
+	return 0;
+}
+
+static int pc87382_connect(void)
+{
+	u8 reg;
+
 	reg = inb(DLPC_GPDO0);
 	reg |= D_PLTRST | D_LPCPD;
 	/* Deassert D_PLTRST# and D_LPCPD# */
@@ -158,10 +156,12 @@
 	outb(reg, DLPC_GPDO0);
 }
 
+/* Returns 3bit dock id */
 static u8 dock_identify(void)
 {
 	u8 id;
 
+	/* Make sure GPIO LDN is configured first ! */
 	id = (inb(DLPC_GPDI0) >> 4) & 1;
 	id |= (inb(DLPC_GPDI2) & 3) << 1;
 
@@ -172,10 +172,8 @@
 
 #include <superio/nsc/pc87384/pc87384.h>
 
-static const pnp_devfn_t r_gpio = PNP_DEV(0x2e, PC87384_GPIO);
-static const pnp_devfn_t r_serial = PNP_DEV(0x2e, PC87384_SP1);
-
-#define DOCK_GPIO_BASE	0x1620
+static const pnp_devfn_t r_gpio = PNP_DEV(SUPERIO_DEV, PC87384_GPIO);
+static const pnp_devfn_t r_serial = PNP_DEV(SUPERIO_DEV, PC87384_SP1);
 
 static const struct pin_config remote_gpio[] = {
 	{0x00, PC87384_GPIO_PIN_DEBOUNCE | PC87384_GPIO_PIN_PULLUP},
@@ -190,7 +188,7 @@
 
 static int pc87384_init(void)
 {
-	if (poll_clk_stable(r_gpio) != 0)
+	if (poll_clk_stable(r_gpio, 1000) != 0)
 		return 1;
 
 	/* set GPIO pins to Serial/Parallel Port
@@ -199,9 +197,11 @@
 	pnp_write_config(r_gpio, 0x22, 0xa9);
 
 	/* enable serial port */
-	pnp_set_logical_device(r_serial);
-	pnp_set_iobase(r_serial, PNP_IDX_IO0, 0x3f8);
-	pnp_set_enable(r_serial, 1);
+	if (IS_ENABLED(CONFIG_CONSOLE_SERIAL)) {
+		pnp_set_logical_device(r_serial);
+		pnp_set_iobase(r_serial, PNP_IDX_IO0, CONFIG_TTYS0_BASE);
+		pnp_set_enable(r_serial, 1);
+	}
 
 	if (gpio_init(r_gpio, DOCK_GPIO_BASE,
 		remote_gpio, ARRAY_SIZE(remote_gpio)) != 0)
@@ -228,14 +228,16 @@
 
 void dock_connect(void)
 {
-	if (dock_identify() == 0)
+	const u8 id = dock_identify();
+
+	/* Dock type 2505 doesn't have serial, LPT port or LEDs */
+	if (id == DOCK_TYPE_NONE || id == DOCK_TYPE_2505)
 		return;
 
-	if (pc87382_connect() != 0) {
+	if (pc87382_connect() != 0 || pc87384_init() != 0) {
 		pc87382_disconnect();
 		return;
 	}
-	pc87384_init();
 
 	ec_write(H8_LED_CONTROL,
 		 H8_LED_CONTROL_OFF | H8_LED_CONTROL_DOCK_LED1);
@@ -253,13 +255,12 @@
 		 H8_LED_CONTROL_OFF | H8_LED_CONTROL_DOCK_LED2);
 }
 
-void h8_mainboard_init_dock(void)
+void dock_info(void)
 {
-	u8 id = dock_identify();
+	const u8 id = dock_identify();
 
-	if (id != 0) {
-		printk(BIOS_DEBUG, "dock (id=%d) is present\n", id);
-		dock_connect();
-	} else
-		printk(BIOS_DEBUG, "dock is not connected\n");
+	if (id != DOCK_TYPE_NONE)
+		printk(BIOS_DEBUG, "DOCK: is present: id=%d\n", id);
+	else
+		printk(BIOS_DEBUG, "DOCK: not connected\n");
 }
diff --git a/src/mainboard/lenovo/t400/dock.h b/src/mainboard/lenovo/t400/dock.h
index 74b730c..d94cb9e 100644
--- a/src/mainboard/lenovo/t400/dock.h
+++ b/src/mainboard/lenovo/t400/dock.h
@@ -16,7 +16,34 @@
 #ifndef THINKPAD_T400_DOCK_H
 #define THINKPAD_T400_DOCK_H
 
+#if ENV_ROMSTAGE || ENV_RAMSTAGE || ENV_SMM
+int pc87382_early(void);
+
 void dock_connect(void);
 void dock_disconnect(void);
 int dock_present(void);
+void dock_info(void);
+#endif
+
+/* pc87382 */
+#define DLPC_CONTROL	0x164c
+#define DLPC_GPIO_BASE	0x1680
+
+#define DLPC_GPDO0		(DLPC_GPIO_BASE + 0x0)
+#define DLPC_GPDI0		(DLPC_GPIO_BASE + 0x1)
+#define		D_PLTRST	0x01
+#define		D_LPCPD		0x02
+
+#define DLPC_GPDO2		(DLPC_GPIO_BASE + 0x8)
+#define DLPC_GPDI2		(DLPC_GPIO_BASE + 0x9)
+
+ /* Pullups on all GPIOs, dock pulls ID pins low */
+#define DOCK_TYPE_2504 1
+#define DOCK_TYPE_2505 2
+#define DOCK_TYPE_NONE 7
+
+/* pc87384 */
+#define SUPERIO_DEV 0x2e
+#define DOCK_GPIO_BASE	0x1620
+
 #endif
diff --git a/src/mainboard/lenovo/t400/romstage.c b/src/mainboard/lenovo/t400/romstage.c
index 7bf14bf..01886dd 100644
--- a/src/mainboard/lenovo/t400/romstage.c
+++ b/src/mainboard/lenovo/t400/romstage.c
@@ -66,6 +66,7 @@
 	sysinfo_t sysinfo;
 	int s3resume = 0;
 	int cbmem_initted;
+	int err;
 	u16 reg16;
 
 	timestamp_init(get_initial_timestamp());
@@ -81,11 +82,20 @@
 	i82801ix_early_init();
 	early_lpc_setup();
 
-	dock_connect();
+	/* Minimal setup to detect dock */
+	err = pc87382_early();
+	if (err == 0)
+		dock_connect();
 
 	console_init();
 	printk(BIOS_DEBUG, "running main(bist = %lu)\n", bist);
 
+	/* Print dock info */
+	if (err)
+		printk(BIOS_ERR, "DOCK: Failed to init pc87382\n");
+
+	dock_info();
+
 	reg16 = pci_read_config16(LPC_DEV, D31F0_GEN_PMCON_3);
 	pci_write_config16(LPC_DEV, D31F0_GEN_PMCON_3, reg16);
 	if ((MCHBAR16(SSKPD_MCHBAR) == 0xCAFE) && !(reg16 & (1 << 9))) {

-- 
To view, visit https://review.coreboot.org/29418
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic4510ffadc67da95961cecd51a6d8ed856b3ac99
Gerrit-Change-Number: 29418
Gerrit-PatchSet: 1
Gerrit-Owner: Patrick Rudolph <siro at das-labor.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20181101/5d9096e3/attachment-0001.html>


More information about the coreboot-gerrit mailing list