summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/ap_state.c43
-rw-r--r--board/cr50/board.c8
-rw-r--r--chip/g/rbox.c12
3 files changed, 53 insertions, 10 deletions
diff --git a/board/cr50/ap_state.c b/board/cr50/ap_state.c
index f40360fa0c..fc75f4a86e 100644
--- a/board/cr50/ap_state.c
+++ b/board/cr50/ap_state.c
@@ -159,18 +159,41 @@ static void init_ap_detect(void)
gpio_enable_interrupt(GPIO_TPM_RST_L);
gpio_enable_interrupt(GPIO_DETECT_TPM_RST_L_ASSERTED);
/*
- * Enable TPM reset GPIO interrupt.
+ * After resuming from any reset other than deep sleep, cr50 needs to
+ * make sure the rest of the system has reset. If cr50 needs a closed
+ * loop reset to reset the system, it can't rely on the short EC_RST
+ * pulse from RO. Use the closed loop reset to ensure the system has
+ * actually been reset.
*
- * If the TPM_RST_L signal is already high when cr50 wakes up or
- * transitions to high before we are able to configure the gpio then we
- * will have missed the edge and the tpm reset isr will not get
- * called. Check that we haven't already missed the rising edge. If we
- * have alert tpm_rst_isr.
+ * During this reset, the ap state will not be set to 'on' until the AP
+ * enters and then leaves reset. The tpm waits until the ap is on before
+ * allowing any tpm activity, so it wont do anything until the reset is
+ * complete.
*/
- if (gpio_get_level(GPIO_TPM_RST_L))
- tpm_rst_deasserted(GPIO_TPM_RST_L);
- else
- tpm_rst_asserted(GPIO_TPM_RST_L);
+ if (board_uses_closed_loop_reset() &&
+ !(system_get_reset_flags() & RESET_FLAG_HIBERNATE)) {
+ board_closed_loop_reset();
+ } else {
+ /*
+ * If the TPM_RST_L signal is already high when cr50 wakes up or
+ * transitions to high before we are able to configure the gpio
+ * then we will have missed the edge and the tpm reset isr will
+ * not get called. Check that we haven't already missed the
+ * rising edge. If we have alert tpm_rst_isr.
+ *
+ * DONT alert tpm_rst_isr if the board is waiting for the closed
+ * loop reset to finish. The isr is edge triggered, so
+ * tpm_rst_deasserted wont be called until the AP enters and
+ * exits reset. That is what we want. The TPM and other
+ * peripherals check ap_is_on before enabling interactions with
+ * the AP, and we want these to be disabled until the closed
+ * loop reset is complete.
+ */
+ if (gpio_get_level(GPIO_TPM_RST_L))
+ tpm_rst_deasserted(GPIO_TPM_RST_L);
+ else
+ tpm_rst_asserted(GPIO_TPM_RST_L);
+ }
}
/*
* TPM_RST_L isn't setup until board_init. Make sure init_ap_detect happens
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 7603453d92..da2e4ad529 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -968,6 +968,10 @@ int is_sys_rst_asserted(void)
*/
void board_reboot_ap(void)
{
+ if (board_uses_closed_loop_reset()) {
+ board_closed_loop_reset();
+ return;
+ }
assert_sys_rst();
msleep(20);
deassert_sys_rst();
@@ -978,6 +982,10 @@ void board_reboot_ap(void)
*/
static void board_reboot_ec(void)
{
+ if (board_uses_closed_loop_reset()) {
+ board_closed_loop_reset();
+ return;
+ }
assert_ec_rst();
deassert_ec_rst();
}
diff --git a/chip/g/rbox.c b/chip/g/rbox.c
index 005ed547c1..6399f0b612 100644
--- a/chip/g/rbox.c
+++ b/chip/g/rbox.c
@@ -62,6 +62,18 @@ static void rbox_release_ec_reset(void)
GREG32(PINMUX, HOLD) = 0;
/*
+ * If the board uses closed loop reset, the short EC_RST_L pulse may
+ * not actually put the system in reset. Don't release EC_RST_L here.
+ * Let ap_state.c handle it once it sees the system is reset.
+ *
+ * Release PINMUX HOLD, so the board can detect changes on TPM_RST_L.
+ */
+ if (!(system_get_reset_flags() & RESET_FLAG_HIBERNATE) &&
+ board_uses_closed_loop_reset()) {
+ return;
+ }
+
+ /*
* After a POR, if the power button is held, then delay releasing
* EC_RST_L.
*/