diff options
author | Vijay Hiremath <vijay.p.hiremath@intel.com> | 2016-11-02 08:03:03 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-01-07 16:10:21 -0800 |
commit | 2ddd8d8e5fc123e75b9720ee26fdcc3e85de51ad (patch) | |
tree | 90019312a88a2fc41911b64e6d58b101292fd6d6 /power | |
parent | b3a9e1b64c25a4e35345903f5e20a841817962f6 (diff) | |
download | chrome-ec-2ddd8d8e5fc123e75b9720ee26fdcc3e85de51ad.tar.gz |
power: Extract Intel x86 power sequencing common code
Extracted Intel x86 power sequencing common code from skylake.c
and apollolake.c to implement common code for power sequencing.
BUG=chrome-os-partner:59141
BRANCH=none
TEST=make buildall -j
Reef can boot to OS. S3, S5, hibernate are working.
Change-Id: I73478fcabb24d6d98cd474bae3586ce5b02986fe
Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/406486
Commit-Ready: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Tested-by: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/apollolake.c | 98 | ||||
-rw-r--r-- | power/apollolake.h | 32 | ||||
-rw-r--r-- | power/build.mk | 4 | ||||
-rw-r--r-- | power/intel_x86.c | 82 | ||||
-rw-r--r-- | power/intel_x86.h | 33 | ||||
-rw-r--r-- | power/skylake.c | 97 | ||||
-rw-r--r-- | power/skylake.h | 34 |
7 files changed, 202 insertions, 178 deletions
diff --git a/power/apollolake.c b/power/apollolake.c index b0d2916df6..adb93f3256 100644 --- a/power/apollolake.c +++ b/power/apollolake.c @@ -5,18 +5,15 @@ /* Apollolake chipset power control module for Chrome EC */ +#include "apollolake.h" #include "charge_state.h" #include "chipset.h" -#include "common.h" #include "console.h" +#include "ec_commands.h" #include "hooks.h" -#include "host_command.h" -#include "lid_switch.h" +#include "intel_x86.h" #include "lpc.h" -#include "power.h" -#include "power_button.h" #include "system.h" -#include "task.h" #include "util.h" #include "wireless.h" @@ -24,25 +21,6 @@ #define CPUTS(outstr) cputs(CC_CHIPSET, outstr) #define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) -/* Input state flags */ -#define IN_RSMRST_N POWER_SIGNAL_MASK(X86_RSMRST_N) -#define IN_ALL_SYS_PG POWER_SIGNAL_MASK(X86_ALL_SYS_PG) -#define IN_SLP_S3_N POWER_SIGNAL_MASK(X86_SLP_S3_N) -#define IN_SLP_S4_N POWER_SIGNAL_MASK(X86_SLP_S4_N) -#define IN_SUSPWRDNACK POWER_SIGNAL_MASK(X86_SUSPWRDNACK) -#define IN_SUS_STAT_N POWER_SIGNAL_MASK(X86_SUS_STAT_N) - -#define IN_ALL_PM_SLP_DEASSERTED (IN_SLP_S3_N | \ - IN_SLP_S4_N) - -#define IN_PGOOD_ALL_CORE (IN_RSMRST_N) - -#define IN_ALL_S0 (IN_PGOOD_ALL_CORE | IN_ALL_PM_SLP_DEASSERTED) - -#define CHARGER_INITIALIZED_DELAY_MS 100 -#define CHARGER_INITIALIZED_TRIES 40 - -static int throttle_cpu; /* Throttle CPU? */ static int forcing_coldreset; /* Forced coldreset in progress? */ static int power_s5_up; /* Chipset is sequencing up or down */ @@ -85,6 +63,11 @@ void chipset_force_shutdown(void) chipset_do_shutdown(); } +void chipset_force_g3(void) +{ + chipset_force_shutdown(); +} + void chipset_reset(int cold_reset) { CPRINTS("%s(%d)", __func__, cold_reset); @@ -106,35 +89,7 @@ void chipset_reset(int cold_reset) } } -void chipset_throttle_cpu(int throttle) -{ - if (chipset_in_state(CHIPSET_STATE_ON)) - gpio_set_level(GPIO_CPU_PROCHOT, throttle); -} - -enum power_state power_chipset_init(void) -{ - /* - * If we're switching between images without rebooting, see if the x86 - * is already powered on; if so, leave it there instead of cycling - * through G3. - */ - if (system_jumped_to_this_image()) { - if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) { - /* Disable idle task deep sleep when in S0. */ - disable_sleep(SLEEP_MASK_AP_RUN); - CPRINTS("already in S0"); - return POWER_S0; - } else { - /* Force all signals to their G3 states */ - chipset_force_shutdown(); - } - } - - return POWER_G3; -} - -static void handle_rsmrst_l_pgood(enum power_state state) +void handle_rsmrst(enum power_state state) { /* * Pass through asynchronously, as SOC may not react @@ -174,37 +129,6 @@ static void handle_all_sys_pgood(enum power_state state) CPRINTS("Pass through GPIO_ALL_SYS_PGOOD: %d", in_level); } -#ifdef CONFIG_BOARD_HAS_RTC_RESET -static enum power_state power_wait_s5_rtc_reset(void) -{ - static int s5_exit_tries; - - /* Wait for S5 exit and then attempt RTC reset */ - while ((power_get_signals() & IN_PCH_SLP_S4_DEASSERTED) == 0) { - /* Handle RSMRST passthru event while waiting */ - handle_rsmrst(POWER_S5); - if (task_wait_event(SECOND*4) == TASK_EVENT_TIMER) { - CPRINTS("timeout waiting for S5 exit"); - chipset_force_g3(); - - /* Assert RTCRST# and retry 5 times */ - board_rtc_reset(); - - if (++s5_exit_tries > 4) { - s5_exit_tries = 0; - return POWER_G3; /* Stay off */ - } - - udelay(10 * MSEC); - return POWER_G3S5; /* Power up again */ - } - } - - s5_exit_tries = 0; - return POWER_S5S3; /* Power up to next state */ -} -#endif - static enum power_state _power_handle_state(enum power_state state) { int tries = 0; @@ -352,7 +276,7 @@ static enum power_state _power_handle_state(enum power_state state) * Throttle CPU if necessary. This should only be asserted * when +VCCP is powered (it is by now). */ - gpio_set_level(GPIO_CPU_PROCHOT, throttle_cpu); + gpio_set_level(GPIO_CPU_PROCHOT, 0); return POWER_S0; @@ -454,7 +378,7 @@ enum power_state power_handle_state(enum power_state state) * RSMRST_L is also checked in some states and, if asserted, will * force shutdown. */ - handle_rsmrst_l_pgood(new_state); + handle_rsmrst(new_state); return new_state; } diff --git a/power/apollolake.h b/power/apollolake.h new file mode 100644 index 0000000000..424da3cefc --- /dev/null +++ b/power/apollolake.h @@ -0,0 +1,32 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Apollolake chipset power control module for Chrome EC */ + +#ifndef __CROS_EC_APOLLOLAKE_H +#define __CROS_EC_APOLLOLAKE_H + +/* + * Input state flags. + * TODO: Normalize the power signal masks from board defines to SoC headers. + */ +#define IN_RSMRST_N POWER_SIGNAL_MASK(X86_RSMRST_N) +#define IN_ALL_SYS_PG POWER_SIGNAL_MASK(X86_ALL_SYS_PG) +#define IN_SLP_S3_N POWER_SIGNAL_MASK(X86_SLP_S3_N) +#define IN_SLP_S4_N POWER_SIGNAL_MASK(X86_SLP_S4_N) +#define IN_SUSPWRDNACK POWER_SIGNAL_MASK(X86_SUSPWRDNACK) +#define IN_SUS_STAT_N POWER_SIGNAL_MASK(X86_SUS_STAT_N) + +#define IN_ALL_PM_SLP_DEASSERTED (IN_SLP_S3_N | \ + IN_SLP_S4_N) + +#define IN_PGOOD_ALL_CORE (IN_RSMRST_N) + +#define IN_ALL_S0 (IN_PGOOD_ALL_CORE | IN_ALL_PM_SLP_DEASSERTED) + +#define CHARGER_INITIALIZED_DELAY_MS 100 +#define CHARGER_INITIALIZED_TRIES 40 + +#endif /* __CROS_EC_APOLLOLAKE_H */ diff --git a/power/build.mk b/power/build.mk index cfb142833b..6143c3dbbf 100644 --- a/power/build.mk +++ b/power/build.mk @@ -6,7 +6,7 @@ # Power management for application processor and peripherals # -power-$(CONFIG_CHIPSET_APOLLOLAKE)+=apollolake.o +power-$(CONFIG_CHIPSET_APOLLOLAKE)+=apollolake.o intel_x86.o power-$(CONFIG_CHIPSET_BAYTRAIL)+=baytrail.o power-$(CONFIG_CHIPSET_BRASWELL)+=braswell.o power-$(CONFIG_CHIPSET_ECDRIVEN)+=ec_driven.o @@ -15,6 +15,6 @@ power-$(CONFIG_CHIPSET_HASWELL)+=haswell.o power-$(CONFIG_CHIPSET_MEDIATEK)+=mediatek.o power-$(CONFIG_CHIPSET_RK3399)+=rk3399.o power-$(CONFIG_CHIPSET_ROCKCHIP)+=rockchip.o -power-$(CONFIG_CHIPSET_SKYLAKE)+=skylake.o +power-$(CONFIG_CHIPSET_SKYLAKE)+=skylake.o intel_x86.o power-$(CONFIG_CHIPSET_TEGRA)+=tegra.o power-$(CONFIG_POWER_COMMON)+=common.o diff --git a/power/intel_x86.c b/power/intel_x86.c new file mode 100644 index 0000000000..616ee739a9 --- /dev/null +++ b/power/intel_x86.c @@ -0,0 +1,82 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Intel X86 chipset power control module for Chrome EC */ + +#include "chipset.h" +#include "console.h" +#include "gpio.h" +#include "intel_x86.h" +#include "system.h" +#include "task.h" + +/* Chipset specific header files */ +#ifdef CONFIG_CHIPSET_APOLLOLAKE +#include "apollolake.h" +#elif defined(CONFIG_CHIPSET_SKYLAKE) +#include "skylake.h" +#endif + +/* Console output macros */ +#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) + +#ifdef CONFIG_BOARD_HAS_RTC_RESET +enum power_state power_wait_s5_rtc_reset(void) +{ + static int s5_exit_tries; + + /* Wait for S5 exit and then attempt RTC reset */ + while ((power_get_signals() & IN_PCH_SLP_S4_DEASSERTED) == 0) { + /* Handle RSMRST passthru event while waiting */ + handle_rsmrst(POWER_S5); + if (task_wait_event(SECOND*4) == TASK_EVENT_TIMER) { + CPRINTS("timeout waiting for S5 exit"); + chipset_force_g3(); + + /* Assert RTCRST# and retry 5 times */ + board_rtc_reset(); + + if (++s5_exit_tries > 4) { + s5_exit_tries = 0; + return POWER_G3; /* Stay off */ + } + + udelay(10 * MSEC); + return POWER_G3S5; /* Power up again */ + } + } + + s5_exit_tries = 0; + return POWER_S5S3; /* Power up to next state */ +} +#endif + +void chipset_throttle_cpu(int throttle) +{ + if (chipset_in_state(CHIPSET_STATE_ON)) + gpio_set_level(GPIO_CPU_PROCHOT, throttle); +} + +enum power_state power_chipset_init(void) +{ + /* + * If we're switching between images without rebooting, see if the x86 + * is already powered on; if so, leave it there instead of cycling + * through G3. + */ + if (system_jumped_to_this_image()) { + if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) { + /* Disable idle task deep sleep when in S0. */ + disable_sleep(SLEEP_MASK_AP_RUN); + CPRINTS("already in S0"); + return POWER_S0; + } + + /* Force all signals to their G3 states */ + chipset_force_g3(); + } + + return POWER_G3; +} diff --git a/power/intel_x86.h b/power/intel_x86.h new file mode 100644 index 0000000000..08d9b89a6f --- /dev/null +++ b/power/intel_x86.h @@ -0,0 +1,33 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Intel X86 chipset power control module for Chrome EC */ + + +#ifndef __CROS_EC_INTEL_X86_H +#define __CROS_EC_INTEL_X86_H + +#include "power.h" + +/** + * Handle RSMRST signal. + * + * @param state Current chipset state. + */ +void handle_rsmrst(enum power_state state); + +/** + * Force chipset to G3 state. + */ +void chipset_force_g3(void); + +/** + * Wait for S5 exit and then attempt RTC reset. + * + * @return power_state New chipset state. + */ +enum power_state power_wait_s5_rtc_reset(void); + +#endif /* __CROS_EC_INTEL_X86_H */ diff --git a/power/skylake.c b/power/skylake.c index bf02714430..1bdad6d491 100644 --- a/power/skylake.c +++ b/power/skylake.c @@ -8,44 +8,22 @@ #include "board_config.h" #include "charge_state.h" #include "chipset.h" -#include "common.h" #include "console.h" +#include "ec_commands.h" +#include "espi.h" #include "hooks.h" -#include "host_command.h" -#include "power.h" +#include "intel_x86.h" +#include "lpc.h" #include "power_button.h" +#include "skylake.h" #include "system.h" -#include "task.h" #include "util.h" #include "wireless.h" -#include "lpc.h" -#include "espi.h" /* Console output macros */ #define CPUTS(outstr) cputs(CC_CHIPSET, outstr) #define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) -/* Input state flags */ -#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) - -#define IN_ALL_PM_SLP_DEASSERTED (IN_PCH_SLP_S3_DEASSERTED | \ - IN_PCH_SLP_S4_DEASSERTED | \ - IN_PCH_SLP_SUS_DEASSERTED) - -/* - * DPWROK is NC / stuffing option on initial boards. - * TODO(shawnn): Figure out proper control signals. - */ -#define IN_PGOOD_ALL_CORE 0 - -#define IN_ALL_S0 (IN_PGOOD_ALL_CORE | IN_ALL_PM_SLP_DEASSERTED) - -#define CHARGER_INITIALIZED_DELAY_MS 100 -#define CHARGER_INITIALIZED_TRIES 40 - -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 */ @@ -97,7 +75,7 @@ __attribute__((weak)) void chipset_set_pmic_slp_sus_l(int level) gpio_set_level(GPIO_PMIC_SLP_SUS_L, level); } -static void chipset_force_g3(void) +void chipset_force_g3(void) { CPRINTS("Forcing fake G3."); @@ -133,35 +111,7 @@ void chipset_reset(int cold_reset) } } -void chipset_throttle_cpu(int throttle) -{ - if (chipset_in_state(CHIPSET_STATE_ON)) - gpio_set_level(GPIO_CPU_PROCHOT, throttle); -} - -enum power_state power_chipset_init(void) -{ - /* - * If we're switching between images without rebooting, see if the x86 - * is already powered on; if so, leave it there instead of cycling - * through G3. - */ - if (system_jumped_to_this_image()) { - if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) { - /* Disable idle task deep sleep when in S0. */ - disable_sleep(SLEEP_MASK_AP_RUN); - CPRINTS("already in S0"); - return POWER_S0; - } else { - /* Force all signals to their G3 states */ - chipset_force_g3(); - } - } - - return POWER_G3; -} - -static void handle_rsmrst(enum power_state state) +void handle_rsmrst(enum power_state state) { /* * Pass through RSMRST asynchronously, as PCH may not react @@ -198,37 +148,6 @@ static void handle_slp_sus(enum power_state state) chipset_set_pmic_slp_sus_l(gpio_get_level(GPIO_PCH_SLP_SUS_L)); } -#ifdef CONFIG_BOARD_HAS_RTC_RESET -static enum power_state power_wait_s5_rtc_reset(void) -{ - static int s5_exit_tries; - - /* Wait for S5 exit and then attempt RTC reset */ - while ((power_get_signals() & IN_PCH_SLP_S4_DEASSERTED) == 0) { - /* Handle RSMRST passthru event while waiting */ - handle_rsmrst(POWER_S5); - if (task_wait_event(SECOND*4) == TASK_EVENT_TIMER) { - CPRINTS("timeout waiting for S5 exit"); - chipset_force_g3(); - - /* Assert RTCRST# and retry 5 times */ - board_rtc_reset(); - - if (++s5_exit_tries > 4) { - s5_exit_tries = 0; - return POWER_G3; /* Stay off */ - } - - udelay(10 * MSEC); - return POWER_G3S5; /* Power up again */ - } - } - - s5_exit_tries = 0; - return POWER_S5S3; /* Power up to next state */ -} -#endif - static enum power_state _power_handle_state(enum power_state state) { int tries = 0; @@ -370,7 +289,7 @@ static enum power_state _power_handle_state(enum power_state state) * Throttle CPU if necessary. This should only be asserted * when +VCCP is powered (it is by now). */ - gpio_set_level(GPIO_CPU_PROCHOT, throttle_cpu); + gpio_set_level(GPIO_CPU_PROCHOT, 0); return POWER_S0; diff --git a/power/skylake.h b/power/skylake.h new file mode 100644 index 0000000000..d44fb00e19 --- /dev/null +++ b/power/skylake.h @@ -0,0 +1,34 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Skylake IMVP8 / ROP PMIC chipset power control module for Chrome EC */ + +#ifndef __CROS_EC_SKYLAKE_H +#define __CROS_EC_SKYLAKE_H + +/* + * Input state flags. + * TODO: Normalize the power signal masks from board defines to SoC headers. + */ +#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) + +#define IN_ALL_PM_SLP_DEASSERTED (IN_PCH_SLP_S3_DEASSERTED | \ + IN_PCH_SLP_S4_DEASSERTED | \ + IN_PCH_SLP_SUS_DEASSERTED) + +/* + * DPWROK is NC / stuffing option on initial boards. + * TODO(shawnn): Figure out proper control signals. + */ +#define IN_PGOOD_ALL_CORE 0 + +#define IN_ALL_S0 (IN_PGOOD_ALL_CORE | IN_ALL_PM_SLP_DEASSERTED) + +#define CHARGER_INITIALIZED_DELAY_MS 100 +#define CHARGER_INITIALIZED_TRIES 40 + +#endif /* __CROS_EC_SKYLAKE_H */ |