summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Sanders <nsanders@chromium.org>2018-08-27 11:42:26 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-08-29 16:09:31 -0700
commitc0ef4ac5ed138cca25ae1ff54dff58fafa344ded (patch)
tree7276be857c52bbb201eba22c930f70605767cf30
parent475f67828ff64d5398616a3998f70178b96e2864 (diff)
downloadchrome-ec-c0ef4ac5ed138cca25ae1ff54dff58fafa344ded.tar.gz
cr50: Release EC Reset on power button release when SuzyQ detected.
It complements crrev.com/c/1137434 in the way EC Reset got released. Instead of time-basis, it shall be released when the power button is released. The desired sequence of actions is: 0. (optional) Have a CR50 console and EC console connected to terminals. 1. Do a shutdown. 2. Press the power button and keep it pressed. 3. Plug a SuzyQ cable. 4. CR50 console shall be connected back, but not EC console. 5. Release the power button at any proper time, so that EC can restart. To keep EC from resetting, do "ecrst true" in CR50 console right after Step 4. It will invalidate Step 5. BRANCH=cr50 BUG=b:37351386 TEST=manually on Duts, Bob (Chrombook) and Sion (chromebox). (A) hard-reset A-1. Binary Download + Hold power button => no delay in EC reset. (B) Wake from hibernation B-1. (EC console) hibernate B-2. unplug all cables B-3. hold "POWER BUTTON" + plug SuzyQ cable => no delay in EC reset. (C) Power-on reset C-1. "REFRESH" + "POWER BUTTON" + unplug power cable. C-2. unplug SuzyQ cable C-3. plug SuzyQ cable => no delay in EC reset. (D) Power-on reset D-1. "REFRESH" + "POWER BUTTON" + unplug power cable. D-2. unplug SuzyQ cable D-3. hold "POWER BUTTON" + plug SuzyQ cable. => EC reset gets held. D-4. release "POWER BUTTON" ==> EC gets reset. (E) Power-on reset + explicit "ec_rst true" E-1. "REFRESH" + "POWER BUTTON" + unplug power cable. E-2. unplug SuzyQ cable E-3. hold "POWER BUTTON" + plug SuzyQ cable. => EC reset gets held. E-4. (CR50 console) ecrst true E-5. release "POWER BUTTON" ==> EC reset still gets held. (F) Power-on reset + explicit "ec_rst false" F-1. "REFRESH" + "POWER BUTTON" + unplug power cable. F-2. unplug SuzyQ cable F-3. hold "POWER BUTTON" + plug SuzyQ cable. => EC reset gets held. F-4. (CR50 console) ecrst false => EC gets reset. F-5. release "POWER BUTTON" ==> Nothing happens. (common) Press "POWER BUTTON" again, and check CR50 doesn't have any more "POWER BUTTON" release events. Changes to be committed: modified: board/cr50/board.c modified: board/cr50/board.h modified: board/cr50/power_button.c modified: chip/g/rbox.c Change-Id: Ic39c9ce7849fa3187e1d277320adf671f857d18d Signed-off-by: Namyoon Woo <namyoon@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1192691 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--board/cr50/board.c12
-rw-r--r--board/cr50/board.h7
-rw-r--r--board/cr50/power_button.c35
-rw-r--r--chip/g/rbox.c9
4 files changed, 58 insertions, 5 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 30e8fc8791..f9b36d8eed 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -943,10 +943,22 @@ void assert_ec_rst(void)
if (uart_bitbang_is_enabled())
task_disable_irq(bitbang_config.rx_irq);
+ /*
+ * If ec_rst was explicitly asserted, then do not let
+ * "power button release" deassert it if set earlier to do so.
+ */
+ power_button_release_enable_interrupt(0);
+
GWRITE(RBOX, ASSERT_EC_RST, 1);
}
void deassert_ec_rst(void)
{
+ /*
+ * If ec_rst was explicitly deasserted, then do not let
+ * "power button release" deassert it again if set earlier to do so.
+ */
+ power_button_release_enable_interrupt(0);
+
GWRITE(RBOX, ASSERT_EC_RST, 0);
if (uart_bitbang_is_enabled())
diff --git a/board/cr50/board.h b/board/cr50/board.h
index 140f230d02..9e8da8acb1 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -269,6 +269,13 @@ int board_deep_sleep_allowed(void);
void power_button_record(void);
+/**
+ * Enable/disable power button release interrupt.
+ *
+ * @param enable Enable (!=0) or disable (==0)
+ */
+void power_button_release_enable_interrupt(int enable);
+
/* Functions needed by CCD config */
int board_battery_is_present(void);
int board_fwmp_allows_unlock(void);
diff --git a/board/cr50/power_button.c b/board/cr50/power_button.c
index 96b3bb7774..efa402259a 100644
--- a/board/cr50/power_button.c
+++ b/board/cr50/power_button.c
@@ -17,6 +17,23 @@
#define CPRINTS(format, args...) cprints(CC_RBOX, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_RBOX, format, ## args)
+DECLARE_DEFERRED(deassert_ec_rst);
+
+void power_button_release_enable_interrupt(int enable)
+{
+ /* Clear any leftover power button rising edge detection interrupts */
+ GWRITE_FIELD(RBOX, INT_STATE, INTR_PWRB_IN_RED, 1);
+
+ if (enable) {
+ /* Enable power button rising edge detection interrupt */
+ GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_RED, 1);
+ task_enable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_RED_INT);
+ } else {
+ GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_RED, 0);
+ task_disable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_RED_INT);
+ }
+}
+
/**
* Enable/disable power button interrupt.
*
@@ -53,6 +70,24 @@ static void power_button_handler(void)
}
DECLARE_IRQ(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT, power_button_handler, 1);
+static void power_button_release_handler(void)
+{
+#ifdef CR50_DEV
+ CPRINTS("power button released");
+#endif
+
+ /*
+ * Let deassert_ec_rst be called deferred rather than
+ * by interrupt handler.
+ */
+ hook_call_deferred(&deassert_ec_rst_data, 0);
+
+ /* Note that this is for one-time use through the current power on. */
+ power_button_release_enable_interrupt(0);
+}
+DECLARE_IRQ(GC_IRQNUM_RBOX0_INTR_PWRB_IN_RED_INT, power_button_release_handler,
+ 1);
+
#ifdef CONFIG_U2F
static void power_button_init(void)
{
diff --git a/chip/g/rbox.c b/chip/g/rbox.c
index 513e6ebb58..00fac521b6 100644
--- a/chip/g/rbox.c
+++ b/chip/g/rbox.c
@@ -10,8 +10,6 @@
#include "system.h"
#include "timer.h"
-#define DELAY_EC_BOOT_USEC (2 * SECOND)
-DECLARE_DEFERRED(deassert_ec_rst);
void rbox_clear_wakeup(void)
{
@@ -39,12 +37,13 @@ static void rbox_release_ec_reset(void)
/* Unfreeze the PINMUX */
GREG32(PINMUX, HOLD) = 0;
- /* After a POR, if it finds RDD cable plugged and Power button pressed,
- * then it delays booting EC by DELAY_EC_BOOT_USEC.
+ /*
+ * After a POR, if it finds RDD cable plugged and Power button pressed,
+ * then it delays releasing EC-reset until power button gets released.
*/
if ((system_get_reset_flags() & RESET_FLAG_POWER_ON) &&
rdd_is_detected() && rbox_powerbtn_is_pressed()) {
- hook_call_deferred(&deassert_ec_rst_data, DELAY_EC_BOOT_USEC);
+ power_button_release_enable_interrupt(1);
return;
}