summaryrefslogtreecommitdiff
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
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>
-rw-r--r--board/cheza/board.c6
-rw-r--r--board/cheza/board.h2
-rw-r--r--power/sdm845.c42
3 files changed, 40 insertions, 10 deletions
diff --git a/board/cheza/board.c b/board/cheza/board.c
index 715e8fa768..8570349f77 100644
--- a/board/cheza/board.c
+++ b/board/cheza/board.c
@@ -188,10 +188,10 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
/* Power signal list. Must match order of enum power_signal. */
const struct power_signal_info power_signal_list[] = {
- [SDM845_AP_RST_L] = {
+ [SDM845_AP_RST_ASSERTED] = {
GPIO_AP_RST_L,
- POWER_SIGNAL_ACTIVE_HIGH | POWER_SIGNAL_DISABLE_AT_BOOT,
- "AP_RST_L"},
+ POWER_SIGNAL_ACTIVE_LOW | POWER_SIGNAL_DISABLE_AT_BOOT,
+ "AP_RST_ASSERTED"},
[SDM845_PS_HOLD] = {
GPIO_PS_HOLD,
POWER_SIGNAL_ACTIVE_HIGH,
diff --git a/board/cheza/board.h b/board/cheza/board.h
index dfdb6e92f4..a243de34f3 100644
--- a/board/cheza/board.h
+++ b/board/cheza/board.h
@@ -169,7 +169,7 @@
#include "registers.h"
enum power_signal {
- SDM845_AP_RST_L = 0,
+ SDM845_AP_RST_ASSERTED = 0,
SDM845_PS_HOLD,
SDM845_PMIC_FAULT_L,
SDM845_POWER_GOOD,
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();
}
/**