summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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();
}
/**