/* * Copyright (c) 2018 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include "pm_policy.h" #define LOG_LEVEL CONFIG_SYS_PM_LOG_LEVEL /* From power module Kconfig */ #include 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(s32_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); }