summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay Hiremath <vijay.p.hiremath@intel.com>2016-11-11 08:19:15 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-11-13 10:58:58 -0800
commit9b47a0812d963c4c02d47655741f63618bd41a22 (patch)
treebbef05891b30210b8d84d5fc9c2f054738846e75
parent98402bb466e53cbe7b0d47287823126f7de0fdb8 (diff)
downloadchrome-ec-9b47a0812d963c4c02d47655741f63618bd41a22.tar.gz
skylake: Add support to S0iX based on host commands from Kernel
Picked the code from Glados branch. Change-Id: I4bf114235c4d542dd7cf0dad6427c771e54d4611 https://chromium-review.googlesource.com/#/c/331358/ BUG=chrome-os-partner:59742 BRANCH=none TEST=make buildall -j Change-Id: Ib79f1209dfd9e6a9de0438cb1866bba2939e5393 Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com> Reviewed-on: https://chromium-review.googlesource.com/410036 Commit-Ready: Vijay P Hiremath <vijay.p.hiremath@intel.com> Tested-by: Vijay P Hiremath <vijay.p.hiremath@intel.com> Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Kevin K Wong <kevin.k.wong@intel.com>
-rw-r--r--board/chell/board.c1
-rw-r--r--board/chell/board.h1
-rw-r--r--board/chell/gpio.inc2
-rw-r--r--include/power.h10
-rw-r--r--power/common.c4
-rw-r--r--power/skylake.c107
6 files changed, 54 insertions, 71 deletions
diff --git a/board/chell/board.c b/board/chell/board.c
index a930e45051..2d59ab68fe 100644
--- a/board/chell/board.c
+++ b/board/chell/board.c
@@ -82,7 +82,6 @@ void usb1_evt(enum gpio_signal signal)
/* power signal list. Must match order of enum power_signal. */
const struct power_signal_info power_signal_list[] = {
{GPIO_RSMRST_L_PGOOD, 1, "RSMRST_N_PWRGD"},
- {GPIO_PCH_SLP_S0_L, 1, "SLP_S0_DEASSERTED"},
{GPIO_PCH_SLP_S3_L, 1, "SLP_S3_DEASSERTED"},
{GPIO_PCH_SLP_S4_L, 1, "SLP_S4_DEASSERTED"},
{GPIO_PCH_SLP_SUS_L, 1, "SLP_SUS_DEASSERTED"},
diff --git a/board/chell/board.h b/board/chell/board.h
index ffac383c9f..7b7033208b 100644
--- a/board/chell/board.h
+++ b/board/chell/board.h
@@ -163,7 +163,6 @@ enum pwm_channel {
/* power signal definitions */
enum power_signal {
X86_RSMRST_L_PWRGD = 0,
- X86_SLP_S0_DEASSERTED,
X86_SLP_S3_DEASSERTED,
X86_SLP_S4_DEASSERTED,
X86_SLP_SUS_DEASSERTED,
diff --git a/board/chell/gpio.inc b/board/chell/gpio.inc
index 2d2d61c60f..d8da255b09 100644
--- a/board/chell/gpio.inc
+++ b/board/chell/gpio.inc
@@ -17,7 +17,6 @@ GPIO_INT(POWER_BUTTON_L, PIN(35), GPIO_INT_BOTH, power_button_interrupt)
GPIO_INT(RSMRST_L_PGOOD, PIN(63), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(PCH_SLP_S4_L, PIN(200), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(PCH_SLP_S3_L, PIN(206), GPIO_INT_BOTH, power_signal_interrupt)
-GPIO_INT(PCH_SLP_S0_L, PIN(211), GPIO_INT_BOTH, power_signal_interrupt_S0)
GPIO_INT(PCH_SLP_SUS_L, PIN(12), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(PMIC_INT_L, PIN(50), GPIO_INT_FALLING, power_signal_interrupt)
GPIO_INT(PD_MCU_INT, PIN(122), GPIO_INT_FALLING | GPIO_PULL_UP, pd_mcu_interrupt)
@@ -56,6 +55,7 @@ GPIO(PCH_RSMRST_L, PIN(143), GPIO_OUT_LOW)
GPIO(PCH_RTCRST, PIN(163), GPIO_OUT_LOW)
GPIO(SYS_RESET_L, PIN(121), GPIO_ODR_HIGH)
GPIO(ENTERING_RW, PIN(41), GPIO_OUT_LOW)
+GPIO(PCH_SLP_S0_L, PIN(211), GPIO_INPUT)
/* Devices and power */
GPIO(PP1800_DX_DMIC_EN, PIN(11), GPIO_OUT_LOW)
diff --git a/include/power.h b/include/power.h
index b81a952156..6a133749bf 100644
--- a/include/power.h
+++ b/include/power.h
@@ -117,20 +117,10 @@ enum power_state power_handle_state(enum power_state state);
*/
#ifdef HAS_TASK_CHIPSET
void power_signal_interrupt(enum gpio_signal signal);
-#ifdef CONFIG_POWER_S0IX
-void power_signal_interrupt_S0(enum gpio_signal signal);
-#endif
#else
static inline void power_signal_interrupt(enum gpio_signal signal) { }
-#ifdef CONFIG_POWER_S0IX
-static inline void power_signal_interrupt_S0(enum gpio_signal signal) { }
-#endif
#endif /* !HAS_TASK_CHIPSET */
-#ifdef CONFIG_POWER_S0IX
-int chipset_get_ps_debounced_level(enum gpio_signal signal);
-#endif
-
/**
* pause_in_s5 getter method.
*
diff --git a/power/common.c b/power/common.c
index 789b872f2a..832e1cc251 100644
--- a/power/common.c
+++ b/power/common.c
@@ -74,16 +74,12 @@ static int pause_in_s5;
static int power_signal_get_level(enum gpio_signal signal)
{
-#ifdef CONFIG_POWER_S0IX
- return chipset_get_ps_debounced_level(signal);
-#else
#ifdef CONFIG_ESPI_VW_SIGNALS
/* Check signal is from GPIOs or VWs */
if ((int)signal > VW_SIGNAL_BASE)
return espi_vw_get_wire(signal);
#endif
return gpio_get_level(signal);
-#endif
}
static int power_signal_enable_interrupt(enum gpio_signal signal)
diff --git a/power/skylake.c b/power/skylake.c
index 718ff5aeca..a90921e327 100644
--- a/power/skylake.c
+++ b/power/skylake.c
@@ -26,21 +26,13 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Input state flags */
-#define IN_PCH_SLP_S0_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S0_DEASSERTED)
#define IN_PCH_SLP_S3_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S3_DEASSERTED)
#define IN_PCH_SLP_S4_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S4_DEASSERTED)
#define IN_PCH_SLP_SUS_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_SUS_DEASSERTED)
-#ifdef CONFIG_POWER_S0IX
-#define IN_ALL_PM_SLP_DEASSERTED (IN_PCH_SLP_S0_DEASSERTED | \
- IN_PCH_SLP_S3_DEASSERTED | \
- IN_PCH_SLP_S4_DEASSERTED | \
- IN_PCH_SLP_SUS_DEASSERTED)
-#else
#define IN_ALL_PM_SLP_DEASSERTED (IN_PCH_SLP_S3_DEASSERTED | \
IN_PCH_SLP_S4_DEASSERTED | \
IN_PCH_SLP_SUS_DEASSERTED)
-#endif
/*
* DPWROK is NC / stuffing option on initial boards.
@@ -63,6 +55,19 @@ enum sys_sleep_state {
SYS_SLEEP_S3
};
+#ifdef CONFIG_POWER_S0IX
+static int slp_s0ix_host_evt = 1;
+static int get_slp_s0ix_host_evt(void)
+{
+ return slp_s0ix_host_evt;
+}
+
+static void set_slp_s0ix_host_evt(int val)
+{
+ slp_s0ix_host_evt = val;
+}
+#endif
+
/* Get system sleep state through GPIOs or VWs */
static int chipset_get_sleep_signal(enum sys_sleep_state state)
{
@@ -279,7 +284,7 @@ static enum power_state _power_handle_state(enum power_state state)
chipset_force_shutdown();
return POWER_S0S3;
#ifdef CONFIG_POWER_S0IX
- } else if ((gpio_get_level(GPIO_PCH_SLP_S0_L) == 0) &&
+ } else if ((get_slp_s0ix_host_evt() == 0) &&
(chipset_get_sleep_signal(SYS_SLEEP_S3) == 1)) {
return POWER_S0S0ix;
#endif
@@ -295,7 +300,7 @@ static enum power_state _power_handle_state(enum power_state state)
/*
* TODO: add code for unexpected power loss
*/
- if ((gpio_get_level(GPIO_PCH_SLP_S0_L) == 1) &&
+ if ((get_slp_s0ix_host_evt() == 1) &&
(chipset_get_sleep_signal(SYS_SLEEP_S3) == 1)) {
return POWER_S0ixS0;
}
@@ -341,6 +346,14 @@ static enum power_state _power_handle_state(enum power_state state)
/* Call hooks now that rails are up */
hook_notify(HOOK_CHIPSET_STARTUP);
+
+#ifdef CONFIG_POWER_S0IX
+ /*
+ * Clearing the S0ix flag on the path to S0
+ * to handle any reset conditions.
+ */
+ set_slp_s0ix_host_evt(1);
+#endif
return POWER_S3;
case POWER_S3S0:
@@ -387,6 +400,10 @@ static enum power_state _power_handle_state(enum power_state state)
*/
enable_sleep(SLEEP_MASK_AP_RUN);
+#ifdef CONFIG_POWER_S0IX
+ /* re-init S0ix flag */
+ set_slp_s0ix_host_evt(1);
+#endif
return POWER_S3;
#ifdef CONFIG_POWER_S0IX
@@ -460,53 +477,35 @@ enum power_state power_handle_state(enum power_state state)
}
#ifdef CONFIG_POWER_S0IX
-static struct {
- int required; /* indicates de-bounce required. */
- int done; /* debounced */
-} slp_s0_debounce = {
- .required = 0,
- .done = 1,
-};
-
-int chipset_get_ps_debounced_level(enum gpio_signal signal)
-{
- /*
- * If power state is updated in power_update_signal() by any interrupts
- * other than SLP_S0 during the 1 msec pulse(invalid SLP_S0 signal),
- * reading SLP_S0 should be corrected with slp_s0_debounce.done flag.
- */
- int level = gpio_get_level(signal);
- return (signal == GPIO_PCH_SLP_S0_L) ?
- (level & slp_s0_debounce.done) : level;
-}
-
-static void slp_s0_assertion_deferred(void)
+/*
+ * EC enters S0ix via a host command and exits S0ix via the above
+ * lid open hook. The host event for exit is received but is a no-op for now.
+ *
+ * EC will not react directly to SLP_S0 signal interrupts anymore.
+ */
+static int host_event_sleep_event(struct host_cmd_handler_args *args)
{
- int s0_level = gpio_get_level(GPIO_PCH_SLP_S0_L);
- /*
- (s0_level != 0) ||
- ((s0_level == 0) && (slp_s0_debounce.required == 0))
- */
- if (s0_level == slp_s0_debounce.required) {
- if (s0_level)
- slp_s0_debounce.done = 1; /* debounced! */
-
- power_signal_interrupt(GPIO_PCH_SLP_S0_L);
+ const struct ec_params_host_sleep_event *p = args->params;
+
+ if (p->sleep_event == HOST_SLEEP_EVENT_S0IX_SUSPEND) {
+ CPRINTS("S0ix sus evt");
+ set_slp_s0ix_host_evt(0);
+ task_wake(TASK_ID_CHIPSET);
+ } else if (p->sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME) {
+ CPRINTS("S0ix res evt");
+ set_slp_s0ix_host_evt(1);
+ /*
+ * For all scenarios where lid is not open
+ * this will be trigerred when other wake
+ * sources like keyboard, trackpad are used.
+ */
+ if (!chipset_in_state(CHIPSET_STATE_ON))
+ task_wake(TASK_ID_CHIPSET);
}
- slp_s0_debounce.required = 0;
+ return EC_RES_SUCCESS;
}
-DECLARE_DEFERRED(slp_s0_assertion_deferred);
+DECLARE_HOST_COMMAND(EC_CMD_HOST_SLEEP_EVENT, host_event_sleep_event,
+ EC_VER_MASK(0));
-void power_signal_interrupt_S0(enum gpio_signal signal)
-{
- if (gpio_get_level(GPIO_PCH_SLP_S0_L)) {
- slp_s0_debounce.required = 1;
- hook_call_deferred(&slp_s0_assertion_deferred_data, 3 * MSEC);
- }
- else if (slp_s0_debounce.required == 0) {
- slp_s0_debounce.done = 0;
- slp_s0_assertion_deferred();
- }
-}
#endif