summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/dmp/dmp_post_code.h1
-rw-r--r--src/southbridge/dmp/vortex86ex/southbridge.c32
2 files changed, 29 insertions, 4 deletions
diff --git a/src/cpu/dmp/dmp_post_code.h b/src/cpu/dmp/dmp_post_code.h
index 6658ce8b02..f699171a44 100644
--- a/src/cpu/dmp/dmp_post_code.h
+++ b/src/cpu/dmp/dmp_post_code.h
@@ -25,6 +25,7 @@
#define POST_DMP_KBD_FW_UPLOAD 0x06
#define POST_DMP_KBD_CHK_READY 0x07
#define POST_DMP_KBD_IS_READY 0x08
+#define POST_DMP_KBD_IS_BAD 0x09
#define POST_DMP_KBD_FW_VERIFY_ERR 0x82
#define POST_DMP_ID_ERR 0x85
#define POST_DMP_DRAM_TEST_ERR 0x86
diff --git a/src/southbridge/dmp/vortex86ex/southbridge.c b/src/southbridge/dmp/vortex86ex/southbridge.c
index 61c484f9ae..61dceea124 100644
--- a/src/southbridge/dmp/vortex86ex/southbridge.c
+++ b/src/southbridge/dmp/vortex86ex/southbridge.c
@@ -25,6 +25,7 @@
#include <pc80/mc146818rtc.h>
#include <pc80/keyboard.h>
#include <string.h>
+#include <delay.h>
#include "arch/io.h"
#include "chip.h"
#include "southbridge.h"
@@ -90,6 +91,9 @@ static const unsigned char irq_to_int_routing[16] = {
#define LPT_PDMAS 0
#define LPT_DREQS 0
+/* keyboard controller system flag timeout : 400 ms */
+#define KBC_TIMEOUT_SYS_FLAG 400
+
static u8 get_pci_dev_func(device_t dev)
{
return PCI_FUNC(dev->path.pci.devfn);
@@ -135,15 +139,21 @@ static void upload_dmp_keyboard_firmware(struct device *dev)
pci_write_config32(dev, SB_REG_IPFCR, reg_sb_c0 & ~0x400L);
}
-static void kbc_wait_system_flag(void)
+static int kbc_wait_system_flag(void)
{
/* wait keyboard controller ready by checking system flag
* (status port bit 2).
*/
post_code(POST_DMP_KBD_CHK_READY);
- while ((inb(0x64) & 0x4) == 0) {
+ u32 timeout;
+ for (timeout = KBC_TIMEOUT_SYS_FLAG;
+ timeout && ((inb(0x64) & 0x4) == 0); timeout--)
+ mdelay(1);
+
+ if (!timeout) {
+ printk(BIOS_WARNING, "Keyboard controller system flag timeout\n");
}
- post_code(POST_DMP_KBD_IS_READY);
+ return !!timeout;
}
static void pci_routing_fixup(struct device *dev)
@@ -572,7 +582,21 @@ static void southbridge_init(struct device *dev)
fix_cmos_rtc_time();
rtc_init(0);
- kbc_wait_system_flag();
+ /* Check keyboard controller ready. If timeout, reload firmware code
+ * and try again.
+ */
+ u32 retries = 10;
+ while (!kbc_wait_system_flag()) {
+ if (!retries) {
+ post_code(POST_DMP_KBD_IS_BAD);
+ die("The keyboard timeout occurred too often. "
+ "Your CPU is probably defect. "
+ "Contact your dealer to replace it\n");
+ }
+ upload_dmp_keyboard_firmware(dev);
+ retries--;
+ }
+ post_code(POST_DMP_KBD_IS_READY);
pc_keyboard_init(0);
}