summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorJenny TC <jenny.tc@intel.com>2017-11-22 09:58:19 +0530
committerchrome-bot <chrome-bot@chromium.org>2017-12-06 03:45:57 -0800
commit67c31eb10bc1ce6e559562aedd2f641de4243bb8 (patch)
tree506d18fd02ac83ec2e89282366a11378c56c984e /power
parentfb32b6d30cf55408f4bdb36b729c99452f6e8e11 (diff)
downloadchrome-ec-67c31eb10bc1ce6e559562aedd2f641de4243bb8.tar.gz
host_events: Introduce unified host event command
Unified Host Event Programming Interface (UHEPI) enables a unified host command EC_CMD_PROGRAM_HOST_EVENT to set/get/clear different host events. Old host event commands (0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F) is supported for backward compatibility. But newer version of BIOS/OS is expected to use UHEPI command (EC_CMD_PROGRAM_HOST_EVENT) The UHEPI also enables the active and lazy wake masks. Active wake mask is the mask that is programmed in the LPC driver (i.e. the mask that is actively used by LPC driver for waking the host during suspended state). It is same as the current wake mask that is set by the smihandler on host just before entering sleep state S3/S5. On the other hand, lazy wake masks are per-sleep masks (S0ix, S3, S5) so that they can be used by EC to set the active wake mask depending upon the type of sleep that the host has entered. This allows the host BIOS to perform one-time programming of the wake masks for each supported sleep type and then EC can take care of appropriately setting the active mask when host enters a particular sleep state. BRANCH=none BUG=b:63969337 TEST=make buildall -j. And verfieid following scenario 1). Verified wake masks with ec hostevent command on S0,S3,S5 and S0ix 2). suspend_stress_test with S3 and S0ix 3). Verified "mosys eventlog list" in S3 and s0ix resume to confirm wake sources (Lid, power buttton and Mode change) 4). Verified "mosys eventlog list" in S5 resume to confirm wake sources (Power Button) 5). Verified above scenarios with combination of Old BIOS + New EC and New BIOS + Old EC(making get_feature_flags1() return 0) Change-Id: Idb82ee87fffb475cd3fa9771bf7a5efda67af616 Signed-off-by: Jenny TC <jenny.tc@intel.com> Reviewed-on: https://chromium-review.googlesource.com/576047 Commit-Ready: Jenny Tc <jenny.tc@intel.com> Commit-Ready: Jenny Tc <jenny.tc@intel.corp-partner.google.com> Tested-by: Jenny Tc <jenny.tc@intel.com> Tested-by: Jenny Tc <jenny.tc@intel.corp-partner.google.com> Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Diffstat (limited to 'power')
-rw-r--r--power/common.c42
-rw-r--r--power/intel_x86.c48
2 files changed, 41 insertions, 49 deletions
diff --git a/power/common.c b/power/common.c
index 452aa7f9a9..ed1ffcc0e5 100644
--- a/power/common.c
+++ b/power/common.c
@@ -13,6 +13,7 @@
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
+#include "lpc.h"
#include "power.h"
#include "system.h"
#include "task.h"
@@ -196,6 +197,43 @@ void power_set_state(enum power_state new_state)
want_g3_exit = 0;
}
+#ifdef CONFIG_LPC
+
+/* If host doesn't program s0ix lazy wake mask, use default s0ix mask */
+#define DEFAULT_WAKE_MASK_S0IX (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE))
+ /*
+ * Set wake mask on edge of sleep state entry
+ * 1. On transition to S0, wake mask is reset.
+ * 2. In non-S0 states, active mask set by host gets a higher preference.
+ * 3. If host has not set any active mask, then check if a lazy mask exists
+ * for the current power state.
+ * 4. If state is S0ix and no lazy or active wake mask is set, then use default
+ * S0ix mask to be compatible with older BIOS versions.
+ *
+ * @param state New sleep state
+ */
+static void power_set_active_wake_mask(enum power_state state)
+{
+ host_event_t wake_mask;
+
+ if (state == POWER_S0)
+ wake_mask = 0;
+ else if (lpc_is_active_wm_set_by_host())
+ return;
+ else if (get_lazy_wake_mask(state, &wake_mask))
+ return;
+#ifdef CONFIG_POWER_S0IX
+ if ((state == POWER_S0ix) && (wake_mask == 0))
+ wake_mask = DEFAULT_WAKE_MASK_S0IX;
+#endif
+
+ lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, wake_mask);
+}
+#else
+static void power_set_active_wake_mask(enum power_state state) { }
+#endif
+
/**
* Common handler for steady states
*
@@ -414,8 +452,10 @@ void chipset_task(void *u)
new_state = power_common_state(state);
/* Handle state changes */
- if (new_state != state)
+ if (new_state != state) {
power_set_state(new_state);
+ power_set_active_wake_mask(new_state);
+ }
}
}
diff --git a/power/intel_x86.c b/power/intel_x86.c
index 59b2d529aa..8233261661 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -155,47 +155,6 @@ static void s0ix_transition(int check_state, int hook_id)
s0ix_notify = S0IX_NOTIFY_NONE;
}
-/*
- * In AP S0 -> S3 & S0ix transitions,
- * the chipset_suspend is called.
- *
- * The chipset_in_state(CHIPSET_STATE_STANDBY | CHIPSET_STATE_ON)
- * is used to detect the S0ix transiton.
- *
- * During S0ix entry, the wake mask for lid open and tablet mode is enabled.
- */
-static void s0ix_lpc_enable_wake_mask(void)
-{
- if (chipset_in_state(CHIPSET_STATE_STANDBY | CHIPSET_STATE_ON)) {
- host_event_t mask;
-
- mask = lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE) |
- EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) |
- EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE);
-
- lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, mask);
- }
-}
-
-/*
- * In AP S0ix & S3 -> S0 transitions,
- * the chipset_resume hook is called.
- *
- * During S0ix exit, the wake mask for lid open and tablet mode is disabled.
- */
-static void s0ix_lpc_disable_wake_mask(void)
-{
- if (chipset_in_state(CHIPSET_STATE_STANDBY | CHIPSET_STATE_ON)) {
- host_event_t mask;
-
- mask = lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE) &
- ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) &
- ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE);
-
- lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, mask);
- }
-}
-
static void handle_chipset_reset(void)
{
if (chipset_in_state(CHIPSET_STATE_STANDBY)) {
@@ -428,9 +387,6 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
#ifdef CONFIG_POWER_S0IX
case POWER_S0S0ix:
-
- s0ix_lpc_enable_wake_mask();
-
/*
* Call hooks only if we haven't notified listeners of S0ix
* suspend.
@@ -442,13 +398,9 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
* to go into deep sleep in S0ix.
*/
enable_sleep(SLEEP_MASK_AP_RUN);
-
return POWER_S0ix;
-
case POWER_S0ixS0:
- s0ix_lpc_disable_wake_mask();
-
/*
* Disable idle task deep sleep. This means that the low
* power idle task will not go into deep sleep while in S0.