From 2d9fe8c8912baf237c7eff6964cc68cf8554669c Mon Sep 17 00:00:00 2001 From: Wai-Hong Tam Date: Tue, 16 Oct 2018 15:50:31 -0700 Subject: cheza: Do S0->S5->S0 transition after warm_reset-toggling finished The warm_reset is used for programming the AP SPI flash. This signal is async that the SPMI transaction between PMIC and AP may get wedged. So after the warm_reset-toggling is finished, should cold- reset PMIC and AP to get a clean state. BRANCH=None BUG=b:112723105, b:112564635 TEST=Toggled the warm_reset on different cases, e.g. S5, S0, coreboot, userspace, etc., and checked the AP reboot as expected, expected S5. Change-Id: I8d5e8690f5a6387d43f79718a8e68b2c810f4d26 Signed-off-by: Wai-Hong Tam Reviewed-on: https://chromium-review.googlesource.com/1285289 Reviewed-by: Stephen Boyd --- power/sdm845.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/power/sdm845.c b/power/sdm845.c index 36e041f96d..dbca0c06a7 100644 --- a/power/sdm845.c +++ b/power/sdm845.c @@ -156,6 +156,26 @@ void chipset_reset_request_interrupt(enum gpio_signal signal) hook_call_deferred(&chipset_reset_request_handler_data, 0); } +/* Cold reset AP after warm_reset-toggling finished */ +static void chipset_warm_reset_finished(void) +{ + CPRINTS("warm_reset-toggling finished -> cold reset AP"); + chipset_reset(CHIPSET_RESET_AP_REQ); + + if (ap_rst_overdriven) { + /* + * This condition should not be reached as the above + * chipset_reset() makes POWER_GOOD drop that triggers an + * interrupt to high-Z both AP_RST_L and PS_HOLD. + */ + CPRINTS("Fatal: AP_RST_L and PS_HOLD not released. Force it!"); + gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH | GPIO_SEL_1P8V); + gpio_set_flags(GPIO_PS_HOLD, GPIO_INT_BOTH | GPIO_SEL_1P8V); + ap_rst_overdriven = 0; + } +} +DECLARE_DEFERRED(chipset_warm_reset_finished); + void chipset_warm_reset_interrupt(enum gpio_signal signal) { /* @@ -196,17 +216,13 @@ void chipset_warm_reset_interrupt(enum gpio_signal signal) /* * Servo or Cr50 releases the WARM_RESET_L signal. * - * High-Z both AP_RST_L and PS_HOLD to restore their - * state. Cold reset the PMIC, doing S0->S5->S0 - * transition, to recover the system. + * Cold reset the PMIC, doing S0->S5->S0 transition, + * to recover the system. The transition to S5 makes + * POWER_GOOD drop that triggers an interrupt to + * high-Z both AP_RST_L and PS_HOLD. */ - gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH | - GPIO_SEL_1P8V); - gpio_set_flags(GPIO_PS_HOLD, GPIO_INT_BOTH | - GPIO_SEL_1P8V); - ap_rst_overdriven = 0; - - /* TODO(b/112723105): Do S0->S5->S0 transition here. */ + hook_call_deferred(&chipset_warm_reset_finished_data, + 0); } /* If not overdriven, just a normal power-up, do nothing. */ } -- cgit v1.2.1