summaryrefslogtreecommitdiff
path: root/power/rk3399.c
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2017-07-14 13:10:34 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-07-28 15:04:24 -0700
commit51ea5020414cd43e280f9d3604e8f44638db2a55 (patch)
treeb673c04ca5ea6151ffe35d3f8303aa12b8b232d5 /power/rk3399.c
parent2f09d4adea3aa4588da24521252c7efe067068f8 (diff)
downloadchrome-ec-51ea5020414cd43e280f9d3604e8f44638db2a55.tar.gz
power/rk3399: Support USB wake in host-requested wakeable S3
For boards with POWER_SEQUENCING_VERSION = 2 (and likely future versions), allow the host to request "wakeable suspend", which will leave rails enabled to allow wake-on-usb. BUG=b:63037490 BRANCH=kevin TEST=With subsequent commit, compile on scarlet w/ power sequencing version = 2. Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: Iaadd371b1d1509d185c8c8306b72760dcfe9989f Reviewed-on: https://chromium-review.googlesource.com/572211 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Philip Chen <philipchen@chromium.org>
Diffstat (limited to 'power/rk3399.c')
-rw-r--r--power/rk3399.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/power/rk3399.c b/power/rk3399.c
index 3c8fe81150..956685783d 100644
--- a/power/rk3399.c
+++ b/power/rk3399.c
@@ -50,6 +50,8 @@
#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 2
#define IN_PGOOD_S3 (IN_PGOOD_PP1250_S3)
#define IN_PGOOD_S0 (IN_PGOOD_S3 | IN_PGOOD_PP900_S0 | IN_PGOOD_AP)
+ /* This board can optionally wake-on-USB in S3 */
+ #define S3_USB_WAKE
#else
#define IN_PGOOD_S3 (IN_PGOOD_PP5000)
#define IN_PGOOD_S0 (IN_PGOOD_S3 | IN_PGOOD_AP | IN_PGOOD_SYS)
@@ -111,9 +113,6 @@ static const struct power_seq_op s5s3_power_seq[] = {
/* The power sequence for POWER_S3S0 */
static const struct power_seq_op s3s0_power_seq[] = {
#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 2
- { GPIO_PP900_S0_EN, 1, 2 },
- { GPIO_PP1800_USB_EN, 1, 2 },
- { GPIO_PP3300_S0_EN, 1, 2 },
{ GPIO_AP_CORE_EN, 1, 2 },
{ GPIO_PP1800_S0_EN, 1, 0},
#else
@@ -126,14 +125,20 @@ static const struct power_seq_op s3s0_power_seq[] = {
#endif
};
+#ifdef S3_USB_WAKE
+/* Sigs that may already be on in S3, if we need to wake-on-USB */
+static const struct power_seq_op s3s0_usb_wake_power_seq[] = {
+ { GPIO_PP900_S0_EN, 1, 2 },
+ { GPIO_PP1800_USB_EN, 1, 2 },
+ { GPIO_PP3300_S0_EN, 1, 2 },
+};
+#endif
+
/* The power sequence for POWER_S0S3 */
static const struct power_seq_op s0s3_power_seq[] = {
#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 2
{ GPIO_PP1800_S0_EN, 0, 1 },
{ GPIO_AP_CORE_EN, 0, 20 },
- { GPIO_PP3300_S0_EN, 0, 20 },
- { GPIO_PP1800_USB_EN, 0, 1 },
- { GPIO_PP900_S0_EN, 0, 1 },
#else
{ GPIO_PP3300_S0_EN_L, 1, 20 },
{ GPIO_PP1800_S0_EN_L, 1, 1 },
@@ -144,6 +149,15 @@ static const struct power_seq_op s0s3_power_seq[] = {
#endif
};
+#ifdef S3_USB_WAKE
+/* Sigs that need to be left on in S3, if we need to wake-on-USB */
+static const struct power_seq_op s0s3_usb_wake_power_seq[] = {
+ { GPIO_PP3300_S0_EN, 0, 20 },
+ { GPIO_PP1800_USB_EN, 0, 1 },
+ { GPIO_PP900_S0_EN, 0, 1 },
+};
+#endif
+
/* The power sequence for POWER_S3S5 */
static const struct power_seq_op s3s5_power_seq[] = {
#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 2
@@ -282,6 +296,9 @@ static int power_seq_run(const struct power_seq_op *power_seq_ops, int op_count)
enum power_state power_handle_state(enum power_state state)
{
static int sys_reset_asserted;
+#ifdef S3_USB_WAKE
+ static int usb_wake_enabled;
+#endif
int tries = 0;
switch (state) {
@@ -380,6 +397,13 @@ enum power_state power_handle_state(enum power_state state)
return POWER_S3;
case POWER_S3S0:
+#ifdef S3_USB_WAKE
+ /* Bring up S3 USB wake rails, if they are down */
+ if (!usb_wake_enabled)
+ power_seq_run(s3s0_usb_wake_power_seq,
+ ARRAY_SIZE(s3s0_usb_wake_power_seq));
+ usb_wake_enabled = 0;
+#endif
power_seq_run(s3s0_power_seq, ARRAY_SIZE(s3s0_power_seq));
/* Release SYS_RST if we came from S5 */
@@ -415,6 +439,16 @@ enum power_state power_handle_state(enum power_state state)
if (power_seq_run(s0s3_power_seq, ARRAY_SIZE(s0s3_power_seq)))
return POWER_S3S0;
+#ifdef S3_USB_WAKE
+ /* Leave up rails needed for S3 USB wake, if requested */
+ usb_wake_enabled = (power_get_host_sleep_state() ==
+ HOST_SLEEP_EVENT_S3_WAKEABLE_SUSPEND);
+ if (!usb_wake_enabled &&
+ power_seq_run(s0s3_usb_wake_power_seq,
+ ARRAY_SIZE(s0s3_power_seq)))
+ return POWER_S3S0;
+#endif
+
/*
* Enable idle task deep sleep. Allow the low power idle task
* to go into deep sleep in S3 or lower.
@@ -433,6 +467,15 @@ enum power_state power_handle_state(enum power_state state)
return POWER_S3;
case POWER_S3S5:
+#ifdef S3_USB_WAKE
+ /* Make sure all S3 rails are off */
+ if (usb_wake_enabled) {
+ power_seq_run(s0s3_usb_wake_power_seq,
+ ARRAY_SIZE(s0s3_power_seq));
+ usb_wake_enabled = 0;
+ }
+#endif
+
/* Call hooks before we remove power rails */
hook_notify(HOOK_CHIPSET_SHUTDOWN);