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:
parent
539ccb880a
commit
579f7049c7
33 changed files with 327 additions and 473 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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*/
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue