summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2020-08-06 15:56:45 -0700
committerCommit Bot <commit-bot@chromium.org>2020-08-08 01:48:32 +0000
commit1a182fd225d9a39c535058d8ce1d48a5ad1c96bc (patch)
treeece4be5f75c0490828881c28f403539553816097
parent67944274aa8b0639e3e23eacd8cf277908874d5f (diff)
downloadchrome-ec-1a182fd225d9a39c535058d8ce1d48a5ad1c96bc.tar.gz
sc7180: Monitor AP_RST_L from PMIC to notify HOOK_CHIPSET_RESET
The HOOK_CHIPSET_RESET should be notified when the AP resets. In x86 platforms, EC monitors the LPC LRESET pin. This LRESET pin is asserted when the chipset resets. However, ARM platforms don't use LPC. We need another way to monitor AP reset. This CL modifies the SC7180 power sequence, to monitor the AP_RST_L signal from PMIC. PMIC uses the AP_RST_L to notify AP reset. A complete warm reset sequence will toggle the AP_RST_L signal 3 times. EC monitors the AP_RST_L signal and wait it transition 3 times to notify the HOOK_CHIPSET_RESET. In case, the AP_RST_L is not toggled 3 times, still notifies the hook but prints a warning message. BRANCH=None BUG=b:163078082 TEST=Checked the HOOK_CHIPSET_RESET is notified after AP warm reset. Change-Id: I4e7b0f0d266e01526deaf54afcdfd2ac1037b8f6 Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2343753 Reviewed-by: Stephen Boyd <swboyd@chromium.org>
-rw-r--r--board/lazor/gpio.inc2
-rw-r--r--board/pompom/gpio.inc2
-rw-r--r--board/trogdor/gpio.inc2
-rw-r--r--include/chipset.h9
-rw-r--r--power/sc7180.c57
5 files changed, 69 insertions, 3 deletions
diff --git a/board/lazor/gpio.inc b/board/lazor/gpio.inc
index 932423f72a..bfe23fdf03 100644
--- a/board/lazor/gpio.inc
+++ b/board/lazor/gpio.inc
@@ -24,7 +24,7 @@ GPIO_INT(EC_VOLDN_BTN_ODL, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_inte
GPIO_INT(EC_VOLUP_BTN_ODL, PIN(F, 2), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) /* Volume Down button */
GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) /* Write protection */
GPIO_INT(LID_OPEN_EC, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) /* Lid open? */
-GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* PMIC to signal AP reset */
+GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, chipset_ap_rst_interrupt) /* PMIC to signal AP reset */
GPIO_INT(PS_HOLD, PIN(A, 4), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, power_signal_interrupt) /* Indicate when AP triggers reset/shutdown */
GPIO_INT(PMIC_FAULT_L, PIN(A, 3), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Any PMIC fault? */
GPIO_INT(AP_SUSPEND, PIN(5, 7), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Suspend signal from PMIC */
diff --git a/board/pompom/gpio.inc b/board/pompom/gpio.inc
index ebe1c023bf..239da6222d 100644
--- a/board/pompom/gpio.inc
+++ b/board/pompom/gpio.inc
@@ -24,7 +24,7 @@ GPIO_INT(EC_VOLDN_BTN_ODL, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_inte
GPIO_INT(EC_VOLUP_BTN_ODL, PIN(F, 2), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) /* Volume Down button */
GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) /* Write protection */
GPIO_INT(LID_OPEN_EC, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) /* Lid open? */
-GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* PMIC to signal AP reset */
+GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, chipset_ap_rst_interrupt) /* PMIC to signal AP reset */
GPIO_INT(PS_HOLD, PIN(A, 4), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, power_signal_interrupt) /* Indicate when AP triggers reset/shutdown */
GPIO_INT(PMIC_FAULT_L, PIN(A, 3), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Any PMIC fault? */
GPIO_INT(AP_SUSPEND, PIN(5, 7), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Suspend signal from PMIC */
diff --git a/board/trogdor/gpio.inc b/board/trogdor/gpio.inc
index ef93c3b25e..e8b560f9a6 100644
--- a/board/trogdor/gpio.inc
+++ b/board/trogdor/gpio.inc
@@ -24,7 +24,7 @@ GPIO_INT(EC_VOLDN_BTN_ODL, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_inte
GPIO_INT(EC_VOLUP_BTN_ODL, PIN(F, 2), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) /* Volume Down button */
GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) /* Write protection */
GPIO_INT(LID_OPEN_EC, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) /* Lid open? */
-GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* PMIC to signal AP reset */
+GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, chipset_ap_rst_interrupt) /* PMIC to signal AP reset */
GPIO_INT(PS_HOLD, PIN(A, 4), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, power_signal_interrupt) /* Indicate when AP triggers reset/shutdown */
GPIO_INT(PMIC_FAULT_L, PIN(A, 3), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Any PMIC fault? */
GPIO_INT(AP_SUSPEND, PIN(5, 7), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) /* Suspend signal from PMIC */
diff --git a/include/chipset.h b/include/chipset.h
index 8664f6ecf3..e2c1421ec6 100644
--- a/include/chipset.h
+++ b/include/chipset.h
@@ -207,6 +207,7 @@ static inline void chipset_handle_espi_reset_assert(void) { }
static inline void chipset_handle_reboot(void) { }
static inline void chipset_reset_request_interrupt(enum gpio_signal signal) { }
static inline void chipset_warm_reset_interrupt(enum gpio_signal signal) { }
+static inline void chipset_ap_rst_interrupt(enum gpio_signal signal) { }
static inline void chipset_power_good_interrupt(enum gpio_signal signal) { }
static inline void chipset_watchdog_interrupt(enum gpio_signal signal) { }
@@ -234,6 +235,14 @@ void chipset_handle_reboot(void);
void chipset_reset_request_interrupt(enum gpio_signal signal);
/**
+ * GPIO interrupt handler of AP_RST_L signal from PMIC.
+ * PMIC uses this signal to notify AP reset.
+ *
+ * It is used in Qualcomm chipset power sequence.
+ */
+void chipset_ap_rst_interrupt(enum gpio_signal signal);
+
+/**
* GPIO interrupt handler of warm reset signal from servo or H1.
*
* It is used in Qualcomm chipset power sequence.
diff --git a/power/sc7180.c b/power/sc7180.c
index fe093ad535..69c64206d4 100644
--- a/power/sc7180.c
+++ b/power/sc7180.c
@@ -100,6 +100,16 @@
*/
#define PMIC_POWER_OFF_DELAY (70 * MSEC)
+/* The AP_RST_L transition count of a normal AP warm reset */
+#define EXPECTED_AP_RST_TRANSITIONS 3
+
+/*
+ * The timeout of waiting the next AP_RST_L transition. We measured
+ * the interval between AP_RST_L transitions is 130ms ~ 150ms. Pick
+ * a safer value.
+ */
+#define AP_RST_TRANSITION_TIMEOUT (450 * MSEC)
+
/* TODO(crosbug.com/p/25047): move to HOOK_POWER_BUTTON_CHANGE */
/* 1 if the power button was pressed last time we checked */
static char power_button_was_pressed;
@@ -155,6 +165,53 @@ enum power_on_event_t {
POWER_ON_EVENT_COUNT,
};
+#ifdef CONFIG_CHIPSET_RESET_HOOK
+static int ap_rst_transitions;
+
+static void notify_chipset_reset(void)
+{
+ if (ap_rst_transitions != EXPECTED_AP_RST_TRANSITIONS)
+ CPRINTS("AP_RST_L transitions not expected: %d",
+ ap_rst_transitions);
+
+ ap_rst_transitions = 0;
+ hook_notify(HOOK_CHIPSET_RESET);
+}
+DECLARE_DEFERRED(notify_chipset_reset);
+#endif
+
+void chipset_ap_rst_interrupt(enum gpio_signal signal)
+{
+#ifdef CONFIG_CHIPSET_RESET_HOOK
+ int delay;
+
+ /*
+ * Only care the raising edge and AP in S0/S3. The single raising edge
+ * of AP power-on during S5S3 is ignored.
+ */
+ if (gpio_get_level(GPIO_AP_RST_L) &&
+ chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_SUSPEND)) {
+ ap_rst_transitions++;
+ if (ap_rst_transitions >= EXPECTED_AP_RST_TRANSITIONS) {
+ /*
+ * Reach the expected transition count. AP is booting
+ * up. Notify HOOK_CHIPSET_RESET immediately.
+ */
+ delay = 0;
+ } else {
+ /*
+ * Should have more transitions of the AP_RST_L signal.
+ * In case the AP_RST_L signal is not toggled, still
+ * notify HOOK_CHIPSET_RESET.
+ */
+ delay = AP_RST_TRANSITION_TIMEOUT;
+ }
+ hook_call_deferred(&notify_chipset_reset_data, delay);
+ }
+#endif
+ power_signal_interrupt(signal);
+}
+
/* Issue a request to initiate a reset sequence */
static void request_cold_reset(void)
{