diff options
author | Mulin Chao <mlchao@nuvoton.com> | 2016-08-05 19:00:40 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-13 01:03:48 -0700 |
commit | 96b0743e1f754ced950c1ecef86b7b05edd7e2f9 (patch) | |
tree | d79ecf6436f009e02be13406988a921ee2f3a328 /power | |
parent | e0497b041ac077673ffa182a3cb0e39f7c0c0cf6 (diff) | |
download | chrome-ec-96b0743e1f754ced950c1ecef86b7b05edd7e2f9.tar.gz |
power: Add virtual-wire power signals support for skylake.
Add virtual wire power signals support for skylake. By adding
CONFIG_VW_SIGNALS definition in board level driver, we can save three
GPIOs (SLP_S3/SLP_S4/CLK_RUN) on skylake platform.
Modified sources:
1. common.c: Add support for VW power signals.
2. skylake.c: Add upper func to get system sleep state through GPIOs or VWs.
BRANCH=none
BUG=none
TEST=make buildall; test boot up and shut down on eSPI POC of wheatley.
Change-Id: I0eae363dad8cec011eb32929a40701f19fde7e1a
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
Reviewed-on: https://chromium-review.googlesource.com/366711
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/common.c | 22 | ||||
-rw-r--r-- | power/skylake.c | 39 |
2 files changed, 54 insertions, 7 deletions
diff --git a/power/common.c b/power/common.c index 7f5d1aa873..cdefe38b9a 100644 --- a/power/common.c +++ b/power/common.c @@ -18,6 +18,7 @@ #include "task.h" #include "timer.h" #include "util.h" +#include "espi.h" /* Console output macros */ #define CPUTS(outstr) cputs(CC_CHIPSET, outstr) @@ -76,10 +77,25 @@ static int power_signal_get_level(enum gpio_signal signal) #ifdef CONFIG_POWER_S0IX return chipset_get_ps_debounced_level(signal); #else +#ifdef CONFIG_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) +{ +#ifdef CONFIG_VW_SIGNALS + /* Check signal is from GPIOs or VWs */ + if ((int)signal > VW_SIGNAL_BASE) + return espi_vw_enable_wire_int(signal); +#endif + return gpio_enable_interrupt(signal); +} + /** * Update input signals mask */ @@ -384,7 +400,7 @@ static void power_common_init(void) /* Enable interrupts for input signals */ for (i = 0; i < POWER_SIGNAL_COUNT; i++, s++) - gpio_enable_interrupt(s->gpio); + power_signal_enable_interrupt(s->gpio); /* * Update input state again since there is a small window @@ -421,6 +437,10 @@ DECLARE_HOOK(HOOK_AC_CHANGE, power_ac_change, HOOK_PRIO_DEFAULT); /*****************************************************************************/ /* Interrupts */ +#if defined(CONFIG_BRINGUP) && defined(CONFIG_VW_SIGNALS) +#error "Not support CONFIG_BRINGUP since gpio_get_name func" +#endif + #ifdef CONFIG_BRINGUP #define MAX_SIGLOG_ENTRIES 24 diff --git a/power/skylake.c b/power/skylake.c index d59f5a7349..39aebe578a 100644 --- a/power/skylake.c +++ b/power/skylake.c @@ -18,6 +18,7 @@ #include "util.h" #include "wireless.h" #include "lpc.h" +#include "espi.h" /* Console output macros */ #define CPUTS(outstr) cputs(CC_CHIPSET, outstr) @@ -55,6 +56,32 @@ static int throttle_cpu; /* Throttle CPU? */ static int forcing_shutdown; /* Forced shutdown in progress? */ static int power_s5_up; /* Chipset is sequencing up or down */ +enum sys_sleep_state { + SYS_SLEEP_S5, + SYS_SLEEP_S4, + SYS_SLEEP_S3 +}; + +/* Get system sleep state through GPIOs or VWs */ +static int chipset_get_sleep_signal(enum sys_sleep_state state) +{ +#ifdef CONFIG_VW_SIGNALS + if (state == SYS_SLEEP_S4) + return espi_vw_get_wire(VW_SLP_S4_L); + else if (state == SYS_SLEEP_S3) + return espi_vw_get_wire(VW_SLP_S3_L); +#else + if (state == SYS_SLEEP_S4) + return gpio_get_level(GPIO_PCH_SLP_S4_L); + else if (state == SYS_SLEEP_S3) + return gpio_get_level(GPIO_PCH_SLP_S3_L); +#endif + + /* We should never run here */ + ASSERT(0); + return 0; +} + void chipset_force_shutdown(void) { CPRINTS("%s()", __func__); @@ -219,7 +246,7 @@ static enum power_state _power_handle_state(enum power_state state) if (power_s5_up) return power_wait_s5_rtc_reset(); #endif - if (gpio_get_level(GPIO_PCH_SLP_S4_L) == 1) + if (chipset_get_sleep_signal(SYS_SLEEP_S4) == 1) return POWER_S5S3; /* Power up to next state */ break; @@ -228,10 +255,10 @@ static enum power_state _power_handle_state(enum power_state state) /* Required rail went away */ chipset_force_shutdown(); return POWER_S3S5; - } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1) { + } else if (chipset_get_sleep_signal(SYS_SLEEP_S3) == 1) { /* Power up to next state */ return POWER_S3S0; - } else if (gpio_get_level(GPIO_PCH_SLP_S4_L) == 0) { + } else if (chipset_get_sleep_signal(SYS_SLEEP_S4) == 0) { /* Power down to next state */ return POWER_S3S5; } @@ -243,10 +270,10 @@ static enum power_state _power_handle_state(enum power_state state) return POWER_S0S3; #ifdef CONFIG_POWER_S0IX } else if ((gpio_get_level(GPIO_PCH_SLP_S0_L) == 0) && - (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1)) { + (chipset_get_sleep_signal(SYS_SLEEP_S3) == 1)) { return POWER_S0S0ix; #endif - } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 0) { + } else if (chipset_get_sleep_signal(SYS_SLEEP_S3) == 0) { /* Power down to next state */ return POWER_S0S3; } @@ -259,7 +286,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) && - (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1)) { + (chipset_get_sleep_signal(SYS_SLEEP_S3) == 1)) { return POWER_S0ixS0; } |