pm: policy: default: Optimize power state selection
Update power state selection. Previously, it was iterating over states starting from the last one so the most common short sleep periods were taking the longest time to select. Order is now swapped so that short sleeps will get power state as quick as possible. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
5a313e141d
commit
bb4fb12ca4
1 changed files with 15 additions and 20 deletions
|
@ -9,13 +9,12 @@
|
|||
#include <zephyr/sys_clock.h>
|
||||
#include <zephyr/pm/device.h>
|
||||
|
||||
extern int32_t max_latency_cyc;
|
||||
|
||||
const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
|
||||
{
|
||||
int64_t cyc = -1;
|
||||
uint8_t num_cpu_states;
|
||||
const struct pm_state_info *cpu_states;
|
||||
const struct pm_state_info *out_state = NULL;
|
||||
|
||||
#ifdef CONFIG_PM_NEED_ALL_DEVICES_IDLE
|
||||
if (pm_device_is_any_busy()) {
|
||||
|
@ -29,29 +28,25 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
|
|||
|
||||
num_cpu_states = pm_state_cpu_get_all(cpu, &cpu_states);
|
||||
|
||||
for (int16_t i = (int16_t)num_cpu_states - 1; i >= 0; i--) {
|
||||
for (uint32_t i = 0; i < num_cpu_states; i++) {
|
||||
const struct pm_state_info *state = &cpu_states[i];
|
||||
uint32_t min_residency_cyc, exit_latency_cyc;
|
||||
uint32_t min_residency_ticks;
|
||||
|
||||
/* check if there is a lock on state + substate */
|
||||
if (pm_policy_state_lock_is_active(state->state, state->substate_id)) {
|
||||
min_residency_ticks =
|
||||
k_us_to_ticks_ceil32(state->min_residency_us + state->exit_latency_us);
|
||||
|
||||
if (ticks < min_residency_ticks) {
|
||||
/* If current state has higher residency then use the previous state; */
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if state is available. */
|
||||
if (!pm_policy_state_is_available(state->state, state->substate_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
min_residency_cyc = k_us_to_cyc_ceil32(state->min_residency_us);
|
||||
exit_latency_cyc = k_us_to_cyc_ceil32(state->exit_latency_us);
|
||||
|
||||
/* skip state if it brings too much latency */
|
||||
if ((max_latency_cyc >= 0) &&
|
||||
(exit_latency_cyc >= max_latency_cyc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cyc < 0) ||
|
||||
(cyc >= (min_residency_cyc + exit_latency_cyc))) {
|
||||
return state;
|
||||
}
|
||||
out_state = state;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return out_state;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue