power: Move pm subsystem to new power states

Migrate the whole pm subsystem to use new power states information
from power_state.h and get states and residency properties from
device tree.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
Flavio Ceolin 2020-12-07 21:51:46 -08:00 committed by Anas Nashif
commit 579f7049c7
33 changed files with 327 additions and 473 deletions

View file

@ -218,9 +218,9 @@ disable sleep state 2 while polling:
.. code-block:: c .. code-block:: c
pm_ctrl_disable_state(POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
<code that calls uart_poll_in() and expects input at any point in time> <code that calls uart_poll_in() and expects input at any point in time>
pm_ctrl_enable_state(POWER_STATE_SLEEP_2); pm_ctrl_enable_state(PM_STATE_STANDBY);
References References

View file

@ -244,9 +244,9 @@ disable sleep state 2 while polling:
.. code-block:: c .. code-block:: c
pm_ctrl_disable_state(SYS_POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
<code that calls uart_poll_in() and expects input at any point in time> <code that calls uart_poll_in() and expects input at any point in time>
pm_ctrl_enable_state(SYS_POWER_STATE_SLEEP_2); pm_ctrl_enable_state(PM_STATE_STANDBY);
References References

View file

@ -224,9 +224,9 @@ disable sleep state 2 while polling:
.. code-block:: c .. code-block:: c
pm_ctrl_disable_state(POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
<code that calls uart_poll_in() and expects input at any point in time> <code that calls uart_poll_in() and expects input at any point in time>
pm_ctrl_enable_state(POWER_STATE_SLEEP_2); pm_ctrl_enable_state(PM_STATE_STANDBY);
References References

View file

@ -111,7 +111,7 @@ The power management subsystem classifies power states into two categories,
Sleep State and Deep Sleep State, based on whether the CPU loses execution Sleep State and Deep Sleep State, based on whether the CPU loses execution
context during the power state transition. context during the power state transition.
The list of available power states is defined by :code:`enum power_states`. In The list of available power states is defined by :code:`enum pm_state`. In
general power states with higher indexes will offer greater power savings and general power states with higher indexes will offer greater power savings and
have higher wake latencies. have higher wake latencies.
@ -158,7 +158,7 @@ the following function.
.. code-block:: c .. code-block:: c
enum power_states pm_policy_next_state(int32_t ticks); enum pm_state pm_policy_next_state(int32_t ticks);
Dummy Dummy
----- -----

View file

@ -110,7 +110,7 @@ static int entropy_cc13xx_cc26xx_get_entropy(const struct device *dev,
unsigned int key = irq_lock(); unsigned int key = irq_lock();
if (!data->constrained) { if (!data->constrained) {
pm_ctrl_disable_state(POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
data->constrained = true; data->constrained = true;
} }
irq_unlock(key); irq_unlock(key);
@ -157,7 +157,7 @@ static void entropy_cc13xx_cc26xx_isr(const void *arg)
defined(CONFIG_PM_SLEEP_STATES) defined(CONFIG_PM_SLEEP_STATES)
if (data->constrained) { if (data->constrained) {
pm_ctrl_enable_state( pm_ctrl_enable_state(
POWER_STATE_SLEEP_2); PM_STATE_STANDBY);
data->constrained = false; data->constrained = false;
} }
#endif #endif
@ -336,7 +336,7 @@ static int entropy_cc13xx_cc26xx_init(const struct device *dev)
Power_setDependency(PowerCC26XX_PERIPH_TRNG); Power_setDependency(PowerCC26XX_PERIPH_TRNG);
#if defined(CONFIG_PM_SLEEP_STATES) #if defined(CONFIG_PM_SLEEP_STATES)
/* Stay out of standby until buffer is filled with entropy */ /* Stay out of standby until buffer is filled with entropy */
pm_ctrl_disable_state(POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
data->constrained = true; data->constrained = true;
#endif #endif
/* Register notification function */ /* Register notification function */

View file

@ -209,7 +209,7 @@ static int i2c_cc13xx_cc26xx_transfer(const struct device *dev,
#if defined(CONFIG_PM) && \ #if defined(CONFIG_PM) && \
defined(CONFIG_PM_SLEEP_STATES) defined(CONFIG_PM_SLEEP_STATES)
pm_ctrl_disable_state(POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
#endif #endif
for (int i = 0; i < num_msgs; i++) { for (int i = 0; i < num_msgs; i++) {
@ -234,7 +234,7 @@ static int i2c_cc13xx_cc26xx_transfer(const struct device *dev,
#if defined(CONFIG_PM) && \ #if defined(CONFIG_PM) && \
defined(CONFIG_PM_SLEEP_STATES) defined(CONFIG_PM_SLEEP_STATES)
pm_ctrl_enable_state(POWER_STATE_SLEEP_2); pm_ctrl_enable_state(PM_STATE_STANDBY);
#endif #endif
k_sem_give(&get_dev_data(dev)->lock); k_sem_give(&get_dev_data(dev)->lock);

View file

@ -244,7 +244,7 @@ static void uart_cc13xx_cc26xx_irq_tx_enable(const struct device *dev)
* standby mode instead, since it is the power state that * standby mode instead, since it is the power state that
* would interfere with a transfer. * would interfere with a transfer.
*/ */
pm_ctrl_disable_state(POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
get_dev_data(dev)->tx_constrained = true; get_dev_data(dev)->tx_constrained = true;
} }
#endif #endif
@ -259,7 +259,7 @@ static void uart_cc13xx_cc26xx_irq_tx_disable(const struct device *dev)
#if defined(CONFIG_PM) && \ #if defined(CONFIG_PM) && \
defined(CONFIG_PM_SLEEP_STATES) defined(CONFIG_PM_SLEEP_STATES)
if (get_dev_data(dev)->tx_constrained) { if (get_dev_data(dev)->tx_constrained) {
pm_ctrl_enable_state(POWER_STATE_SLEEP_2); pm_ctrl_enable_state(PM_STATE_STANDBY);
get_dev_data(dev)->tx_constrained = false; get_dev_data(dev)->tx_constrained = false;
} }
#endif #endif
@ -280,7 +280,7 @@ static void uart_cc13xx_cc26xx_irq_rx_enable(const struct device *dev)
* standby. * standby.
*/ */
if (!get_dev_data(dev)->rx_constrained) { if (!get_dev_data(dev)->rx_constrained) {
pm_ctrl_disable_state(POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
get_dev_data(dev)->rx_constrained = true; get_dev_data(dev)->rx_constrained = true;
} }
#endif #endif
@ -293,7 +293,7 @@ static void uart_cc13xx_cc26xx_irq_rx_disable(const struct device *dev)
#if defined(CONFIG_PM) && \ #if defined(CONFIG_PM) && \
defined(CONFIG_PM_SLEEP_STATES) defined(CONFIG_PM_SLEEP_STATES)
if (get_dev_data(dev)->rx_constrained) { if (get_dev_data(dev)->rx_constrained) {
pm_ctrl_enable_state(POWER_STATE_SLEEP_2); pm_ctrl_enable_state(PM_STATE_STANDBY);
get_dev_data(dev)->rx_constrained = false; get_dev_data(dev)->rx_constrained = false;
} }
#endif #endif

View file

@ -150,7 +150,7 @@ static int spi_cc13xx_cc26xx_transceive(const struct device *dev,
#if defined(CONFIG_PM) && \ #if defined(CONFIG_PM) && \
defined(CONFIG_PM_SLEEP_STATES) defined(CONFIG_PM_SLEEP_STATES)
pm_ctrl_disable_state(POWER_STATE_SLEEP_2); pm_ctrl_disable_state(PM_STATE_STANDBY);
#endif #endif
err = spi_cc13xx_cc26xx_configure(dev, config); err = spi_cc13xx_cc26xx_configure(dev, config);
@ -187,7 +187,7 @@ static int spi_cc13xx_cc26xx_transceive(const struct device *dev,
done: done:
#if defined(CONFIG_PM) && \ #if defined(CONFIG_PM) && \
defined(CONFIG_PM_SLEEP_STATES) defined(CONFIG_PM_SLEEP_STATES)
pm_ctrl_enable_state(POWER_STATE_SLEEP_2); pm_ctrl_enable_state(PM_STATE_STANDBY);
#endif #endif
spi_context_release(ctx, err); spi_context_release(ctx, err);
return err; return err;

View file

@ -22,38 +22,6 @@ extern "C" {
* @} * @}
*/ */
/**
* @brief System power states.
*/
enum power_states {
POWER_STATE_AUTO = (-2),
POWER_STATE_ACTIVE = (-1),
#ifdef CONFIG_PM_SLEEP_STATES
# ifdef CONFIG_HAS_POWER_STATE_SLEEP_1
POWER_STATE_SLEEP_1,
# endif
# ifdef CONFIG_HAS_POWER_STATE_SLEEP_2
POWER_STATE_SLEEP_2,
# endif
# ifdef CONFIG_HAS_POWER_STATE_SLEEP_3
POWER_STATE_SLEEP_3,
# endif
#endif /* CONFIG_PM_SLEEP_STATES */
#ifdef CONFIG_PM_DEEP_SLEEP_STATES
# ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
POWER_STATE_DEEP_SLEEP_1,
# endif
# ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_2
POWER_STATE_DEEP_SLEEP_2,
# endif
# ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_3
POWER_STATE_DEEP_SLEEP_3,
# endif
#endif /* CONFIG_PM_DEEP_SLEEP_STATES */
POWER_STATE_MAX
};
#ifdef CONFIG_PM #ifdef CONFIG_PM
extern unsigned char pm_idle_exit_notify; extern unsigned char pm_idle_exit_notify;
@ -86,12 +54,12 @@ struct pm_notifier {
* Application defined function for doing any target specific operations * Application defined function for doing any target specific operations
* for power state entry. * for power state entry.
*/ */
void (*state_entry)(enum power_states state); void (*state_entry)(enum pm_state state);
/** /**
* Application defined function for doing any target specific operations * Application defined function for doing any target specific operations
* for power state exit. * for power state exit.
*/ */
void (*state_exit)(enum power_states state); void (*state_exit)(enum pm_state state);
}; };
/** /**
@ -99,25 +67,17 @@ struct pm_notifier {
* *
* This function returns true if given power state is a sleep state. * This function returns true if given power state is a sleep state.
*/ */
static inline bool pm_is_sleep_state(enum power_states state) static inline bool pm_is_sleep_state(enum pm_state state)
{ {
bool ret = true; bool ret = true;
switch (state) { switch (state) {
#ifdef CONFIG_PM_SLEEP_STATES case PM_STATE_RUNTIME_IDLE:
# ifdef CONFIG_HAS_POWER_STATE_SLEEP_1 __fallthrough;
case POWER_STATE_SLEEP_1: case PM_STATE_SUSPEND_TO_IDLE:
__fallthrough;
case PM_STATE_STANDBY:
break; break;
# endif
# ifdef CONFIG_HAS_POWER_STATE_SLEEP_2
case POWER_STATE_SLEEP_2:
break;
# endif
# ifdef CONFIG_HAS_POWER_STATE_SLEEP_3
case POWER_STATE_SLEEP_3:
break;
# endif
#endif /* CONFIG_PM_SLEEP_STATES */
default: default:
ret = false; ret = false;
break; break;
@ -131,26 +91,15 @@ static inline bool pm_is_sleep_state(enum power_states state)
* *
* This function returns true if given power state is a deep sleep state. * This function returns true if given power state is a deep sleep state.
*/ */
static inline bool pm_is_deep_sleep_state(enum power_states state) static inline bool pm_is_deep_sleep_state(enum pm_state state)
{ {
bool ret = true; bool ret = true;
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SUSPEND_TO_RAM:
# ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1 __fallthrough;
case POWER_STATE_DEEP_SLEEP_1: case PM_STATE_SUSPEND_TO_DISK:
break; break;
# endif
# ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_2
case POWER_STATE_DEEP_SLEEP_2:
break;
# endif
# ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_3
case POWER_STATE_DEEP_SLEEP_3:
break;
# endif
#endif /* CONFIG_PM_DEEP_SLEEP_STATES */
default: default:
ret = false; ret = false;
break; break;
@ -187,7 +136,7 @@ static inline void pm_idle_exit_notification_disable(void)
* @param state Power state which should be used in the ongoing * @param state Power state which should be used in the ongoing
* suspend operation or POWER_STATE_AUTO. * suspend operation or POWER_STATE_AUTO.
*/ */
void pm_power_state_force(enum power_states state); void pm_power_state_force(enum pm_state state);
/** /**
* @brief Put processor into a power state. * @brief Put processor into a power state.
@ -195,7 +144,7 @@ void pm_power_state_force(enum power_states state);
* This function implements the SoC specific details necessary * This function implements the SoC specific details necessary
* to put the processor into available power states. * to put the processor into available power states.
*/ */
void pm_power_state_set(enum power_states state); void pm_power_state_set(enum pm_state state);
#ifdef CONFIG_PM_DEBUG #ifdef CONFIG_PM_DEBUG
/** /**
@ -218,7 +167,7 @@ void pm_dump_debug_info(void);
* *
* @param [in] state Power state to be disabled. * @param [in] state Power state to be disabled.
*/ */
void pm_ctrl_disable_state(enum power_states state); void pm_ctrl_disable_state(enum pm_state state);
/** /**
* @brief Enable particular power state * @brief Enable particular power state
@ -231,7 +180,7 @@ void pm_ctrl_disable_state(enum power_states state);
* *
* @param [in] state Power state to be enabled. * @param [in] state Power state to be enabled.
*/ */
void pm_ctrl_enable_state(enum power_states state); void pm_ctrl_enable_state(enum pm_state state);
/** /**
* @brief Check if particular power state is enabled * @brief Check if particular power state is enabled
@ -240,7 +189,7 @@ void pm_ctrl_enable_state(enum power_states state);
* *
* @param [in] state Power state. * @param [in] state Power state.
*/ */
bool pm_ctrl_is_state_enabled(enum power_states state); bool pm_ctrl_is_state_enabled(enum pm_state state);
#endif /* CONFIG_PM_STATE_LOCK */ #endif /* CONFIG_PM_STATE_LOCK */
@ -315,7 +264,7 @@ void pm_system_resume(void);
* @return Power state which was entered or POWER_STATE_ACTIVE if SoC was * @return Power state which was entered or POWER_STATE_ACTIVE if SoC was
* kept in the active state. * kept in the active state.
*/ */
enum power_states pm_system_suspend(int32_t ticks); enum pm_state pm_system_suspend(int32_t ticks);
/** /**
* @brief Do any SoC or architecture specific post ops after sleep state exits. * @brief Do any SoC or architecture specific post ops after sleep state exits.
@ -325,7 +274,7 @@ enum power_states pm_system_suspend(int32_t ticks);
* interrupts after resuming from sleep state. In future, the enabling * interrupts after resuming from sleep state. In future, the enabling
* of interrupts may be moved into the kernel. * of interrupts may be moved into the kernel.
*/ */
void pm_power_state_exit_post_ops(enum power_states state); void pm_power_state_exit_post_ops(enum pm_state state);
/** /**
* @brief Register a power management notifier * @brief Register a power management notifier

View file

@ -67,9 +67,9 @@ void __attribute__((weak)) pm_system_resume_from_deep_sleep(void)
* @return N/A * @return N/A
*/ */
#if !SMP_FALLBACK && CONFIG_PM #if !SMP_FALLBACK && CONFIG_PM
static enum power_states pm_save_idle(int32_t ticks) static enum pm_state pm_save_idle(int32_t ticks)
{ {
static enum power_states pm_state = POWER_STATE_ACTIVE; static enum pm_state idle_state = PM_STATE_ACTIVE;
#if (defined(CONFIG_PM_SLEEP_STATES) || \ #if (defined(CONFIG_PM_SLEEP_STATES) || \
defined(CONFIG_PM_DEEP_SLEEP_STATES)) defined(CONFIG_PM_DEEP_SLEEP_STATES))
@ -89,12 +89,12 @@ static enum power_states pm_save_idle(int32_t ticks)
* idle processing re-enables interrupts which is essential for * idle processing re-enables interrupts which is essential for
* the kernel's scheduling logic. * the kernel's scheduling logic.
*/ */
pm_state = pm_system_suspend(ticks); idle_state = pm_system_suspend(ticks);
if (pm_state == POWER_STATE_ACTIVE) { if (idle_state == PM_STATE_ACTIVE) {
pm_idle_exit_notify = 0U; pm_idle_exit_notify = 0U;
} }
#endif #endif
return pm_state; return idle_state;
} }
#endif /* !SMP_FALLBACK */ #endif /* !SMP_FALLBACK */
@ -194,7 +194,7 @@ void idle(void *p1, void *unused2, void *unused3)
/* Check power policy and decide if we are going to sleep or /* Check power policy and decide if we are going to sleep or
* just idle. * just idle.
*/ */
if (pm_save_idle(ticks) == POWER_STATE_ACTIVE) { if (pm_save_idle(ticks) == PM_STATE_ACTIVE) {
k_cpu_idle(); k_cpu_idle();
} }
#else /* CONFIG_PM */ #else /* CONFIG_PM */

View file

@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(pwrmgmt_test);
/* Thread properties */ /* Thread properties */
#define TASK_STACK_SIZE 1024ul #define TASK_STACK_SIZE 1024ul
#define PRIORITY K_PRIO_COOP(5) #define PRIORITY K_PRIO_COOP(5)
/* Sleep time should be lower than CONFIG_PM_MIN_RESIDENCY_SLEEP_1 */ /* Sleep time should be lower than SUSPEND_TO_IDLE residency time */
#define THREAD_A_SLEEP_TIME 100ul #define THREAD_A_SLEEP_TIME 100ul
#define THREAD_B_SLEEP_TIME 1000ul #define THREAD_B_SLEEP_TIME 1000ul
@ -48,6 +48,11 @@ static bool checks_enabled;
/* Track entry/exit to sleep */ /* Track entry/exit to sleep */
struct pm_counter pm_counters[SLP_STATES_SUPPORTED]; struct pm_counter pm_counters[SLP_STATES_SUPPORTED];
static const struct pm_state_info residency_info[] =
PM_STATE_INFO_DT_ITEMS_LIST(DT_NODELABEL(cpu0));
static size_t residency_info_len = PM_STATE_DT_ITEMS_LEN(DT_NODELABEL(cpu0));
/* Instrumentation to measure latency and track entry exit via gpios /* Instrumentation to measure latency and track entry exit via gpios
* *
* In EVB set following jumpers: * In EVB set following jumpers:
@ -85,18 +90,18 @@ static void pm_latency_check(void)
} }
/* Hooks to count entry/exit */ /* Hooks to count entry/exit */
static void notify_pm_state_entry(enum power_states state) static void notify_pm_state_entry(enum pm_state state)
{ {
if (!checks_enabled) { if (!checks_enabled) {
return; return;
} }
switch (state) { switch (state) {
case POWER_STATE_SLEEP_1: case PM_STATE_SUSPEND_TO_IDLE:
GPIO_CTRL_REGS->CTRL_0012 = 0x240ul; GPIO_CTRL_REGS->CTRL_0012 = 0x240ul;
pm_counters[0].entry_cnt++; pm_counters[0].entry_cnt++;
break; break;
case POWER_STATE_DEEP_SLEEP_1: case PM_STATE_SUSPEND_TO_RAM:
GPIO_CTRL_REGS->CTRL_0013 = 0x240ul; GPIO_CTRL_REGS->CTRL_0013 = 0x240ul;
pm_counters[1].entry_cnt++; pm_counters[1].entry_cnt++;
pm_latency_check(); pm_latency_check();
@ -106,18 +111,18 @@ static void notify_pm_state_entry(enum power_states state)
} }
} }
static void notify_pm_state_exit(enum power_states state) static void notify_pm_state_exit(enum pm_state state)
{ {
if (!checks_enabled) { if (!checks_enabled) {
return; return;
} }
switch (state) { switch (state) {
case POWER_STATE_SLEEP_1: case PM_STATE_SUSPEND_TO_IDLE:
GPIO_CTRL_REGS->CTRL_0012 = 0x10240ul; GPIO_CTRL_REGS->CTRL_0012 = 0x10240ul;
pm_counters[0].exit_cnt++; pm_counters[0].exit_cnt++;
break; break;
case POWER_STATE_DEEP_SLEEP_1: case PM_STATE_SUSPEND_TO_RAM:
GPIO_CTRL_REGS->CTRL_0013 = 0x10240ul; GPIO_CTRL_REGS->CTRL_0013 = 0x10240ul;
pm_counters[1].exit_cnt++; pm_counters[1].exit_cnt++;
break; break;
@ -278,7 +283,7 @@ int test_pwr_mgmt_multithread(bool use_logging, uint8_t cycles)
LOG_INF("Suspend..."); LOG_INF("Suspend...");
suspend_all_tasks(); suspend_all_tasks();
LOG_INF("About to enter light sleep"); LOG_INF("About to enter light sleep");
k_msleep(CONFIG_PM_MIN_RESIDENCY_SLEEP_1 + k_msleep((residency_info[0].min_residency_us / 1000U) +
LT_EXTRA_SLP_TIME); LT_EXTRA_SLP_TIME);
k_busy_wait(100); k_busy_wait(100);
@ -298,8 +303,9 @@ int test_pwr_mgmt_multithread(bool use_logging, uint8_t cycles)
/* GPIO toggle to measure latency for deep sleep */ /* GPIO toggle to measure latency for deep sleep */
pm_trigger_marker(); pm_trigger_marker();
k_msleep(CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_1 + k_msleep(
DP_EXTRA_SLP_TIME); (residency_info[residency_info_len - 1].min_residency_us /
1000U) + DP_EXTRA_SLP_TIME);
k_busy_wait(100); k_busy_wait(100);
if (use_logging) { if (use_logging) {
@ -336,7 +342,7 @@ int test_pwr_mgmt_singlethread(bool use_logging, uint8_t cycles)
/* Trigger Light Sleep 1 state. 48MHz PLL stays on */ /* Trigger Light Sleep 1 state. 48MHz PLL stays on */
LOG_INF("About to enter light sleep"); LOG_INF("About to enter light sleep");
k_msleep(CONFIG_PM_MIN_RESIDENCY_SLEEP_1 + k_msleep((residency_info[0].min_residency_us / 1000U) +
LT_EXTRA_SLP_TIME); LT_EXTRA_SLP_TIME);
k_busy_wait(100); k_busy_wait(100);
@ -351,8 +357,9 @@ int test_pwr_mgmt_singlethread(bool use_logging, uint8_t cycles)
/* GPIO toggle to measure latency */ /* GPIO toggle to measure latency */
pm_trigger_marker(); pm_trigger_marker();
k_msleep(CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_1 + k_msleep(
DP_EXTRA_SLP_TIME); (residency_info[residency_info_len - 1].min_residency_us /
1000U) + DP_EXTRA_SLP_TIME);
k_busy_wait(100); k_busy_wait(100);
if (use_logging) { if (use_logging) {

View file

@ -11,10 +11,10 @@
/** @brief Alternates between light and deep sleep cycles. /** @brief Alternates between light and deep sleep cycles.
* *
* For light sleep, the test sleeps in main thread for 500 ms longer than * For light sleep, the test sleeps in main thread for 500 ms longer than
* CONFIG_PM_MIN_RESIDENCY_SLEEP_1. * SUSPEND_TO_IDLE residency.
* *
* Similarly for deep sleep, the test sleeps in the main thread for 500 ms * Similarly for deep sleep, the test sleeps in the main thread for 500 ms
* longer than CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_1. * longer than STANDBY residency.
* *
* @param use_logging test progress will be reported using logging, * @param use_logging test progress will be reported using logging,
* otherwise printk. * otherwise printk.

View file

@ -27,7 +27,7 @@ static int disable_ds_1(const struct device *dev)
{ {
ARG_UNUSED(dev); ARG_UNUSED(dev);
pm_ctrl_disable_state(POWER_STATE_DEEP_SLEEP_1); pm_ctrl_disable_state(PM_STATE_SOFT_OFF);
return 0; return 0;
} }
@ -68,7 +68,7 @@ void main(void)
* controlled delay. Here we need to override that, then * controlled delay. Here we need to override that, then
* force entry to deep sleep on any delay. * force entry to deep sleep on any delay.
*/ */
pm_power_state_force(POWER_STATE_DEEP_SLEEP_1); pm_power_state_force(PM_STATE_SOFT_OFF);
k_sleep(K_MSEC(1)); k_sleep(K_MSEC(1));
printk("ERROR: System off failed\n"); printk("ERROR: System off failed\n");

View file

@ -68,7 +68,7 @@ void main(void)
* controlled delay. Here we need to override that, then * controlled delay. Here we need to override that, then
* force a sleep so that the deep sleep takes effect. * force a sleep so that the deep sleep takes effect.
*/ */
pm_power_state_force(POWER_STATE_DEEP_SLEEP_1); pm_power_state_force(PM_STATE_STANDBY);
k_sleep(K_MSEC(1)); k_sleep(K_MSEC(1));
printk("ERROR: System off failed\n"); printk("ERROR: System off failed\n");

View file

@ -107,37 +107,29 @@ static void z_power_soc_sleep(void)
* For deep sleep pm_system_suspend has executed all the driver * For deep sleep pm_system_suspend has executed all the driver
* power management call backs. * power management call backs.
*/ */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
switch (state) { switch (state) {
#if (defined(CONFIG_PM_SLEEP_STATES)) case PM_STATE_SUSPEND_TO_IDLE:
case POWER_STATE_SLEEP_1:
z_power_soc_sleep(); z_power_soc_sleep();
break; break;
#endif case PM_STATE_SUSPEND_TO_RAM:
#if (defined(CONFIG_PM_DEEP_SLEEP_STATES))
case POWER_STATE_DEEP_SLEEP_1:
z_power_soc_deep_sleep(); z_power_soc_deep_sleep();
break; break;
#endif
default: default:
break; break;
} }
} }
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
switch (state) { switch (state) {
#if (defined(CONFIG_PM_SLEEP_STATES)) case PM_STATE_SUSPEND_TO_IDLE:
case POWER_STATE_SLEEP_1:
__enable_irq(); __enable_irq();
break; break;
#endif case PM_STATE_SUSPEND_TO_RAM:
#if (defined(CONFIG_PM_DEEP_SLEEP_STATES))
case POWER_STATE_DEEP_SLEEP_1:
__enable_irq(); __enable_irq();
break; break;
#endif
default: default:
break; break;
} }

View file

@ -11,16 +11,12 @@
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
/* Invoke Low Power/System Off specific Tasks */ /* Invoke Low Power/System Off specific Tasks */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SOFT_OFF:
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
case POWER_STATE_DEEP_SLEEP_1:
nrf_power_system_off(NRF_POWER); nrf_power_system_off(NRF_POWER);
break; break;
#endif
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;
@ -28,16 +24,12 @@ void pm_power_state_set(enum power_states state)
} }
/* Handle SOC specific activity after Low Power Mode Exit */ /* Handle SOC specific activity after Low Power Mode Exit */
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SOFT_OFF:
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
case POWER_STATE_DEEP_SLEEP_1:
/* Nothing to do. */ /* Nothing to do. */
break; break;
#endif
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;

View file

@ -11,16 +11,12 @@
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
/* Invoke Low Power/System Off specific Tasks */ /* Invoke Low Power/System Off specific Tasks */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SOFT_OFF:
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
case POWER_STATE_DEEP_SLEEP_1:
nrf_power_system_off(NRF_POWER); nrf_power_system_off(NRF_POWER);
break; break;
#endif
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;
@ -28,16 +24,12 @@ void pm_power_state_set(enum power_states state)
} }
/* Handle SOC specific activity after Low Power Mode Exit */ /* Handle SOC specific activity after Low Power Mode Exit */
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SOFT_OFF:
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
case POWER_STATE_DEEP_SLEEP_1:
/* Nothing to do. */ /* Nothing to do. */
break; break;
#endif
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;

View file

@ -7,24 +7,18 @@
#include <zephyr.h> #include <zephyr.h>
#include <power/power.h> #include <power/power.h>
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
#include <hal/nrf_regulators.h> #include <hal/nrf_regulators.h>
#endif
#include <logging/log.h> #include <logging/log.h>
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
/* Invoke Low Power/System Off specific Tasks */ /* Invoke Low Power/System Off specific Tasks */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SOFT_OFF:
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
case POWER_STATE_DEEP_SLEEP_1:
nrf_regulators_system_off(NRF_REGULATORS); nrf_regulators_system_off(NRF_REGULATORS);
break; break;
#endif
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;
@ -32,16 +26,12 @@ void pm_power_state_set(enum power_states state)
} }
/* Handle SOC specific activity after Low Power Mode Exit */ /* Handle SOC specific activity after Low Power Mode Exit */
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SOFT_OFF:
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
case POWER_STATE_DEEP_SLEEP_1:
/* Nothing to do. */ /* Nothing to do. */
break; break;
#endif
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;

View file

@ -12,16 +12,12 @@
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
/* Invoke Low Power/System Off specific Tasks */ /* Invoke Low Power/System Off specific Tasks */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SOFT_OFF:
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
case POWER_STATE_DEEP_SLEEP_1:
nrf_regulators_system_off(NRF_REGULATORS); nrf_regulators_system_off(NRF_REGULATORS);
break; break;
#endif
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;
@ -29,16 +25,12 @@ void pm_power_state_set(enum power_states state)
} }
/* Handle SOC specific activity after Low Power Mode Exit */ /* Handle SOC specific activity after Low Power Mode Exit */
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SOFT_OFF:
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
case POWER_STATE_DEEP_SLEEP_1:
/* Nothing to do. */ /* Nothing to do. */
break; break;
#endif
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;

View file

@ -12,13 +12,13 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
/* /*
* Power state map: * Power state map:
* POWER_STATE_SLEEP_1: EM1 Sleep * PM_STATE_RUNTIME_IDLE: EM1 Sleep
* POWER_STATE_SLEEP_2: EM2 Deep Sleep * PM_STATE_SUSPEND_TO_IDLE: EM2 Deep Sleep
* POWER_STATE_SLEEP_3: EM3 Stop * PM_STATE_STANDBY: EM3 Stop
*/ */
/* Invoke Low Power/System Off specific Tasks */ /* Invoke Low Power/System Off specific Tasks */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
LOG_DBG("SoC entering power state %d", state); LOG_DBG("SoC entering power state %d", state);
@ -35,23 +35,15 @@ void pm_power_state_set(enum power_states state)
irq_unlock(0); irq_unlock(0);
switch (state) { switch (state) {
#ifdef CONFIG_PM_SLEEP_STATES case PM_STATE_RUNTIME_IDLE:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_1
case POWER_STATE_SLEEP_1:
EMU_EnterEM1(); EMU_EnterEM1();
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_1 */ case PM_STATE_SUSPEND_TO_IDLE:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_2
case POWER_STATE_SLEEP_2:
EMU_EnterEM2(true); EMU_EnterEM2(true);
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_2 */ case PM_STATE_STANDBY:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_3
case POWER_STATE_SLEEP_3:
EMU_EnterEM3(true); EMU_EnterEM3(true);
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_3 */
#endif /* CONFIG_PM_SLEEP_STATES */
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;
@ -64,7 +56,7 @@ void pm_power_state_set(enum power_states state)
} }
/* Handle SOC specific activity after Low Power Mode Exit */ /* Handle SOC specific activity after Low Power Mode Exit */
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
ARG_UNUSED(state); ARG_UNUSED(state);
} }

View file

@ -17,12 +17,10 @@
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
/* Invoke Low Power/System Off specific Tasks */ /* Invoke Low Power/System Off specific Tasks */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_SLEEP_STATES case PM_STATE_RUNTIME_IDLE:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_1
case POWER_STATE_SLEEP_1:
/* this corresponds to the STOP0 mode: */ /* this corresponds to the STOP0 mode: */
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
@ -37,9 +35,7 @@ void pm_power_state_set(enum power_states state)
/* enter SLEEP mode : WFE or WFI */ /* enter SLEEP mode : WFE or WFI */
k_cpu_idle(); k_cpu_idle();
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_1 */ case PM_STATE_SUSPEND_TO_IDLE:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_2
case POWER_STATE_SLEEP_2:
/* this corresponds to the STOP1 mode: */ /* this corresponds to the STOP1 mode: */
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
/* Enable the Debug Module during STOP mode */ /* Enable the Debug Module during STOP mode */
@ -52,9 +48,7 @@ void pm_power_state_set(enum power_states state)
LL_LPM_EnableDeepSleep(); LL_LPM_EnableDeepSleep();
k_cpu_idle(); k_cpu_idle();
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_2 */ case PM_STATE_STANDBY:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_3
case POWER_STATE_SLEEP_3:
/* this corresponds to the STOP2 mode: */ /* this corresponds to the STOP2 mode: */
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
/* Enable the Debug Module during STOP mode */ /* Enable the Debug Module during STOP mode */
@ -70,8 +64,6 @@ void pm_power_state_set(enum power_states state)
LL_LPM_EnableDeepSleep(); LL_LPM_EnableDeepSleep();
k_cpu_idle(); k_cpu_idle();
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_3 */
#endif /* CONFIG_PM_SLEEP_STATES */
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;
@ -79,23 +71,17 @@ void pm_power_state_set(enum power_states state)
} }
/* Handle SOC specific activity after Low Power Mode Exit */ /* Handle SOC specific activity after Low Power Mode Exit */
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_SLEEP_STATES case PM_STATE_RUNTIME_IDLE:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_1 __fallthrough;
case POWER_STATE_SLEEP_1: case PM_STATE_SUSPEND_TO_IDLE:
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_1 */ __fallthrough;
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_2 case PM_STATE_STANDBY:
case POWER_STATE_SLEEP_2:
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_2 */
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_3
case POWER_STATE_SLEEP_3:
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_3 */
LL_LPM_DisableSleepOnExit(); LL_LPM_DisableSleepOnExit();
LL_LPM_EnableSleep(); LL_LPM_EnableSleep();
break; break;
#endif /* CONFIG_PM_SLEEP_STATES */
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;

View file

@ -17,12 +17,10 @@
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
/* Invoke Low Power/System Off specific Tasks */ /* Invoke Low Power/System Off specific Tasks */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_SLEEP_STATES case PM_STATE_RUNTIME_IDLE:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_1
case POWER_STATE_SLEEP_1:
/* this corresponds to the STOP0 mode: */ /* this corresponds to the STOP0 mode: */
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
@ -37,9 +35,7 @@ void pm_power_state_set(enum power_states state)
/* enter SLEEP mode : WFE or WFI */ /* enter SLEEP mode : WFE or WFI */
k_cpu_idle(); k_cpu_idle();
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_1 */ case PM_STATE_SUSPEND_TO_IDLE:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_2
case POWER_STATE_SLEEP_2:
/* this corresponds to the STOP1 mode: */ /* this corresponds to the STOP1 mode: */
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
/* Enable the Debug Module during STOP mode */ /* Enable the Debug Module during STOP mode */
@ -52,9 +48,7 @@ void pm_power_state_set(enum power_states state)
LL_LPM_EnableDeepSleep(); LL_LPM_EnableDeepSleep();
k_cpu_idle(); k_cpu_idle();
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_2 */ case PM_STATE_STANDBY:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_3
case POWER_STATE_SLEEP_3:
/* this corresponds to the STOP2 mode: */ /* this corresponds to the STOP2 mode: */
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
/* Enable the Debug Module during STOP mode */ /* Enable the Debug Module during STOP mode */
@ -70,8 +64,6 @@ void pm_power_state_set(enum power_states state)
LL_LPM_EnableDeepSleep(); LL_LPM_EnableDeepSleep();
k_cpu_idle(); k_cpu_idle();
break; break;
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_3 */
#endif /* CONFIG_PM_SLEEP_STATES */
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;
@ -79,23 +71,17 @@ void pm_power_state_set(enum power_states state)
} }
/* Handle SOC specific activity after Low Power Mode Exit */ /* Handle SOC specific activity after Low Power Mode Exit */
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
switch (state) { switch (state) {
#ifdef CONFIG_PM_SLEEP_STATES case PM_STATE_RUNTIME_IDLE:
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_1 __fallthrough;
case POWER_STATE_SLEEP_1: case PM_STATE_SUSPEND_TO_IDLE:
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_1 */ __fallthrough;
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_2 case PM_STATE_STANDBY:
case POWER_STATE_SLEEP_2:
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_2 */
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_3
case POWER_STATE_SLEEP_3:
#endif /* CONFIG_HAS_POWER_STATE_SLEEP_3 */
LL_LPM_DisableSleepOnExit(); LL_LPM_DisableSleepOnExit();
LL_LPM_EnableSleep(); LL_LPM_EnableSleep();
break; break;
#endif /* CONFIG_PM_SLEEP_STATES */
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;

View file

@ -50,13 +50,13 @@ extern PowerCC26X2_ModuleState PowerCC26X2_module;
/* /*
* Power state mapping: * Power state mapping:
* POWER_STATE_SLEEP_1: Idle * PM_STATE_SUSPEND_TO_IDLE: Idle
* POWER_STATE_SLEEP_2: Standby * PM_STATE_STANDBY: Standby
* POWER_STATE_DEEP_SLEEP_1: Shutdown * PM_STATE_SUSPEND_TO_RAM | PM_STATE_SUSPEND_TO_DISK: Shutdown
*/ */
/* Invoke Low Power/System Off specific Tasks */ /* Invoke Low Power/System Off specific Tasks */
void pm_power_state_set(enum power_states state) void pm_power_state_set(enum pm_state state)
{ {
#ifdef CONFIG_PM_SLEEP_STATES #ifdef CONFIG_PM_SLEEP_STATES
uint32_t modeVIMS; uint32_t modeVIMS;
@ -74,8 +74,7 @@ void pm_power_state_set(enum power_states state)
irq_unlock(0); irq_unlock(0);
switch (state) { switch (state) {
#ifdef CONFIG_PM_SLEEP_STATES case PM_STATE_SUSPEND_TO_IDLE:
case POWER_STATE_SLEEP_1:
/* query the declared constraints */ /* query the declared constraints */
constraints = Power_getConstraintMask(); constraints = Power_getConstraintMask();
/* 1. Get the current VIMS mode */ /* 1. Get the current VIMS mode */
@ -101,7 +100,7 @@ void pm_power_state_set(enum power_states state)
SysCtrlAonUpdate(); SysCtrlAonUpdate();
break; break;
case POWER_STATE_SLEEP_2: case PM_STATE_STANDBY:
/* schedule the wakeup event */ /* schedule the wakeup event */
ClockP_start(ClockP_handle((ClockP_Struct *) ClockP_start(ClockP_handle((ClockP_Struct *)
&PowerCC26X2_module.clockObj)); &PowerCC26X2_module.clockObj));
@ -111,13 +110,11 @@ void pm_power_state_set(enum power_states state)
ClockP_stop(ClockP_handle((ClockP_Struct *) ClockP_stop(ClockP_handle((ClockP_Struct *)
&PowerCC26X2_module.clockObj)); &PowerCC26X2_module.clockObj));
break; break;
#endif case PM_STATE_SUSPEND_TO_RAM:
__fallthrough;
#ifdef CONFIG_PM_DEEP_SLEEP_STATES case PM_STATE_SUSPEND_TO_DISK:
case POWER_STATE_DEEP_SLEEP_1:
Power_shutdown(0, 0); Power_shutdown(0, 0);
break; break;
#endif
default: default:
LOG_DBG("Unsupported power state %u", state); LOG_DBG("Unsupported power state %u", state);
break; break;
@ -127,7 +124,7 @@ void pm_power_state_set(enum power_states state)
} }
/* Handle SOC specific activity after Low Power Mode Exit */ /* Handle SOC specific activity after Low Power Mode Exit */
void pm_power_state_exit_post_ops(enum power_states state) void pm_power_state_exit_post_ops(enum pm_state state)
{ {
/* /*
* System is now in active mode. Reenable interrupts which were disabled * System is now in active mode. Reenable interrupts which were disabled

View file

@ -8,19 +8,22 @@
#include <string.h> #include <string.h>
#include <device.h> #include <device.h>
#include <sys/atomic.h> #include <sys/atomic.h>
#include <power/power_state.h>
#include "policy/pm_policy.h" #include "policy/pm_policy.h"
#define LOG_LEVEL CONFIG_PM_LOG_LEVEL /* From power module Kconfig */ #define LOG_LEVEL CONFIG_PM_LOG_LEVEL /* From power module Kconfig */
#include <logging/log.h> #include <logging/log.h>
LOG_MODULE_DECLARE(power); LOG_MODULE_DECLARE(power);
static atomic_t power_state_disable_count[POWER_STATE_MAX]; #define PM_STATES_LEN (PM_STATE_SOFT_OFF - PM_STATE_ACTIVE)
void pm_ctrl_disable_state(enum power_states state) static atomic_t power_state_disable_count[PM_STATES_LEN];
void pm_ctrl_disable_state(enum pm_state state)
{ {
atomic_val_t v; atomic_val_t v;
__ASSERT(state < POWER_STATE_MAX, "Invalid power state!"); __ASSERT(state < PM_STATES_LEN, "Invalid power state!");
v = atomic_inc(&power_state_disable_count[state]); v = atomic_inc(&power_state_disable_count[state]);
__ASSERT(v < UINT_MAX, "Power state disable count overflowed!"); __ASSERT(v < UINT_MAX, "Power state disable count overflowed!");
@ -28,11 +31,11 @@ void pm_ctrl_disable_state(enum power_states state)
(void)(v); (void)(v);
} }
void pm_ctrl_enable_state(enum power_states state) void pm_ctrl_enable_state(enum pm_state state)
{ {
atomic_val_t v; atomic_val_t v;
__ASSERT(state < POWER_STATE_MAX, "Invalid power state!"); __ASSERT(state < PM_STATES_LEN, "Invalid power state!");
v = atomic_dec(&power_state_disable_count[state]); v = atomic_dec(&power_state_disable_count[state]);
__ASSERT(v > 0, "Power state disable count underflowed!"); __ASSERT(v > 0, "Power state disable count underflowed!");
@ -40,9 +43,9 @@ void pm_ctrl_enable_state(enum power_states state)
(void)(v); (void)(v);
} }
bool pm_ctrl_is_state_enabled(enum power_states state) bool pm_ctrl_is_state_enabled(enum pm_state state)
{ {
__ASSERT(state < POWER_STATE_MAX, "Invalid power state!"); __ASSERT(state < PM_STATES_LEN, "Invalid power state!");
return (atomic_get(&power_state_disable_count[state]) == 0); return (atomic_get(&power_state_disable_count[state]) == 0);
} }

View file

@ -41,13 +41,13 @@ void pm_resume_devices(void);
/** /**
* @brief Function to get the next PM state based on the ticks * @brief Function to get the next PM state based on the ticks
*/ */
enum power_states pm_policy_next_state(int32_t ticks); enum pm_state pm_policy_next_state(int32_t ticks);
/** /**
* @brief Function to determine whether to put devices in low * @brief Function to determine whether to put devices in low
* power state, given the system PM state. * power state, given the system PM state.
*/ */
bool pm_policy_low_power_devices(enum power_states pm_state); bool pm_policy_low_power_devices(enum pm_state state);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -6,40 +6,45 @@
#include <zephyr.h> #include <zephyr.h>
#include <kernel.h> #include <kernel.h>
#include <power/power_state.h>
#include "pm_policy.h" #include "pm_policy.h"
#include <logging/log.h> #include <logging/log.h>
LOG_MODULE_DECLARE(power, CONFIG_PM_LOG_LEVEL); LOG_MODULE_DECLARE(power, CONFIG_PM_LOG_LEVEL);
enum power_states pm_policy_next_state(int32_t ticks) static const struct pm_state_info pm_dummy_states[] =
{ PM_STATE_DT_ITEMS_LIST(DT_NODELABEL(cpu0));
static uint8_t cur_power_state;
int i = cur_power_state;
if (POWER_STATE_MAX == 0) { enum pm_state pm_policy_next_state(int32_t ticks)
{
static enum pm_state cur_power_state;
int i = (int)cur_power_state;
uint8_t states_len = ARRAY_SIZE(pm_dummy_states);
if (states_len == 0) {
/* No power states to go through. */ /* No power states to go through. */
return POWER_STATE_ACTIVE; return PM_STATE_ACTIVE;
} }
do { do {
i = (i + 1) % POWER_STATE_MAX; i = (i + 1) % states_len;
#ifdef CONFIG_PM_STATE_LOCK #ifdef CONFIG_PM_STATE_LOCK
if (!pm_ctrl_is_state_enabled((enum power_states)(i))) { if (!pm_ctrl_is_state_enabled(pm_dummy_states[i].state)) {
continue; continue;
} }
#endif #endif
cur_power_state = i; cur_power_state = pm_dummy_states[i].state;
LOG_DBG("Selected power state: %u", i); LOG_DBG("Selected power state: %u", pm_dummy_states[i].state);
return (enum power_states)(i); return pm_dummy_states[i].state;
} while (i != cur_power_state); } while (pm_dummy_states[i].state != cur_power_state);
LOG_DBG("No suitable power state found!"); LOG_DBG("No suitable power state found!");
return POWER_STATE_ACTIVE; return PM_STATE_ACTIVE;
} }
__weak bool pm_policy_low_power_devices(enum power_states pm_state) __weak bool pm_policy_low_power_devices(enum pm_state state)
{ {
return pm_is_sleep_state(pm_state); return pm_is_sleep_state(state);
} }

View file

@ -12,68 +12,35 @@
#include <logging/log.h> #include <logging/log.h>
LOG_MODULE_DECLARE(power); LOG_MODULE_DECLARE(power);
#define SECS_TO_TICKS CONFIG_SYS_CLOCK_TICKS_PER_SEC static const struct pm_state_info pm_min_residency[] =
PM_STATE_INFO_DT_ITEMS_LIST(DT_NODELABEL(cpu0));
/* PM Policy based on SoC/Platform residency requirements */ enum pm_state pm_policy_next_state(int32_t ticks)
static const unsigned int pm_min_residency[] = {
#ifdef CONFIG_PM_SLEEP_STATES
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_1
CONFIG_PM_MIN_RESIDENCY_SLEEP_1 * SECS_TO_TICKS / MSEC_PER_SEC,
#endif
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_2
CONFIG_PM_MIN_RESIDENCY_SLEEP_2 * SECS_TO_TICKS / MSEC_PER_SEC,
#endif
#ifdef CONFIG_HAS_POWER_STATE_SLEEP_3
CONFIG_PM_MIN_RESIDENCY_SLEEP_3 * SECS_TO_TICKS / MSEC_PER_SEC,
#endif
#endif /* CONFIG_PM_SLEEP_STATES */
#ifdef CONFIG_PM_DEEP_SLEEP_STATES
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_1
CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_1 * SECS_TO_TICKS / MSEC_PER_SEC,
#endif
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_2
CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_2 * SECS_TO_TICKS / MSEC_PER_SEC,
#endif
#ifdef CONFIG_HAS_POWER_STATE_DEEP_SLEEP_3
CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_3 * SECS_TO_TICKS / MSEC_PER_SEC,
#endif
#endif /* CONFIG_PM_DEEP_SLEEP_STATES */
};
enum power_states pm_policy_next_state(int32_t ticks)
{ {
int i; int i;
if ((ticks != K_TICKS_FOREVER) && (ticks < pm_min_residency[0])) {
LOG_DBG("Not enough time for PM operations: %d", ticks);
return POWER_STATE_ACTIVE;
}
for (i = ARRAY_SIZE(pm_min_residency) - 1; i >= 0; i--) { for (i = ARRAY_SIZE(pm_min_residency) - 1; i >= 0; i--) {
#ifdef CONFIG_PM_STATE_LOCK #ifdef CONFIG_PM_STATE_LOCK
if (!pm_ctrl_is_state_enabled((enum power_states)(i))) { if (!pm_ctrl_is_state_enabled(pm_min_residency[i].state)) {
continue; continue;
} }
#endif #endif
if ((ticks == K_TICKS_FOREVER) || if ((ticks == K_TICKS_FOREVER) ||
(ticks >= pm_min_residency[i])) { (ticks >= k_us_to_ticks_ceil32(
pm_min_residency[i].min_residency_us))) {
LOG_DBG("Selected power state %d " LOG_DBG("Selected power state %d "
"(ticks: %d, min_residency: %u)", "(ticks: %d, min_residency: %u)",
i, ticks, pm_min_residency[i]); pm_min_residency[i].state, ticks,
return (enum power_states)(i); pm_min_residency[i].min_residency_us);
return pm_min_residency[i].state;
} }
} }
LOG_DBG("No suitable power state found!"); LOG_DBG("No suitable power state found!");
return POWER_STATE_ACTIVE; return PM_STATE_ACTIVE;
} }
__weak bool pm_policy_low_power_devices(enum power_states pm_state) __weak bool pm_policy_low_power_devices(enum pm_state state)
{ {
return pm_is_sleep_state(pm_state); return pm_is_sleep_state(state);
} }

View file

@ -22,22 +22,16 @@
#include <logging/log.h> #include <logging/log.h>
LOG_MODULE_DECLARE(power); LOG_MODULE_DECLARE(power);
#define SECS_TO_TICKS CONFIG_SYS_CLOCK_TICKS_PER_SEC
/* Wakeup delay from standby in microseconds */ /* Wakeup delay from standby in microseconds */
#define WAKEDELAYSTANDBY 240 #define WAKEDELAYSTANDBY 240
extern PowerCC26X2_ModuleState PowerCC26X2_module; extern PowerCC26X2_ModuleState PowerCC26X2_module;
/* PM Policy based on SoC/Platform residency requirements */ /* PM Policy based on SoC/Platform residency requirements */
static const unsigned int pm_min_residency[] = { static const struct pm_state_info residency_info[] =
#ifdef CONFIG_PM_SLEEP_STATES PM_STATE_INFO_DT_ITEMS_LIST(DT_NODELABEL(cpu0));
CONFIG_PM_MIN_RESIDENCY_SLEEP_1 * SECS_TO_TICKS / MSEC_PER_SEC,
CONFIG_PM_MIN_RESIDENCY_SLEEP_2 * SECS_TO_TICKS / MSEC_PER_SEC,
#endif /* CONFIG_PM_SLEEP_STATES */
};
enum power_states pm_policy_next_state(int32_t ticks) enum pm_state pm_policy_next_state(int32_t ticks)
{ {
uint32_t constraints; uint32_t constraints;
bool disallowed = false; bool disallowed = false;
@ -49,97 +43,98 @@ enum power_states pm_policy_next_state(int32_t ticks)
/* query the declared constraints */ /* query the declared constraints */
constraints = Power_getConstraintMask(); constraints = Power_getConstraintMask();
if ((ticks != K_TICKS_FOREVER) && (ticks < pm_min_residency[0])) { if ((ticks != K_TICKS_FOREVER) && (ticks <
k_us_to_ticks_ceil32(residency_info[0].min_residency_us))) {
LOG_DBG("Not enough time for PM operations: %d", ticks); LOG_DBG("Not enough time for PM operations: %d", ticks);
return POWER_STATE_ACTIVE; return PM_STATE_ACTIVE;
} }
for (i = ARRAY_SIZE(pm_min_residency) - 1; i >= 0; i--) { for (i = ARRAY_SIZE(residency_info) - 1; i >= 0; i--) {
#ifdef CONFIG_PM_STATE_LOCK #ifdef CONFIG_PM_STATE_LOCK
if (!pm_ctrl_is_state_enabled((enum power_states)(i))) { if (!pm_ctrl_is_state_enabled(residency_info[i].state)) {
continue; continue;
} }
#endif #endif
if ((ticks == K_TICKS_FOREVER) || if ((ticks <
(ticks >= pm_min_residency[i])) { k_us_to_ticks_ceil32(residency_info[i].min_residency_us))
/* Verify if Power module has constraints set to && (ticks != K_TICKS_FOREVER)) {
* disallow a state continue;
*/ }
switch (i) {
case 0: /* Idle mode */ /* Verify if Power module has constraints set to
if ((constraints & (1 << * disallow a state
PowerCC26XX_DISALLOW_IDLE)) != 0) { */
disallowed = true; switch (residency_info[i].state) {
} case PM_STATE_SUSPEND_TO_IDLE: /* Idle mode */
break; if ((constraints & (1 <<
case 1: /* Standby mode */ PowerCC26XX_DISALLOW_IDLE)) != 0) {
if ((constraints & (1 << disallowed = true;
PowerCC26XX_DISALLOW_STANDBY)) != 0) { }
disallowed = true; break;
} case PM_STATE_STANDBY: /* Standby mode */
/* Set timeout for wakeup event */ if ((constraints & (1 <<
__ASSERT( PowerCC26XX_DISALLOW_STANDBY)) != 0) {
CONFIG_PM_MIN_RESIDENCY_SLEEP_2 > 1, disallowed = true;
"CONFIG_PM_MIN_RESIDENCY_SLEEP_2 must " }
"be greater than 1."); /* Set timeout for wakeup event */
if (ticks != K_TICKS_FOREVER) { __ASSERT(
/* NOTE: Ideally we'd like to set a residency_info[i].min_residency_us > 1000,
* timer to wake up just a little "PM_STATE_STANDBY must be greater than 1000.");
* earlier to take care of the wakeup if (ticks != K_TICKS_FOREVER) {
* sequence, ie. by WAKEDELAYSTANDBY /* NOTE: Ideally we'd like to set a
* microsecs. However, given * timer to wake up just a little
* k_timer_start (called later by * earlier to take care of the wakeup
* ClockP_start) does not currently * sequence, ie. by WAKEDELAYSTANDBY
* have sub-millisecond accuracy, wakeup * microsecs. However, given
* would be at up to (WAKEDELAYSTANDBY * k_timer_start (called later by
* + 1 ms) ahead of the next timeout. * ClockP_start) does not currently
* This also has the implication that * have sub-millisecond accuracy, wakeup
* PM_MIN_RESIDENCY_SLEEP_2 * would be at up to (WAKEDELAYSTANDBY
* must be greater than 1. * + 1 ms) ahead of the next timeout.
*/ * This also has the implication that
ticks -= (WAKEDELAYSTANDBY * * PM_STATE_STANDBY
CONFIG_SYS_CLOCK_TICKS_PER_SEC * must be greater than 1.
+ 1000000) / 1000000; */
ticks -= (WAKEDELAYSTANDBY *
CONFIG_SYS_CLOCK_TICKS_PER_SEC
+ 1000000) / 1000000;
#if (CONFIG_SYS_CLOCK_TICKS_PER_SEC <= 1000) #if (CONFIG_SYS_CLOCK_TICKS_PER_SEC <= 1000)
/* /*
* ClockP_setTimeout cannot handle any * ClockP_setTimeout cannot handle any
* more ticks * more ticks
*/ */
ticks = MIN(ticks, UINT32_MAX / 1000 * ticks = MIN(ticks, UINT32_MAX / 1000 *
CONFIG_SYS_CLOCK_TICKS_PER_SEC); CONFIG_SYS_CLOCK_TICKS_PER_SEC);
#endif #endif
ClockP_setTimeout(ClockP_handle( ClockP_setTimeout(ClockP_handle(
(ClockP_Struct *) (ClockP_Struct *)
&PowerCC26X2_module.clockObj), &PowerCC26X2_module.clockObj),
ticks); ticks);
}
break;
default:
/* This should never be reached */
LOG_ERR("Invalid sleep state detected\n");
} }
break;
if (disallowed) { default:
disallowed = false; /* This should never be reached */
continue; LOG_ERR("Invalid sleep state detected\n");
}
LOG_DBG("Selected power state %d "
"(ticks: %d, min_residency: %u)",
i, ticks, pm_min_residency[i]);
return (enum power_states)(i);
} }
if (disallowed) {
disallowed = false;
continue;
}
LOG_DBG("Selected power state %d "
"(ticks: %d, min_residency: %u)",
residency_info[i].state, ticks,
k_us_to_ticks_ceil32(
residency_info[i].min_residency_us));
return residency_info[i].state;
} }
LOG_DBG("No suitable power state found!"); LOG_DBG("No suitable power state found!");
return POWER_STATE_ACTIVE; return PM_STATE_ACTIVE;
} }
__weak bool pm_policy_low_power_devices(enum power_states pm_state) __weak bool pm_policy_low_power_devices(enum pm_state state)
{ {
#ifdef CONFIG_PM_SLEEP_STATES return state == PM_STATE_STANDBY;
return (pm_state == POWER_STATE_SLEEP_2);
#else
return false;
#endif
} }

View file

@ -9,15 +9,17 @@
#include <init.h> #include <init.h>
#include <string.h> #include <string.h>
#include <power/power.h> #include <power/power.h>
#include <power/power_state.h>
#include "policy/pm_policy.h" #include "policy/pm_policy.h"
#define PM_STATES_LEN (PM_STATE_SOFT_OFF - PM_STATE_ACTIVE)
#define LOG_LEVEL CONFIG_PM_LOG_LEVEL #define LOG_LEVEL CONFIG_PM_LOG_LEVEL
#include <logging/log.h> #include <logging/log.h>
LOG_MODULE_REGISTER(power); LOG_MODULE_REGISTER(power);
static int post_ops_done = 1; static int post_ops_done = 1;
static enum power_states forced_pm_state = POWER_STATE_AUTO; static bool z_forced_power_state;
static enum power_states pm_state; static enum pm_state z_power_state;
static sys_slist_t pm_notifiers = SYS_SLIST_STATIC_INIT(&pm_notifiers); static sys_slist_t pm_notifiers = SYS_SLIST_STATIC_INIT(&pm_notifiers);
static struct k_spinlock pm_notifier_lock; static struct k_spinlock pm_notifier_lock;
@ -29,7 +31,7 @@ struct pm_debug_info {
uint32_t total_res; uint32_t total_res;
}; };
static struct pm_debug_info pm_dbg_info[POWER_STATE_MAX]; static struct pm_debug_info pm_dbg_info[PM_STATES_LEN];
static uint32_t timer_start, timer_end; static uint32_t timer_start, timer_end;
static inline void pm_debug_start_timer(void) static inline void pm_debug_start_timer(void)
@ -42,7 +44,7 @@ static inline void pm_debug_stop_timer(void)
timer_end = k_cycle_get_32(); timer_end = k_cycle_get_32();
} }
static void pm_log_debug_info(enum power_states state) static void pm_log_debug_info(enum pm_state state)
{ {
uint32_t res = timer_end - timer_start; uint32_t res = timer_end - timer_start;
@ -53,7 +55,7 @@ static void pm_log_debug_info(enum power_states state)
void pm_dump_debug_info(void) void pm_dump_debug_info(void)
{ {
for (int i = 0; i < POWER_STATE_MAX; i++) { for (int i = 0; i < PM_STATES_LEN; i++) {
LOG_DBG("PM:state = %d, count = %d last_res = %d, " LOG_DBG("PM:state = %d, count = %d last_res = %d, "
"total_res = %d\n", i, pm_dbg_info[i].count, "total_res = %d\n", i, pm_dbg_info[i].count,
pm_dbg_info[i].last_res, pm_dbg_info[i].total_res); pm_dbg_info[i].last_res, pm_dbg_info[i].total_res);
@ -62,22 +64,23 @@ void pm_dump_debug_info(void)
#else #else
static inline void pm_debug_start_timer(void) { } static inline void pm_debug_start_timer(void) { }
static inline void pm_debug_stop_timer(void) { } static inline void pm_debug_stop_timer(void) { }
static void pm_log_debug_info(enum power_states state) { } static void pm_log_debug_info(enum pm_state state) { }
void pm_dump_debug_info(void) { } void pm_dump_debug_info(void) { }
#endif #endif
void pm_power_state_force(enum power_states state) void pm_power_state_force(enum pm_state state)
{ {
__ASSERT(state >= POWER_STATE_AUTO && __ASSERT(state < PM_STATES_LEN,
state < POWER_STATE_MAX,
"Invalid power state %d!", state); "Invalid power state %d!", state);
#ifdef CONFIG_PM_DIRECT_FORCE_MODE #ifdef CONFIG_PM_DIRECT_FORCE_MODE
(void)arch_irq_lock(); (void)arch_irq_lock();
forced_pm_state = state; z_forced_power_state = true;
z_power_state = state;
pm_system_suspend(K_TICKS_FOREVER); pm_system_suspend(K_TICKS_FOREVER);
#else #else
forced_pm_state = state; z_power_state = state;
z_forced_power_state = true;
#endif #endif
} }
@ -89,7 +92,7 @@ static inline void pm_state_notify(bool entering_state)
{ {
struct pm_notifier *notifier; struct pm_notifier *notifier;
k_spinlock_key_t pm_notifier_key; k_spinlock_key_t pm_notifier_key;
void (*callback)(enum power_states state); void (*callback)(enum pm_state state);
pm_notifier_key = k_spin_lock(&pm_notifier_lock); pm_notifier_key = k_spin_lock(&pm_notifier_lock);
SYS_SLIST_FOR_EACH_CONTAINER(&pm_notifiers, notifier, _node) { SYS_SLIST_FOR_EACH_CONTAINER(&pm_notifiers, notifier, _node) {
@ -100,40 +103,40 @@ static inline void pm_state_notify(bool entering_state)
} }
if (callback) { if (callback) {
callback(pm_state); callback(z_power_state);
} }
} }
k_spin_unlock(&pm_notifier_lock, pm_notifier_key); k_spin_unlock(&pm_notifier_lock, pm_notifier_key);
} }
static enum pm_state _handle_device_abort(enum pm_state state)
static enum power_states _handle_device_abort(enum power_states state)
{ {
LOG_DBG("Some devices didn't enter suspend state!"); LOG_DBG("Some devices didn't enter suspend state!");
pm_resume_devices(); pm_resume_devices();
pm_state_notify(false); pm_state_notify(false);
pm_state = POWER_STATE_ACTIVE; z_power_state = PM_STATE_ACTIVE;
return pm_state; return z_power_state;
} }
static enum power_states pm_policy_mgr(int32_t ticks) static enum pm_state pm_policy_mgr(int32_t ticks)
{ {
bool deep_sleep; bool deep_sleep;
#if CONFIG_PM_DEVICE #if CONFIG_PM_DEVICE
bool low_power = false; bool low_power = false;
#endif #endif
pm_state = (forced_pm_state == POWER_STATE_AUTO) ? if (z_forced_power_state == false) {
pm_policy_next_state(ticks) : forced_pm_state; z_power_state = pm_policy_next_state(ticks);
}
if (pm_state == POWER_STATE_ACTIVE) { if (z_power_state == PM_STATE_ACTIVE) {
LOG_DBG("No PM operations to be done."); LOG_DBG("No PM operations done.");
return pm_state; return z_power_state;
} }
deep_sleep = IS_ENABLED(CONFIG_PM_DEEP_SLEEP_STATES) ? deep_sleep = IS_ENABLED(CONFIG_PM_DEEP_SLEEP_STATES) ?
pm_is_deep_sleep_state(pm_state) : 0; pm_is_deep_sleep_state(z_power_state) : 0;
post_ops_done = 0; post_ops_done = 0;
pm_state_notify(true); pm_state_notify(true);
@ -141,7 +144,7 @@ static enum power_states pm_policy_mgr(int32_t ticks)
if (deep_sleep) { if (deep_sleep) {
/* Suspend peripherals. */ /* Suspend peripherals. */
if (IS_ENABLED(CONFIG_PM_DEVICE) && pm_suspend_devices()) { if (IS_ENABLED(CONFIG_PM_DEVICE) && pm_suspend_devices()) {
return _handle_device_abort(pm_state); return _handle_device_abort(z_power_state);
} }
/* /*
* Disable idle exit notification as it is not needed * Disable idle exit notification as it is not needed
@ -150,10 +153,10 @@ static enum power_states pm_policy_mgr(int32_t ticks)
pm_idle_exit_notification_disable(); pm_idle_exit_notification_disable();
#if CONFIG_PM_DEVICE #if CONFIG_PM_DEVICE
} else { } else {
if (pm_policy_low_power_devices(pm_state)) { if (pm_policy_low_power_devices(z_power_state)) {
/* low power peripherals. */ /* low power peripherals. */
if (pm_low_power_devices()) { if (pm_low_power_devices()) {
return _handle_device_abort(pm_state); return _handle_device_abort(z_power_state);
} }
low_power = true; low_power = true;
@ -163,7 +166,7 @@ static enum power_states pm_policy_mgr(int32_t ticks)
pm_debug_start_timer(); pm_debug_start_timer();
/* Enter power state */ /* Enter power state */
pm_power_state_set(pm_state); pm_power_state_set(z_power_state);
pm_debug_stop_timer(); pm_debug_stop_timer();
/* Wake up sequence starts here */ /* Wake up sequence starts here */
@ -173,21 +176,21 @@ static enum power_states pm_policy_mgr(int32_t ticks)
pm_resume_devices(); pm_resume_devices();
} }
#endif #endif
pm_log_debug_info(pm_state); pm_log_debug_info(z_power_state);
if (!post_ops_done) { if (!post_ops_done) {
post_ops_done = 1; post_ops_done = 1;
/* clear forced_pm_state */ /* clear z_forced_power_state */
forced_pm_state = POWER_STATE_AUTO; z_forced_power_state = false;
pm_state_notify(false); pm_state_notify(false);
pm_power_state_exit_post_ops(pm_state); pm_power_state_exit_post_ops(z_power_state);
} }
return pm_state; return z_power_state;
} }
enum power_states pm_system_suspend(int32_t ticks) enum pm_state pm_system_suspend(int32_t ticks)
{ {
return pm_policy_mgr(ticks); return pm_policy_mgr(ticks);
} }
@ -212,7 +215,7 @@ void pm_system_resume(void)
if (!post_ops_done) { if (!post_ops_done) {
post_ops_done = 1; post_ops_done = 1;
pm_state_notify(false); pm_state_notify(false);
pm_power_state_exit_post_ops(pm_state); pm_power_state_exit_post_ops(z_power_state);
} }
} }

View file

@ -26,20 +26,20 @@ static void tdata_dump_callback(const struct k_thread *thread, void *user_data)
* Weak power hook functions. Used on systems that have not implemented * Weak power hook functions. Used on systems that have not implemented
* power management. * power management.
*/ */
__weak void pm_power_state_set(enum power_states state) __weak void pm_power_state_set(enum pm_state state)
{ {
/* Never called. */ /* Never called. */
__ASSERT_NO_MSG(false); __ASSERT_NO_MSG(false);
} }
__weak void pm_power_state_exit_post_ops(enum power_states state) __weak void pm_power_state_exit_post_ops(enum pm_state state)
{ {
/* Never called. */ /* Never called. */
__ASSERT_NO_MSG(false); __ASSERT_NO_MSG(false);
} }
/* Our PM policy handler */ /* Our PM policy handler */
enum power_states pm_policy_next_state(int32_t ticks) enum pm_state pm_policy_next_state(int32_t ticks)
{ {
static bool test_flag; static bool test_flag;
@ -51,7 +51,7 @@ enum power_states pm_policy_next_state(int32_t ticks)
test_flag = true; test_flag = true;
} }
return POWER_STATE_ACTIVE; return PM_STATE_ACTIVE;
} }
/*work handler*/ /*work handler*/

View file

@ -30,7 +30,7 @@ static struct dummy_driver_api *api;
* Weak power hook functions. Used on systems that have not implemented * Weak power hook functions. Used on systems that have not implemented
* power management. * power management.
*/ */
__weak void pm_power_state_set(enum power_states state) __weak void pm_power_state_set(enum pm_state state)
{ {
/* at this point, notify_pm_state_entry() implemented in /* at this point, notify_pm_state_entry() implemented in
* this file has been called and set_pm should have been set * this file has been called and set_pm should have been set
@ -47,11 +47,11 @@ __weak void pm_power_state_set(enum power_states state)
/* this function is called when system entering low power state, so /* this function is called when system entering low power state, so
* parameter state should not be POWER_STATE_ACTIVE * parameter state should not be POWER_STATE_ACTIVE
*/ */
zassert_false(state == POWER_STATE_ACTIVE, zassert_false(state == PM_STATE_ACTIVE,
"Entering low power state with a wrong parameter"); "Entering low power state with a wrong parameter");
} }
__weak void pm_power_state_exit_post_ops(enum power_states state) __weak void pm_power_state_exit_post_ops(enum pm_state state)
{ {
/* pm_system_suspend is entered with irq locked /* pm_system_suspend is entered with irq locked
* unlock irq before leave pm_system_suspend * unlock irq before leave pm_system_suspend
@ -59,15 +59,15 @@ __weak void pm_power_state_exit_post_ops(enum power_states state)
irq_unlock(0); irq_unlock(0);
} }
__weak bool pm_policy_low_power_devices(enum power_states pm_state) __weak bool pm_policy_low_power_devices(enum pm_state state)
{ {
return pm_is_sleep_state(pm_state); return pm_is_sleep_state(state);
} }
/* Our PM policy handler */ /* Our PM policy handler */
enum power_states pm_policy_next_state(int ticks) enum pm_state pm_policy_next_state(int ticks)
{ {
enum power_states state; enum pm_state state;
/* make sure this is idle thread */ /* make sure this is idle thread */
zassert_true(z_is_idle_thread_object(_current), NULL); zassert_true(z_is_idle_thread_object(_current), NULL);
@ -77,18 +77,18 @@ enum power_states pm_policy_next_state(int ticks)
if (enter_low_power) { if (enter_low_power) {
enter_low_power = false; enter_low_power = false;
notify_app_entry = true; notify_app_entry = true;
state = POWER_STATE_SLEEP_1; state = PM_STATE_RUNTIME_IDLE;
} else { } else {
/* only test pm_policy_next_state() /* only test pm_policy_next_state()
* no PM operation done * no PM operation done
*/ */
state = POWER_STATE_ACTIVE; state = PM_STATE_ACTIVE;
} }
return state; return state;
} }
/* implement in application, called by idle thread */ /* implement in application, called by idle thread */
static void notify_pm_state_entry(enum power_states state) static void notify_pm_state_entry(enum pm_state state)
{ {
uint32_t device_power_state; uint32_t device_power_state;
@ -96,7 +96,7 @@ static void notify_pm_state_entry(enum power_states state)
zassert_true(notify_app_entry == true, zassert_true(notify_app_entry == true,
"Notification to enter suspend was not sent to the App"); "Notification to enter suspend was not sent to the App");
zassert_true(z_is_idle_thread_object(_current), NULL); zassert_true(z_is_idle_thread_object(_current), NULL);
zassert_equal(state, POWER_STATE_SLEEP_1, NULL); zassert_equal(state, PM_STATE_RUNTIME_IDLE, NULL);
/* at this point, devices are active */ /* at this point, devices are active */
device_get_power_state(dev, &device_power_state); device_get_power_state(dev, &device_power_state);
@ -106,7 +106,7 @@ static void notify_pm_state_entry(enum power_states state)
} }
/* implement in application, called by idle thread */ /* implement in application, called by idle thread */
static void notify_pm_state_exit(enum power_states state) static void notify_pm_state_exit(enum pm_state state)
{ {
uint32_t device_power_state; uint32_t device_power_state;
@ -114,7 +114,7 @@ static void notify_pm_state_exit(enum power_states state)
zassert_true(notify_app_exit == true, zassert_true(notify_app_exit == true,
"Notification to leave suspend was not sent to the App"); "Notification to leave suspend was not sent to the App");
zassert_true(z_is_idle_thread_object(_current), NULL); zassert_true(z_is_idle_thread_object(_current), NULL);
zassert_equal(state, POWER_STATE_SLEEP_1, NULL); zassert_equal(state, PM_STATE_RUNTIME_IDLE, NULL);
/* at this point, devices are active again*/ /* at this point, devices are active again*/
device_get_power_state(dev, &device_power_state); device_get_power_state(dev, &device_power_state);

View file

@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(pwrmgmt_test);
#define TASK_STACK_SIZE 1024ul #define TASK_STACK_SIZE 1024ul
#define PRIORITY K_PRIO_COOP(5) #define PRIORITY K_PRIO_COOP(5)
/* Sleep time should be lower than CONFIG_PM_MIN_RESIDENCY_SLEEP_1 */ /* Sleep time should be lower than SUSPEND_TO_IDLE */
#define THREAD_A_SLEEP_TIME 100ul #define THREAD_A_SLEEP_TIME 100ul
#define THREAD_B_SLEEP_TIME 1000ul #define THREAD_B_SLEEP_TIME 1000ul
@ -51,6 +51,10 @@ static bool checks_enabled;
/* Track entry/exit to sleep */ /* Track entry/exit to sleep */
struct pm_counter pm_counters[SLP_STATES_SUPPORTED]; struct pm_counter pm_counters[SLP_STATES_SUPPORTED];
static const struct pm_state_info residency_info[] =
PM_STATE_INFO_DT_ITEMS_LIST(DT_NODELABEL(cpu0));
static size_t residency_info_len = PM_STATE_DT_ITEMS_LEN(DT_NODELABEL(cpu0));
static void pm_latency_check(void) static void pm_latency_check(void)
{ {
int64_t latency; int64_t latency;
@ -68,7 +72,7 @@ static void pm_latency_check(void)
"Sleep entry latency is higher than expected"); "Sleep entry latency is higher than expected");
} }
static void notify_pm_state_entry(enum power_states state) static void notify_pm_state_entry(enum pm_state state)
{ {
if (!checks_enabled) { if (!checks_enabled) {
return; return;
@ -83,7 +87,7 @@ static void notify_pm_state_entry(enum power_states state)
} }
} }
static void notify_pm_state_exit(enum power_states state) static void notify_pm_state_exit(enum pm_state state)
{ {
if (!checks_enabled) { if (!checks_enabled) {
return; return;
@ -235,7 +239,7 @@ int test_pwr_mgmt_multithread(uint8_t cycles)
suspend_all_tasks(); suspend_all_tasks();
LOG_INF("About to enter light sleep"); LOG_INF("About to enter light sleep");
pm_trigger_marker(); pm_trigger_marker();
k_msleep(CONFIG_PM_MIN_RESIDENCY_SLEEP_1 + k_msleep((residency_info[0].min_residency_us / 1000U) +
LT_EXTRA_SLP_TIME); LT_EXTRA_SLP_TIME);
LOG_INF("Wake from Light Sleep"); LOG_INF("Wake from Light Sleep");
@ -252,8 +256,9 @@ int test_pwr_mgmt_multithread(uint8_t cycles)
LOG_INF("About to enter deep sleep"); LOG_INF("About to enter deep sleep");
pm_trigger_marker(); pm_trigger_marker();
k_msleep(CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_1 + k_msleep(
DP_EXTRA_SLP_TIME); (residency_info[residency_info_len - 1].min_residency_us /
1000U) + DP_EXTRA_SLP_TIME);
LOG_INF("Wake from Deep Sleep"); LOG_INF("Wake from Deep Sleep");
pm_exit_marker(); pm_exit_marker();
@ -284,7 +289,7 @@ int test_pwr_mgmt_singlethread(uint8_t cycles)
/* Trigger Light Sleep 1 state. 48MHz PLL stays on */ /* Trigger Light Sleep 1 state. 48MHz PLL stays on */
LOG_INF("About to enter light sleep"); LOG_INF("About to enter light sleep");
pm_trigger_marker(); pm_trigger_marker();
k_msleep(CONFIG_PM_MIN_RESIDENCY_SLEEP_1 + k_msleep((residency_info[0].min_residency_us / 1000U) +
LT_EXTRA_SLP_TIME); LT_EXTRA_SLP_TIME);
LOG_INF("Wake from Light Sleep"); LOG_INF("Wake from Light Sleep");
pm_exit_marker(); pm_exit_marker();
@ -296,9 +301,9 @@ int test_pwr_mgmt_singlethread(uint8_t cycles)
LOG_INF("About to enter deep Sleep"); LOG_INF("About to enter deep Sleep");
pm_trigger_marker(); pm_trigger_marker();
k_msleep(CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_1 + k_msleep(
DP_EXTRA_SLP_TIME); (residency_info[residency_info_len - 1].min_residency_us /
1000U) + DP_EXTRA_SLP_TIME);
LOG_INF("Wake from Deep Sleep"); LOG_INF("Wake from Deep Sleep");
pm_exit_marker(); pm_exit_marker();
} }
@ -321,15 +326,16 @@ int test_dummy_init(void)
while (iterations-- > 0) { while (iterations-- > 0) {
LOG_INF("About to enter light sleep"); LOG_INF("About to enter light sleep");
pm_trigger_marker(); pm_trigger_marker();
k_msleep(CONFIG_PM_MIN_RESIDENCY_SLEEP_1 + k_msleep((residency_info[0].min_residency_us / 1000U) +
LT_EXTRA_SLP_TIME); LT_EXTRA_SLP_TIME);
LOG_INF("Wake from Light Sleep"); LOG_INF("Wake from Light Sleep");
pm_exit_marker(); pm_exit_marker();
LOG_INF("About to enter deep Sleep"); LOG_INF("About to enter deep Sleep");
pm_trigger_marker(); pm_trigger_marker();
k_msleep(CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_1 + k_msleep(
DP_EXTRA_SLP_TIME); (residency_info[residency_info_len - 1].min_residency_us /
1000U) + DP_EXTRA_SLP_TIME);
LOG_INF("Wake from Deep Sleep"); LOG_INF("Wake from Deep Sleep");
pm_exit_marker(); pm_exit_marker();
} }

View file

@ -11,10 +11,10 @@
/** @brief Alternates between light and deep sleep cycles. /** @brief Alternates between light and deep sleep cycles.
* *
* For light sleep, the test sleeps in main thread for 500 ms longer than * For light sleep, the test sleeps in main thread for 500 ms longer than
* CONFIG_PM_MIN_RESIDENCY_SLEEP_1. * SUSPEND_TO_IDLE.
* *
* Similarly for deep sleep, the test sleeps in the main thread for 500 ms * Similarly for deep sleep, the test sleeps in the main thread for 500 ms
* longer than CONFIG_PM_MIN_RESIDENCY_DEEP_SLEEP_1. * longer than STANDBY.
* *
* @param cycles to repeat the cycle described above. * @param cycles to repeat the cycle described above.
* @retval 0 if successful, errno otherwise. * @retval 0 if successful, errno otherwise.