diff options
author | Vic (Chun-Ju) Yang <victoryang@chromium.org> | 2014-01-10 15:19:41 +0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-01-11 04:46:46 +0000 |
commit | dc82ca44d348665132584a21c89ed824562e9696 (patch) | |
tree | 10015092cde7197c462635720c6ae5c9146e58ab | |
parent | d32c19729eae3b8c9c89378e9844808a857f9763 (diff) | |
download | chrome-ec-dc82ca44d348665132584a21c89ed824562e9696.tar.gz |
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 <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/182120
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | chip/mec1322/registers.h | 1 | ||||
-rw-r--r-- | 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 */ |