summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2018-04-21 11:06:51 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-08 13:17:13 -0700
commit71e966af61f3e4b23e658f42552938c9d6941228 (patch)
treea274871e29466717adee085ba9b02973f88f7333
parent139b84f5b0ed20bc14ce76cb5e2e16a11165b3bd (diff)
downloadchrome-ec-71e966af61f3e4b23e658f42552938c9d6941228.tar.gz
cheza: Enable AP_RST_REQ as a request from AP to reset itself
This makes the EC listen to the AP_RST_REQ GPIO from AP. The rising edge interrupts to trigger a hook to call chipset_reset(). As the hook task will be preempted by the chipset task, it adds a flag bypass_power_lost_trigger to avoid triggering to S5 as the chipset state machines sees power lost during the reset. So far the chipset_reset() implementation is to do a cold reset; will be revised to a warm reset after the PMIC registers are reprogrammed. BRANCH=none BUG=b:74395451 TEST=make buildall -j TEST=Ran 'reboot' on AP console which toggles the GPIO. Change-Id: I946cb029541ce018a8ed1ce25681d38998a7f4b6 Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/1023986 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/cheza/board.c1
-rw-r--r--board/cheza/gpio.inc2
-rw-r--r--include/chipset.h8
-rw-r--r--power/sdm845.c28
4 files changed, 37 insertions, 2 deletions
diff --git a/board/cheza/board.c b/board/cheza/board.c
index c22c7c6d3e..e7862b9064 100644
--- a/board/cheza/board.c
+++ b/board/cheza/board.c
@@ -7,6 +7,7 @@
#include "adc_chip.h"
#include "button.h"
+#include "chipset.h"
#include "extpower.h"
#include "gpio.h"
#include "hooks.h"
diff --git a/board/cheza/gpio.inc b/board/cheza/gpio.inc
index 8c89555bbc..85ea7a4a5f 100644
--- a/board/cheza/gpio.inc
+++ b/board/cheza/gpio.inc
@@ -13,6 +13,7 @@ GPIO_INT(VOLUME_DOWN_L, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_inte
GPIO_INT(VOLUME_UP_L, PIN(1, 1), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) /* EC_VOLUP_BTN_ODL */
GPIO_INT(WP_L, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) /* EC_WP_ODL */
GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH, lid_interrupt) /* LID_OPEN_EC */
+GPIO_INT(AP_RST_REQ, PIN(C, 2), GPIO_INT_RISING | GPIO_PULL_DOWN, chipset_reset_request_interrupt) /* Reset request from AP */
/* AP_RST_L is used for PMIC and AP negotiation. Don't change its state. */
GPIO_INT(AP_RST_L, PIN(C, 1), GPIO_INT_BOTH, power_signal_interrupt)
@@ -30,7 +31,6 @@ GPIO(CCD_MODE_ODL, PIN(E, 3), GPIO_INPUT) /* Case Closed Debug Mode
GPIO(BATT_PRES_ODL, PIN(E, 5), GPIO_INPUT | GPIO_PULL_UP) /* EC_BATT_PRES_ODL: Battery Present */
GPIO(PMIC_FAULT_L, PIN(7, 6), GPIO_INPUT) /* Any PMIC fault? */
GPIO(PMIC_KPD_PWR_ODL, PIN(D, 6), GPIO_OUT_HIGH) /* TP10, rework jumps to PMIC power button */
-GPIO(AP_RST_REQ, PIN(C, 2), GPIO_INPUT) /* Reset request from AP */
GPIO(AP_EC_INT_L, PIN(A, 2), GPIO_INPUT) /* Interrupt line between AP and EC */
/* Power enables */
diff --git a/include/chipset.h b/include/chipset.h
index ba78c45397..85d33425f8 100644
--- a/include/chipset.h
+++ b/include/chipset.h
@@ -121,4 +121,12 @@ int chipset_pltrst_is_valid(void) __attribute__((weak));
* Execute chipset-specific reboot.
*/
void chipset_handle_reboot(void);
+
+/**
+ * GPIO interrupt handler of reset request from AP.
+ *
+ * It is used in SDM845 chipset power sequence.
+ */
+void chipset_reset_request_interrupt(enum gpio_signal signal);
+
#endif /* __CROS_EC_CHIPSET_H */
diff --git a/power/sdm845.c b/power/sdm845.c
index fb3eb40efc..ded32ee64b 100644
--- a/power/sdm845.c
+++ b/power/sdm845.c
@@ -73,6 +73,14 @@ static char power_button_was_pressed;
/* 1 if lid-open event has been detected */
static char lid_opened;
+/*
+ * 1 if power state is controlled by special functions, like a console command
+ * or an interrupt handler, for bypassing POWER_GOOD lost trigger. It is
+ * because these functions control the PMIC and AP power signals directly and
+ * don't want to get preempted by the chipset state machine.
+ */
+static uint8_t bypass_power_lost_trigger;
+
/* Time where we will power off, if power button still held down */
static timestamp_t power_off_deadline;
@@ -116,6 +124,19 @@ enum power_on_event_t {
POWER_ON_EVENT_COUNT,
};
+/* AP-requested reset GPIO interrupt handlers */
+static void chipset_reset_request_handler(void)
+{
+ CPRINTS("AP wants reset");
+ chipset_reset();
+}
+DECLARE_DEFERRED(chipset_reset_request_handler);
+
+void chipset_reset_request_interrupt(enum gpio_signal signal)
+{
+ hook_call_deferred(&chipset_reset_request_handler_data, 0);
+}
+
static void sdm845_lid_event(void)
{
/* Power task only cares about lid-open events */
@@ -257,6 +278,9 @@ enum power_state power_chipset_init(void)
int init_power_state;
uint32_t reset_flags = system_get_reset_flags();
+ /* Enable reboot control input from AP */
+ gpio_enable_interrupt(GPIO_AP_RST_REQ);
+
/*
* Force the AP shutdown unless we are doing SYSJUMP. Otherwise,
* the AP could stay in strange state.
@@ -444,7 +468,7 @@ static int check_for_power_off_event(void)
power_button_was_pressed = pressed;
/* POWER_GOOD released by AP : shutdown immediately */
- if (!power_has_signals(IN_POWER_GOOD)) {
+ if (!power_has_signals(IN_POWER_GOOD) && !bypass_power_lost_trigger) {
if (power_button_was_pressed)
timer_cancel(TASK_ID_CHIPSET);
@@ -474,7 +498,9 @@ void chipset_reset(void)
* reset pin and zero-latency. We do cold reset instead.
*/
CPRINTS("EC triggered cold reboot");
+ bypass_power_lost_trigger = 1;
power_off();
+ bypass_power_lost_trigger = 0;
/* Issue a request to initiate a power-on sequence */
power_request = POWER_REQ_ON;