summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@google.com>2018-08-17 17:57:03 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-08-23 13:20:46 -0700
commit18307f177db0c517e4734d61e3fd1655ea72b512 (patch)
tree4c710765a1667a0dcd49940b81d895525a3a171c
parentf4c3719fd8769c360d17846a554541adcaef5659 (diff)
downloadchrome-ec-18307f177db0c517e4734d61e3fd1655ea72b512.tar.gz
cr50: only enable rbox wakeup during sleep
Enable rbox wakeups before entering any form of sleep. Disable them immediately on resume. Without rbox wakeups enabled during normal operation, we don't need to worry about clearing them after every rbox interrupt. In TOT we missed clearing the power button rbox wakeup. This was causing cr50 to wake up immediately after entering regular sleep. It caused a ton of pmu interrupts and prevented cr50 from staying asleep. With this change cr50 enters enters sleep and deep sleep normally. It only resumes when there's a real wakeup. BUG=none BRANCH=cr50 TEST=verify power button can still wake cr50 from sleep and deep sleep. Run firmware_Cr50DeviceState with TOT Change-Id: I56bf81c19a6e32750dc9d21be7f27188635dd662 Signed-off-by: Mary Ruthven <mruthven@google.com> Reviewed-on: https://chromium-review.googlesource.com/1180572 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Tested-by: Mary Ruthven <mruthven@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--board/cr50/board.c22
-rw-r--r--board/cr50/board.h1
-rw-r--r--chip/g/idle.c8
-rw-r--r--chip/g/rbox.c22
-rw-r--r--chip/g/rbox.h5
-rw-r--r--include/config.h3
6 files changed, 44 insertions, 17 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 8958309fea..30e8fc8791 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -20,6 +20,7 @@
#include "init_chip.h"
#include "nvmem.h"
#include "nvmem_vars.h"
+#include "rbox.h"
#include "rdd.h"
#include "registers.h"
#include "scratch_reg1.h"
@@ -315,25 +316,10 @@ enum {
static void ac_power_state_changed(void)
{
uint32_t req;
- int i = 0;
-
/* Get current status and clear it. */
req = GREG32(RBOX, INT_STATE) & (ac_pres_red | ac_pres_fed);
GREG32(RBOX, INT_STATE) = req;
- /* Clear the wakeup interrupt */
- GREG32(RBOX, WAKEUP) = GC_RBOX_WAKEUP_CLEAR_MASK;
- /*
- * Wait until the interrupt status register is cleared, since RBOX runs
- * off of RTC instead of the core clock. Wait a max of 50 iterations.
- * Experimentally, 15 iterations is usually sufficient. We don't want to
- * wait here forever.
- */
- while (GREAD(RBOX, WAKEUP_INTR) && i < 50)
- i++;
- /* Reenable rbox wakeup */
- GREG32(RBOX, WAKEUP) = GC_RBOX_WAKEUP_ENABLE_MASK;
-
CPRINTS("AC: %c%c",
req & ac_pres_red ? 'R' : '-',
req & ac_pres_fed ? 'F' : '-');
@@ -461,6 +447,12 @@ void pmu_wakeup_interrupt(void)
ccprintf(" %2x ", wakeup_src);
}
+ if (wakeup_src & GC_PMU_EXITPD_SRC_RBOX_WAKEUP_MASK)
+ rbox_clear_wakeup();
+
+ /* Disable rbox wakeup. It will be reenabled before entering sleep. */
+ GREG32(RBOX, WAKEUP) = 0;
+
if (wakeup_src & GC_PMU_EXITPD_SRC_PIN_PD_EXIT_MASK) {
reset_wake_logic();
diff --git a/board/cr50/board.h b/board/cr50/board.h
index 0d224ec38b..a523da7151 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -126,6 +126,7 @@
#define CONFIG_TPM_SPS
#define CONFIG_RBOX
+#define CONFIG_RBOX_WAKEUP
/* We don't need to send events to the AP */
#undef CONFIG_HOSTCMD_EVENTS
diff --git a/chip/g/idle.c b/chip/g/idle.c
index e0f82cb0ef..e46351d2f5 100644
--- a/chip/g/idle.c
+++ b/chip/g/idle.c
@@ -97,6 +97,14 @@ static void prepare_to_sleep(void)
GC_PMU_EXITPD_MASK_TIMELS0_PD_EXIT_TIMER0_MASK |
GC_PMU_EXITPD_MASK_TIMELS0_PD_EXIT_TIMER1_MASK;
+#ifdef CONFIG_RBOX_WAKEUP
+ /*
+ * Enable RBOX wakeup. It will immediately be disabled on resume in
+ * rbox_init or pmu_wakeup_interrupt.
+ */
+ GREG32(RBOX, WAKEUP) = GC_RBOX_WAKEUP_ENABLE_MASK;
+#endif
+
if (utmi_wakeup_is_enabled() && idle_action != IDLE_DEEP_SLEEP)
GR_PMU_EXITPD_MASK |=
GC_PMU_EXITPD_MASK_UTMI_SUSPEND_N_MASK;
diff --git a/chip/g/rbox.c b/chip/g/rbox.c
index a202c9a1c6..513e6ebb58 100644
--- a/chip/g/rbox.c
+++ b/chip/g/rbox.c
@@ -13,6 +13,22 @@
#define DELAY_EC_BOOT_USEC (2 * SECOND)
DECLARE_DEFERRED(deassert_ec_rst);
+void rbox_clear_wakeup(void)
+{
+ int i = 0;
+
+ /* Clear the wakeup interrupt */
+ GREG32(RBOX, WAKEUP) = GC_RBOX_WAKEUP_CLEAR_MASK;
+ /*
+ * Wait until the interrupt status register is cleared, since RBOX runs
+ * off of RTC instead of the core clock. Wait a max of 50 iterations.
+ * Experimentally, 15 iterations is usually sufficient. We don't want to
+ * wait here forever.
+ */
+ while (GREAD(RBOX, WAKEUP_INTR) && i < 50)
+ i++;
+}
+
int rbox_powerbtn_is_pressed(void)
{
return !GREAD_FIELD(RBOX, CHECK_OUTPUT, PWRB_OUT);
@@ -48,8 +64,10 @@ static void rbox_init(void)
/* Clear any interrupt bits (write 1's to clear) */
GREG32(RBOX, INT_STATE) = 0xffffffff;
- /* Clear any wakeup bits (write 0x2, then 0x0) */
- GREG32(RBOX, WAKEUP) = GC_RBOX_WAKEUP_CLEAR_MASK;
+ /* Clear any wakeup bits */
+ rbox_clear_wakeup();
+
+ /* Disable rbox wakeup. It will be reenabled before entering sleep. */
GREG32(RBOX, WAKEUP) = 0;
/* Override rbox fuses and setup correct behavior */
diff --git a/chip/g/rbox.h b/chip/g/rbox.h
index 5d08118c54..5ceeb81953 100644
--- a/chip/g/rbox.h
+++ b/chip/g/rbox.h
@@ -10,4 +10,9 @@
* Return true if the power button output shows it is pressed
*/
int rbox_powerbtn_is_pressed(void);
+
+/**
+ * Clear the wakeup interrupts
+ */
+void rbox_clear_wakeup(void);
#endif /* __CROS_RBOX_H */
diff --git a/include/config.h b/include/config.h
index a16b37b43e..f3ab3b81cf 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2491,6 +2491,9 @@
/* Enable rbox peripheral */
#undef CONFIG_RBOX
+/* Enable rbox wakeup */
+#undef CONFIG_RBOX_WAKEUP
+
/* Enable RDD peripheral */
#undef CONFIG_RDD