summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2018-11-09 16:13:43 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-12-09 00:48:16 -0800
commit768ce709a6dd85921e60bf871ff0d34824eba990 (patch)
tree80e542e70ab9c08383becbaec67b773de5edcf8e /power
parenta47d02a9411d5ec2e6397eaf9ec0b8a73aebaa29 (diff)
downloadchrome-ec-768ce709a6dd85921e60bf871ff0d34824eba990.tar.gz
cheza: Make chipset_reset do a warm reset
Make the chipset_reset function do a warm reset to match the expectation of what AP-initiated reset does, which is also a warm reset but triggered by PS_HOLD. The warm reset is done by sending a low pulse to the PMIC RESIN_L pin, which requires PMIC registers being reprogrammed that makes it as a warm reset trigger. If the PMIC registers not reprogrammed properly, it falls back to do a cold reset power sequence. It is done by EC monitoring the AP_RST_L signal, which is already one of the power signals. BRANCH=none BUG=b:117941911 TEST=Typed "apreset" just after "reboot" (PMIC registers not programmed), checked the transition S0 -> S5 -> S0. TEST=Typed "apreset" when AP booted into userspace (PMIC registers programmed), checked a warm reset happened, AP_RST_L toggled. Change-Id: Ia1c5c7a8fd56a9e4867d4dd4c8bf2333c083c616 Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/1330117 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Diffstat (limited to 'power')
-rw-r--r--power/sdm845.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/power/sdm845.c b/power/sdm845.c
index 9fb4bcd141..837a54875d 100644
--- a/power/sdm845.c
+++ b/power/sdm845.c
@@ -37,7 +37,9 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Masks for power signals */
-#define IN_POWER_GOOD POWER_SIGNAL_MASK(SDM845_POWER_GOOD)
+#define IN_POWER_GOOD POWER_SIGNAL_MASK(SDM845_POWER_GOOD)
+#define IN_AP_RST_ASSERTED POWER_SIGNAL_MASK(SDM845_AP_RST_ASSERTED)
+
/* Long power key press to force shutdown */
#define DELAY_FORCE_SHUTDOWN (8 * SECOND)
@@ -67,6 +69,9 @@
/* Wait for polling the AP on signal */
#define PMIC_POWER_AP_WAIT (1 * MSEC)
+/* The length of an issued low pulse to the PM845_RESIN_L signal */
+#define PMIC_RESIN_PULSE_LENGTH (20 * MSEC)
+
/* The timeout of the check if the system can boot AP */
#define CAN_BOOT_AP_CHECK_TIMEOUT (500 * MSEC)
@@ -670,14 +675,39 @@ void chipset_force_shutdown(enum chipset_shutdown_reason reason)
void chipset_reset(enum chipset_reset_reason reason)
{
- /*
- * Before we can reprogram the PMIC to make the PMIC RESIN_N pin as
- * reset pin and zero-latency. We do cold reset instead.
- */
+ int rv;
+
CPRINTS("%s(%d)", __func__, reason);
report_ap_reset(reason);
- request_cold_reset();
+ /* The host command is used to hard reset AP. Check b/119261783 */
+ if (reason == CHIPSET_RESET_HOST_CMD) {
+ request_cold_reset();
+ return;
+ }
+
+ /*
+ * Warm reset sequence:
+ * 1. Issue a low pulse to PM845_RESIN_L, which triggers PMIC
+ * to do a warm reset (requiring reprogramming PMIC registers
+ * to make PM845_RESIN_L as a warm reset trigger).
+ * 2. PMIC then issues a low pulse to AP_RST_L to reset AP.
+ * EC monitors the signal to see any low pulse.
+ * 2.1. If a low pulse found, done.
+ * 2.2. If a low pulse not found (the above PMIC registers
+ * not programmed or programmed wrong), issue a request
+ * to initiate a cold reset power sequence.
+ */
+
+ gpio_set_level(GPIO_PM845_RESIN_L, 0);
+ usleep(PMIC_RESIN_PULSE_LENGTH);
+ gpio_set_level(GPIO_PM845_RESIN_L, 1);
+
+ rv = power_wait_signals_timeout(IN_AP_RST_ASSERTED,
+ PMIC_POWER_AP_RESPONSE_TIMEOUT);
+ /* Exception case: PMIC not work as expected, request a cold reset */
+ if (rv != EC_SUCCESS)
+ request_cold_reset();
}
/**