80 lines
2.2 KiB
C
80 lines
2.2 KiB
C
/*
|
|
* Copyright (c) 2018 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr.h>
|
|
#include <kernel.h>
|
|
#include "pm_policy.h"
|
|
|
|
#define LOG_LEVEL CONFIG_SYS_PM_LOG_LEVEL /* From power module Kconfig */
|
|
#include <logging/log.h>
|
|
LOG_MODULE_DECLARE(power);
|
|
|
|
#define SECS_TO_TICKS CONFIG_SYS_CLOCK_TICKS_PER_SEC
|
|
|
|
/* PM Policy based on SoC/Platform residency requirements */
|
|
static const unsigned int pm_min_residency[] = {
|
|
#ifdef CONFIG_SYS_POWER_SLEEP_STATES
|
|
#ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_1
|
|
CONFIG_SYS_PM_MIN_RESIDENCY_SLEEP_1 * SECS_TO_TICKS / MSEC_PER_SEC,
|
|
#endif
|
|
|
|
#ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_2
|
|
CONFIG_SYS_PM_MIN_RESIDENCY_SLEEP_2 * SECS_TO_TICKS / MSEC_PER_SEC,
|
|
#endif
|
|
|
|
#ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_3
|
|
CONFIG_SYS_PM_MIN_RESIDENCY_SLEEP_3 * SECS_TO_TICKS / MSEC_PER_SEC,
|
|
#endif
|
|
#endif /* CONFIG_SYS_POWER_SLEEP_STATES */
|
|
|
|
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP_STATES
|
|
#ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_1
|
|
CONFIG_SYS_PM_MIN_RESIDENCY_DEEP_SLEEP_1 * SECS_TO_TICKS / MSEC_PER_SEC,
|
|
#endif
|
|
|
|
#ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_2
|
|
CONFIG_SYS_PM_MIN_RESIDENCY_DEEP_SLEEP_2 * SECS_TO_TICKS / MSEC_PER_SEC,
|
|
#endif
|
|
|
|
#ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_3
|
|
CONFIG_SYS_PM_MIN_RESIDENCY_DEEP_SLEEP_3 * SECS_TO_TICKS / MSEC_PER_SEC,
|
|
#endif
|
|
#endif /* CONFIG_SYS_POWER_DEEP_SLEEP_STATES */
|
|
};
|
|
|
|
enum power_states sys_pm_policy_next_state(int32_t ticks)
|
|
{
|
|
int i;
|
|
|
|
if ((ticks != K_TICKS_FOREVER) && (ticks < pm_min_residency[0])) {
|
|
LOG_DBG("Not enough time for PM operations: %d", ticks);
|
|
return SYS_POWER_STATE_ACTIVE;
|
|
}
|
|
|
|
for (i = ARRAY_SIZE(pm_min_residency) - 1; i >= 0; i--) {
|
|
#ifdef CONFIG_SYS_PM_STATE_LOCK
|
|
if (!sys_pm_ctrl_is_state_enabled((enum power_states)(i))) {
|
|
continue;
|
|
}
|
|
#endif
|
|
if ((ticks == K_TICKS_FOREVER) ||
|
|
(ticks >= pm_min_residency[i])) {
|
|
LOG_DBG("Selected power state %d "
|
|
"(ticks: %d, min_residency: %u)",
|
|
i, ticks, pm_min_residency[i]);
|
|
return (enum power_states)(i);
|
|
}
|
|
}
|
|
|
|
LOG_DBG("No suitable power state found!");
|
|
return SYS_POWER_STATE_ACTIVE;
|
|
}
|
|
|
|
__weak bool sys_pm_policy_low_power_devices(enum power_states pm_state)
|
|
{
|
|
return sys_pm_is_sleep_state(pm_state);
|
|
}
|