diff options
-rw-r--r-- | board/cr50/ap_state.c | 43 | ||||
-rw-r--r-- | board/cr50/board.c | 8 | ||||
-rw-r--r-- | chip/g/rbox.c | 12 |
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. */ |