Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/29204
Change subject: ec/lenovo/h8: Wait for sense ready ......................................................................
ec/lenovo/h8: Wait for sense ready
Wait for the EC to fully boot before jumping to payload. The probed registers reads as zero until the EC is ready.
Tested on Lenovo T500.
Change-Id: Ie27e2881a256c4efb3def11f05070c446db6e5fc Signed-off-by: Patrick Rudolph siro@das-labor.org --- M src/ec/lenovo/h8/Makefile.inc M src/ec/lenovo/h8/h8.c M src/ec/lenovo/h8/h8.h A src/ec/lenovo/h8/sense.c 4 files changed, 79 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/04/29204/1
diff --git a/src/ec/lenovo/h8/Makefile.inc b/src/ec/lenovo/h8/Makefile.inc index e4408f1..6e98636 100644 --- a/src/ec/lenovo/h8/Makefile.inc +++ b/src/ec/lenovo/h8/Makefile.inc @@ -1,5 +1,9 @@ ifeq ($(CONFIG_EC_LENOVO_H8),y)
+ramstage-y += sense.c +romstage-y += sense.c +smm-y += sense.c + ifneq ($(filter y,$(CONFIG_H8_BEEP_ON_DEATH) $(CONFIG_H8_FLASH_LEDS_ON_DEATH)),) romstage-y += panic.c ramstage-y += panic.c diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c index 1f1655d..b4f1baa 100644 --- a/src/ec/lenovo/h8/h8.c +++ b/src/ec/lenovo/h8/h8.c @@ -24,6 +24,7 @@ #include <smbios.h> #include <pc80/mc146818rtc.h> #include <pc80/keyboard.h> +#include <delay.h>
#include "h8.h" #include "chip.h" @@ -316,7 +317,25 @@ #endif }
+static void h8_final(void *chip_info) +{ + int timeout = 3 * 1000; + + /* + * Wait for sense ready. + * May help preventing keyboard timeouts observed in the payload. + */ + while (timeout && !h8_get_sense_ready()) { + mdelay(1); + timeout--; + }; + + if (!timeout) + printk(BIOS_ERR, "H8: Failed waiting for sense ready\n"); +} + struct chip_operations ec_lenovo_h8_ops = { CHIP_NAME("Lenovo H8 EC") .enable_dev = h8_enable, + .final = h8_final, }; diff --git a/src/ec/lenovo/h8/h8.h b/src/ec/lenovo/h8/h8.h index 4ac395a..c92a084 100644 --- a/src/ec/lenovo/h8/h8.h +++ b/src/ec/lenovo/h8/h8.h @@ -31,6 +31,9 @@
void h8_mainboard_init_dock (void);
+int h8_get_fn_key(void); +int h8_get_sense_ready(void); + void h8_bluetooth_enable(int on); bool h8_bluetooth_nv_enable(void); bool h8_has_bdc(struct device *dev); @@ -89,6 +92,8 @@ #define H8_USB_ALWAYS_ON_ENABLE 0x01 #define H8_USB_ALWAYS_ON_AC_ONLY 0x0c
+#define H8_PASSWD_SCANCODE 0x27 + #define H8_FAN_CONTROL 0x2f #define H8_FAN_CONTROL_AUTO 0x80
@@ -130,6 +135,7 @@ #define H8_STATUS0 0x46 #define H8_STATUS1 0x47 #define H8_STATUS2 0x48 +#define H8_STATUS3 0x49
#define H8_EVENT_BAT0 0x4a #define H8_EVENT_BAT0_STATE 0x4b diff --git a/src/ec/lenovo/h8/sense.c b/src/ec/lenovo/h8/sense.c new file mode 100644 index 0000000..5e1f4bf --- /dev/null +++ b/src/ec/lenovo/h8/sense.c @@ -0,0 +1,50 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Patrick Rudolph siro@das-labor.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <ec/acpi/ec.h> + +#include "h8.h" + +/** + * Return the EC boot state. + * + * Some registers are all zero until the EC has booted. + * Wait for any register having at least one bit set. + * Unlikely that all register will be zero after booting has + * finished. + * + * @return 1 if the EC provides valid data in sense status registers + */ +int h8_get_sense_ready(void) +{ + static const u8 regs[] = { H8_STATUS0, H8_STATUS1, H8_STATUS2, + H8_STATUS3, H8_PASSWD_SCANCODE}; + + for (size_t i = 0; i < ARRAY_SIZE(regs); i++) + if (ec_read(regs[i])) + return 1; + return 0; +} + +/** + * Return the state of Fn key. + * Only valid if sense ready is true. + * + * @return 1 if the key is pressed. + */ +int h8_get_fn_key(void) +{ + return ec_read(H8_STATUS0) & H8_STATUS0_FN_KEY_DOWN; +}