Andrew Wu (arw@dmp.com.tw) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3958
-gerrit
commit 79f98518213c20c8b7c9373290351adca161711a Author: Andrew Wu arw@dmp.com.tw Date: Fri Oct 11 13:44:55 2013 +0800
keyboard: Check keyboard controller is ready before initialization
PS/2 keyboard controller (8042) has a system flag bit in status byte (bit 2 of 0x64 port). This bit indicates keyboard controller is ready or not. System reset clears this bit, and when keyboard controller is ready, this bit is set.
Add checking system flag bit in pc_keyboard_init function to make sure keyboard controller is ready to accept commands.
It is important for Vortex86EX keyboard controller, which has a long startup time.
Change-Id: I2cdb533a5b25575e1717434533a60decf748f6d8 Signed-off-by: Andrew Wu arw@dmp.com.tw --- src/drivers/pc80/keyboard.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/src/drivers/pc80/keyboard.c b/src/drivers/pc80/keyboard.c index 2888bcf..74846f5 100644 --- a/src/drivers/pc80/keyboard.c +++ b/src/drivers/pc80/keyboard.c @@ -31,6 +31,7 @@ #define KBD_STATUS 0x64 #define KBD_IBF (1 << 1) // 1: input buffer full (data ready for ec) #define KBD_OBF (1 << 0) // 1: output buffer full (data ready for host) +#define KBD_SYS_FLAG (1 << 2) // 1: self-test passed
// Keyboard Controller Commands #define KBC_CMD_READ_COMMAND 0x20 // Read command byte @@ -64,6 +65,19 @@ /* Wait 400ms for keyboard controller answers */ #define KBC_TIMEOUT_IN_MS 400
+static int kbc_wait_system_flag(void) +{ + u32 timeout; + for(timeout = KBC_TIMEOUT_IN_MS; timeout && ((inb(KBD_STATUS) & KBD_SYS_FLAG) == 0); timeout--) { + mdelay(1); + } + + if (!timeout) { + printk(BIOS_INFO, "Keyboard controller system flag timeout\n"); + } + return !!timeout; +} + static int kbc_input_buffer_empty(void) { u32 timeout; @@ -196,6 +210,10 @@ void pc_keyboard_init(struct pc_keyboard *keyboard) return; printk(BIOS_DEBUG, "Keyboard init...\n");
+ /* Wait until keyboard controller ready (system flag = 1) */ + if (!kbc_wait_system_flag()) + return; + /* Run a keyboard controller self-test */ if (!kbc_self_test()) return;