diff --git a/soc/arm/nordic_nrf/nrf51/Kconfig.series b/soc/arm/nordic_nrf/nrf51/Kconfig.series index 4c55832add5..cf7690b1179 100644 --- a/soc/arm/nordic_nrf/nrf51/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf51/Kconfig.series @@ -13,7 +13,8 @@ config SOC_SERIES_NRF51X select NRF_RTC_TIMER select CLOCK_CONTROL select CLOCK_CONTROL_NRF - select SYS_POWER_LOW_POWER_STATE_SUPPORTED + select SYS_POWER_DEEP_SLEEP_SUPPORTED + select SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED select XIP select HAS_CMSIS select HAS_NRFX diff --git a/soc/arm/nordic_nrf/nrf51/power.c b/soc/arm/nordic_nrf/nrf51/power.c index 2e90d68dd38..dc31bab7242 100644 --- a/soc/arm/nordic_nrf/nrf51/power.c +++ b/soc/arm/nordic_nrf/nrf51/power.c @@ -1,11 +1,95 @@ /* - * Copyright (c) 2018 Intel Corporation. + * Copyright (c) 2017 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include +#include +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); + +/* Invoke Low Power/System Off specific Tasks */ +void sys_set_power_state(enum power_states state) +{ + switch (state) { +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED + case SYS_POWER_STATE_DEEP_SLEEP: + nrf_power_system_off(); + break; + #endif +#endif + default: + LOG_ERR("Unsupported power state %u", state); + break; + } +} + +/* Handle SOC specific activity after Low Power Mode Exit */ +void sys_power_state_post_ops(enum power_states state) +{ + switch (state) { +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED + case SYS_POWER_STATE_DEEP_SLEEP: + /* Nothing to do. */ + break; + #endif +#endif + default: + LOG_ERR("Unsupported power state %u", state); + break; + } + + /* + * System is now in active mode. Reenable interrupts which were disabled + * when OS started idling code. + */ + irq_unlock(0); +} + +bool sys_is_valid_power_state(enum power_states state) +{ + switch (state) { +#ifdef CONFIG_SYS_POWER_LOW_POWER_STATE + #ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_SUPPORTED + case SYS_POWER_STATE_CPU_LPS: + return true; + #endif + #ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_1_SUPPORTED + case SYS_POWER_STATE_CPU_LPS_1: + return true; + #endif + #ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_2_SUPPORTED + case SYS_POWER_STATE_CPU_LPS_2: + return true; + #endif +#endif /* CONFIG_SYS_POWER_LOW_POWER_STATE */ + +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED + case SYS_POWER_STATE_DEEP_SLEEP: + return true; + #endif + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_1_SUPPORTED + case SYS_POWER_STATE_DEEP_SLEEP_1: + return true; + #endif + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_2_SUPPORTED + case SYS_POWER_STATE_DEEP_SLEEP_2: + return true; + #endif +#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */ + + default: + return false; + } + + /* Not reached */ +} + /* Overrides the weak ARM implementation: Set general purpose retention register and reboot */ void sys_arch_reboot(int type) diff --git a/soc/arm/nordic_nrf/nrf51/soc.h b/soc/arm/nordic_nrf/nrf51/soc.h index eded6e6f13d..f3efba1f8fb 100644 --- a/soc/arm/nordic_nrf/nrf51/soc.h +++ b/soc/arm/nordic_nrf/nrf51/soc.h @@ -16,6 +16,8 @@ #include #include +#include + /* Add include for DTS generated information */ #include diff --git a/soc/arm/nordic_nrf/nrf51/soc_power.h b/soc/arm/nordic_nrf/nrf51/soc_power.h new file mode 100644 index 00000000000..f254d0a88b2 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf51/soc_power.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_POWER_H_ +#define _SOC_POWER_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum power_states { +#ifdef CONFIG_SYS_POWER_LOW_POWER_STATE +# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_SUPPORTED + SYS_POWER_STATE_CPU_LPS, /* Not used */ +# endif +# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_1_SUPPORTED + SYS_POWER_STATE_CPU_LPS_1, /* Not used */ +# endif +# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_2_SUPPORTED + SYS_POWER_STATE_CPU_LPS_2, /* Not used */ +# endif +#endif /* CONFIG_SYS_POWER_LOW_POWER_STATE */ + +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP +# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED + SYS_POWER_STATE_DEEP_SLEEP, /* System OFF */ +# endif +# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_1_SUPPORTED + SYS_POWER_STATE_DEEP_SLEEP_1, /* Not used */ +# endif +# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_2_SUPPORTED + SYS_POWER_STATE_DEEP_SLEEP_2, /* Not used */ +# endif +#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */ + SYS_POWER_STATE_MAX /* Do nothing */ +}; + +/** + * @brief Put processor into low power state + */ +void sys_set_power_state(enum power_states state); + +/** + * @brief Check the low power state is supported by SoC + */ +bool sys_is_valid_power_state(enum power_states state); + +/** + * @brief Do any SoC or architecture specific post ops after low power states. + */ +void sys_power_state_post_ops(enum power_states state); + +#ifdef __cplusplus +} +#endif + +#endif /* _SOC_POWER_H_ */