From dc82ca44d348665132584a21c89ed824562e9696 Mon Sep 17 00:00:00 2001 From: "Vic (Chun-Ju) Yang" Date: Fri, 10 Jan 2014 15:19:41 +0800 Subject: mec1322: Refine reset cause detection The VBAT POR indication is unreliable for detecting a power-on reset, and thus we often see "unknown" reset cause when we should see "power-on". A better indication is to check for VCC1 POR, which manifests by clearing watchdog count. The catch is that we still cannot tell power-on reset from reset-pin reset. Also, to distinguish soft/hard reset from actual watchdog reset, we need to explicitly save soft/hard reset flag before triggering watchdog reset. BUG=chrome-os-partner:24107 TEST=Power cycle EVB and see 'power-on' reset cause. TEST='reboot' and see 'soft' reset cause. TEST='reboot hard' and see 'hard' reset cause. TEST='waitms 2000' and see 'watchdog' reset cause. BRANCH=None Change-Id: I0075f5bf5cdb032d206c4a53c586b75b69093235 Signed-off-by: Vic (Chun-Ju) Yang Reviewed-on: https://chromium-review.googlesource.com/182120 Reviewed-by: Randall Spangler --- chip/mec1322/registers.h | 1 + chip/mec1322/system.c | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/chip/mec1322/registers.h b/chip/mec1322/registers.h index 47a839ed96..edc276f0eb 100644 --- a/chip/mec1322/registers.h +++ b/chip/mec1322/registers.h @@ -43,6 +43,7 @@ #define MEC1322_EC_INT_CTRL REG32(MEC1322_EC_BASE + 0x18) #define MEC1322_EC_TRACE_EN REG32(MEC1322_EC_BASE + 0x1c) #define MEC1322_EC_JTAG_EN REG32(MEC1322_EC_BASE + 0x20) +#define MEC1322_EC_WDT_CNT REG32(MEC1322_EC_BASE + 0x28) /* Interrupt aggregator */ diff --git a/chip/mec1322/system.c b/chip/mec1322/system.c index aa7b36e459..7364029498 100644 --- a/chip/mec1322/system.c +++ b/chip/mec1322/system.c @@ -22,6 +22,20 @@ enum hibdata_index { HIBDATA_INDEX_SAVED_RESET_FLAGS /* Saved reset flags */ }; +static int check_vcc1_por(void) +{ + /* + * WDT count resets on VCC1 POR. If we see WDT count = 0, we know + * POR has occurred, and we set WDT count to 1. + */ + if (MEC1322_EC_WDT_CNT == 0) { + MEC1322_EC_WDT_CNT = 1; + return 1; + } + + return 0; +} + static void check_reset_cause(void) { uint32_t status = MEC1322_VBAT_STS; @@ -30,15 +44,15 @@ static void check_reset_cause(void) /* Clear the reset causes now that we've read them */ MEC1322_VBAT_STS |= status; - if (status & (1 << 7)) + if (status & (1 << 7) || check_vcc1_por()) flags |= RESET_FLAG_POWER_ON; - if (status & (1 << 5)) - flags |= RESET_FLAG_WATCHDOG; - flags |= MEC1322_VBAT_RAM(HIBDATA_INDEX_SAVED_RESET_FLAGS); MEC1322_VBAT_RAM(HIBDATA_INDEX_SAVED_RESET_FLAGS) = 0; + if (status & (1 << 5) && !(flags & (RESET_FLAG_SOFT | RESET_FLAG_HARD))) + flags |= RESET_FLAG_WATCHDOG; + system_set_reset_flags(flags); } @@ -70,6 +84,11 @@ void system_reset(int flags) if (flags & SYSTEM_RESET_LEAVE_AP_OFF) save_flags |= RESET_FLAG_AP_OFF; + if (flags & SYSTEM_RESET_HARD) + save_flags |= RESET_FLAG_HARD; + else + save_flags |= RESET_FLAG_SOFT; + MEC1322_VBAT_RAM(HIBDATA_INDEX_SAVED_RESET_FLAGS) = save_flags; /* Trigger watchdog in 1ms */ -- cgit v1.2.1