Commit bb4fb12c authored by Krzysztof Chruściński's avatar Krzysztof Chruściński Committed by Benjamin Cabé
Browse files

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: default avatarKrzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
parent 5a313e14
Loading
Loading
Loading
Loading
+13 −18
Changes for subsys/pm/policy/policy_default.c: 13 added lines, 18 removed lines.
Original line number Diff line number Diff line
@@ -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)) {
			continue;
		}
		min_residency_ticks =
			k_us_to_ticks_ceil32(state->min_residency_us + state->exit_latency_us);

		min_residency_cyc = k_us_to_cyc_ceil32(state->min_residency_us);
		exit_latency_cyc = k_us_to_cyc_ceil32(state->exit_latency_us);
		if (ticks < min_residency_ticks) {
			/* If current state has higher residency then use the previous state; */
			break;
		}

		/* skip state if it brings too much latency */
		if ((max_latency_cyc >= 0) &&
		    (exit_latency_cyc >= max_latency_cyc)) {
		/* check if state is available. */
		if (!pm_policy_state_is_available(state->state, state->substate_id)) {
			continue;
		}

		if ((cyc < 0) ||
		    (cyc >= (min_residency_cyc + exit_latency_cyc))) {
			return state;
		}
		out_state = state;
	}

	return NULL;
	return out_state;
}