1 /* 2 * Copyright (c) 2018 Intel Corporation. 3 * Copyright (c) 2022 Nordic Semiconductor ASA 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #include <zephyr/pm/policy.h> 9 #include <zephyr/sys_clock.h> 10 #include <zephyr/pm/device.h> 11 12 extern int32_t max_latency_cyc; 13 pm_policy_next_state(uint8_t cpu,int32_t ticks)14const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) 15 { 16 int64_t cyc = -1; 17 uint8_t num_cpu_states; 18 const struct pm_state_info *cpu_states; 19 20 #ifdef CONFIG_PM_NEED_ALL_DEVICES_IDLE 21 if (pm_device_is_any_busy()) { 22 return NULL; 23 } 24 #endif 25 26 if (ticks != K_TICKS_FOREVER) { 27 cyc = k_ticks_to_cyc_ceil32(ticks); 28 } 29 30 num_cpu_states = pm_state_cpu_get_all(cpu, &cpu_states); 31 32 for (int16_t i = (int16_t)num_cpu_states - 1; i >= 0; i--) { 33 const struct pm_state_info *state = &cpu_states[i]; 34 uint32_t min_residency_cyc, exit_latency_cyc; 35 36 /* check if there is a lock on state + substate */ 37 if (pm_policy_state_lock_is_active(state->state, state->substate_id)) { 38 continue; 39 } 40 41 min_residency_cyc = k_us_to_cyc_ceil32(state->min_residency_us); 42 exit_latency_cyc = k_us_to_cyc_ceil32(state->exit_latency_us); 43 44 /* skip state if it brings too much latency */ 45 if ((max_latency_cyc >= 0) && 46 (exit_latency_cyc >= max_latency_cyc)) { 47 continue; 48 } 49 50 if ((cyc < 0) || 51 (cyc >= (min_residency_cyc + exit_latency_cyc))) { 52 return state; 53 } 54 } 55 56 return NULL; 57 } 58