From c6b6626cdccef04b0ff203aaed0d84dbdcecf8b7 Mon Sep 17 00:00:00 2001 From: Philip Chen Date: Thu, 24 May 2018 12:01:24 -0700 Subject: system: Enable/Disable low power idle in run time We have enable_sleep()/disable_sleep() to enable/disable EC deep sleep mode in runtime. Here we introduce similar interfaces to enable/disable EC idle (sleep) mode. BUG=b:78792296 BRANCH=scarlet TEST=Confirm idle mode is enabled/disabled when enable_idle() and disable_idle() are called. Change-Id: I2484f08a066523441064968da99c47de9342ecf0 Signed-off-by: Philip Chen Reviewed-on: https://chromium-review.googlesource.com/1072370 Reviewed-by: Randall Spangler Reviewed-by: Philip Chen Commit-Queue: Philip Chen Tested-by: Philip Chen --- chip/stm32/clock-stm32f0.c | 8 ++++++++ common/system.c | 5 +++++ include/config.h | 3 +++ include/system.h | 24 ++++++++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/chip/stm32/clock-stm32f0.c b/chip/stm32/clock-stm32f0.c index 2db0244cf9..d324e8bab5 100644 --- a/chip/stm32/clock-stm32f0.c +++ b/chip/stm32/clock-stm32f0.c @@ -322,6 +322,11 @@ void __idle(void) t0 = get_time(); next_delay = __hw_clock_event_get() - t0.le.lo; +#ifdef CONFIG_LOW_POWER_IDLE_LIMITED + if (idle_is_disabled()) + goto en_int; +#endif + if (DEEP_SLEEP_ALLOWED && #ifdef CONFIG_HOSTCMD_RTC /* @@ -381,6 +386,9 @@ void __idle(void) /* normal idle : only CPU clock stopped */ asm("wfi"); } +#ifdef CONFIG_LOW_POWER_IDLE_LIMITED +en_int: +#endif asm volatile("cpsie i"); } } diff --git a/common/system.c b/common/system.c index 48c26776b9..4df432ba3b 100644 --- a/common/system.c +++ b/common/system.c @@ -101,6 +101,11 @@ static enum ec_reboot_cmd reboot_at_shutdown; /* On-going actions preventing going into deep-sleep mode */ uint32_t sleep_mask; +#ifdef CONFIG_LOW_POWER_IDLE_LIMITED +/* Set it to prevent going into idle mode */ +uint32_t idle_disabled; +#endif + #ifdef CONFIG_HOSTCMD_AP_SET_SKUID static uint32_t ap_sku_id; diff --git a/include/config.h b/include/config.h index 4bdfd023ce..b2313b3813 100644 --- a/include/config.h +++ b/include/config.h @@ -1983,6 +1983,9 @@ #undef CONFIG_LOW_POWER_IDLE #undef CONFIG_LOW_POWER_USE_LFIOSC +/* Allows us to enable/disable low power idle mode in runtime. */ +#undef CONFIG_LOW_POWER_IDLE_LIMITED + /* * Enable deep sleep during S0 (ignores SLEEP_MASK_AP_RUN). */ diff --git a/include/system.h b/include/system.h index acc3f71471..9b58203c5c 100644 --- a/include/system.h +++ b/include/system.h @@ -479,6 +479,30 @@ static inline void disable_sleep(uint32_t mask) atomic_or(&sleep_mask, mask); } +#ifdef CONFIG_LOW_POWER_IDLE_LIMITED +/* + * If this variable is nonzero, all levels of idle modes are disabled. + * Do NOT access it directly. Use idle_is_disabled() to read it and + * enable_idle()/disable_idle() to write it. + */ +extern uint32_t idle_disabled; + +static inline uint32_t idle_is_disabled(void) +{ + return idle_disabled; +} + +static inline void disable_idle(void) +{ + atomic_or(&idle_disabled, 1); +} + +static inline void enable_idle(void) +{ + atomic_clear(&idle_disabled, 1); +} +#endif + /* The following three functions are not available on all chips. */ /** * Postpone sleeping for at least this long, regardless of sleep_mask. -- cgit v1.2.1