summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2018-10-16 15:50:31 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-10-31 12:42:23 -0700
commit2d9fe8c8912baf237c7eff6964cc68cf8554669c (patch)
tree42fd947e4d5e50c86cc8310c0a511c822ef2667a
parent2a040ce6429b59ea27dd5c3d0ae9e2bf12dc2c90 (diff)
downloadchrome-ec-2d9fe8c8912baf237c7eff6964cc68cf8554669c.tar.gz
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 <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/1285289 Reviewed-by: Stephen Boyd <swboyd@chromium.org>
-rw-r--r--power/sdm845.c36
1 files 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. */
}