summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2017-07-17 16:23:47 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-07-27 19:56:22 -0700
commit3be8c42996dc69a497025a9a3404cc58154cc234 (patch)
tree3cdedcac3bbf020ef8e6b02e55097cd6fb8a7bc9 /board
parente03e58c745716241df056750b765d1c7d5985b62 (diff)
downloadchrome-ec-3be8c42996dc69a497025a9a3404cc58154cc234.tar.gz
cr50: Preserve CCD state across deep sleep
Define two bits in a long-life register to hold the current CCD state across deep sleep. Update the bits on CCD config change, and restore them on init. This is necessary because Cr50 loses RAM contents on deep sleep. It would be really inconvenient to open CCD, get a cup of coffee, and come back to find CCD has locked again because Cr50 was idle too long. See go/cr50-ccd-wp for more information. BUG=b:62537474 BRANCH=cr50 TEST=manual with CR50_DEV=1 build ccdinfo --> state=opened idle d ccdunlock ccdinfo --> state=unlocked (wait for deep sleep) sysinfo --> reset flags = hibernate wake-pin ccdinfo --> state=unlocked reboot sysinfo --> reset flags = hard ccdinfo --> state=opened Change-Id: I7864f374af5c159bc9691b094958fb030f3cb8ad Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/575996 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Diffstat (limited to 'board')
-rw-r--r--board/cr50/board.c33
-rw-r--r--board/cr50/scratch_reg1.h9
2 files changed, 41 insertions, 1 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index f3e3f59dcf..76b14b1f30 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -618,6 +618,12 @@ static void check_board_id_mismatch(void)
/* Initialize board. */
static void board_init(void)
{
+#ifdef CR50_DEV
+ static enum ccd_state ccd_init_state = CCD_STATE_OPENED;
+#else
+ static enum ccd_state ccd_init_state = CCD_STATE_LOCKED;
+#endif
+
/*
* Deep sleep resets should be considered valid and should not impact
* the rolling reboot count.
@@ -634,8 +640,19 @@ static void board_init(void)
nvmem_init();
/* Initialize the persistent storage. */
initvars();
+
+ /*
+ * If this was a low power wake and not a rollback, restore the ccd
+ * state from the long-life register.
+ */
+ if ((system_get_reset_flags() & RESET_FLAG_HIBERNATE) &&
+ !system_rollback_detected()) {
+ ccd_init_state = (GREG32(PMU, LONG_LIFE_SCRATCH1) &
+ BOARD_CCD_STATE) >> BOARD_CCD_SHIFT;
+ }
+
/* Load case-closed debugging config */
- ccd_config_init();
+ ccd_config_init(ccd_init_state);
system_update_rollback_mask_with_both_imgs();
@@ -661,6 +678,20 @@ static void board_init(void)
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+/**
+ * Hook for CCD config loaded/changed.
+ */
+static void board_ccd_config_changed(void)
+{
+ /* Store the current CCD state so we can restore it after deep sleep */
+ GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG1, 1);
+ GREG32(PMU, LONG_LIFE_SCRATCH1) &= ~BOARD_CCD_STATE;
+ GREG32(PMU, LONG_LIFE_SCRATCH1) |= (ccd_get_state() << BOARD_CCD_SHIFT)
+ & BOARD_CCD_STATE;
+ GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG1, 0);
+}
+DECLARE_HOOK(HOOK_CCD_CHANGE, board_ccd_config_changed, HOOK_PRIO_DEFAULT);
+
#if defined(CONFIG_USB)
const void * const usb_strings[] = {
[USB_STR_DESC] = usb_string_desc,
diff --git a/board/cr50/scratch_reg1.h b/board/cr50/scratch_reg1.h
index 546cd43d62..23b03db546 100644
--- a/board/cr50/scratch_reg1.h
+++ b/board/cr50/scratch_reg1.h
@@ -38,6 +38,15 @@
#define BOARD_NO_RO_UART (1 << 10)
/*
+ * Bits to store current case-closed debug state across deep sleep.
+ *
+ * DO NOT examine these bits to determine the current CCD state. Call methods
+ * from case_closed_debug.h instead.
+ */
+#define BOARD_CCD_SHIFT 11
+#define BOARD_CCD_STATE (3 << BOARD_CCD_SHIFT)
+
+/*
* Macro to capture all properties related to board strapping pins. This must be
* updated if additional strap related properties are added.
*/