summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic (Chun-Ju) Yang <victoryang@chromium.org>2014-01-10 15:19:41 +0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-01-11 04:46:46 +0000
commitdc82ca44d348665132584a21c89ed824562e9696 (patch)
tree10015092cde7197c462635720c6ae5c9146e58ab
parentd32c19729eae3b8c9c89378e9844808a857f9763 (diff)
downloadchrome-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.h1
-rw-r--r--chip/mec1322/system.c27
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 */