summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@google.com>2019-01-29 16:08:02 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-03-06 06:51:02 -0800
commit36469aa61c23e0e0180541db54f29a292e3d9845 (patch)
tree2c991489d44ec62b4e912319dcdb878be8ec2911
parentb559bd558a357afd29ba4898d22374b3b2050f02 (diff)
downloadchrome-ec-36469aa61c23e0e0180541db54f29a292e3d9845.tar.gz
cr50: use closed loop reset based on board property
Use the closed loop reset when cr50 needs to reset the device. Cr50 expects the board to reset in three places: board_reboot_ap, board_reboot_ec, or during init after any cr50 reset other than deep sleep. This change modifies these to use the closed loop reset if the board property is set. In board_reboot_ap and board_reboot_ec it calls board_closed_loop_reset instead of doing the normal reset steps if the board property is set. In init_ap_detect call board_closed_loop_reset if cr50 just resumed from any reset other than hibernate. Don't trigger the tpm_rst_isr manually. BUG=b:123544145 BRANCH=cr50 TEST=manual Flash firmware that supports resetting the AP when EC_RST_L is asserted. Reboot cr50 and verify deferred_tpm_rst_isr is only called after tpm_rst_asserted. Open Cr50. Verify the AP is reset Flash old Mistral firmware which seems to take around 12 seconds for the warm reset to happen. Boot the AP. Reboot cr50 while the AP is up. The AP wont reset for a while. While the AP is still up, verify Cr50 keeps EC_RST_L asserted, the AP state is Unknown, and tpm commands fail while the AP is in this state. Eventually the AP resets. Make sure the TPM becomes usable again and the AP state is on. Change-Id: I6f0e8728717f1ed35c96b2669f1796078ebf93f7 Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1447001 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-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.
*/