Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions subsys/pm/policy/policy_default.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <zephyr/sys_clock.h>
#include <zephyr/pm/device.h>

extern struct pm_policy_event *next_event;
extern int32_t max_latency_cyc;

const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
Expand All @@ -30,27 +29,6 @@ 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);

if ((next_event) && (next_event->value_cyc >= 0)) {
uint32_t cyc_curr = k_cycle_get_32();
int64_t cyc_evt = next_event->value_cyc - cyc_curr;

/* event happening after cycle counter max value, pad */
if (next_event->value_cyc <= cyc_curr) {
cyc_evt += UINT32_MAX;
}

if (cyc_evt > 0) {
/* if there's no system wakeup event always wins,
* otherwise, who comes earlier wins
*/
if (cyc < 0) {
cyc = cyc_evt;
} else {
cyc = MIN(cyc, cyc_evt);
}
}
}

for (int16_t i = (int16_t)num_cpu_states - 1; i >= 0; i--) {
const struct pm_state_info *state = &cpu_states[i];
uint32_t min_residency_cyc, exit_latency_cyc;
Expand Down
7 changes: 3 additions & 4 deletions subsys/pm/policy/policy_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,13 @@ int32_t pm_policy_next_event_ticks(void)
return -1;
}

void pm_policy_event_register(struct pm_policy_event *evt, uint32_t time_us)
void pm_policy_event_register(struct pm_policy_event *evt, uint32_t cycle)
{
k_spinlock_key_t key = k_spin_lock(&events_lock);
uint32_t cyc = k_cycle_get_32();

evt->value_cyc = cyc + k_us_to_cyc_ceil32(time_us);
evt->value_cyc = cycle;
sys_slist_append(&events_list, &evt->node);
update_next_event(cyc);
update_next_event(k_cycle_get_32());

k_spin_unlock(&events_lock, key);
}
Expand Down
82 changes: 25 additions & 57 deletions tests/subsys/pm/policy_api/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,68 +304,36 @@ ZTEST(policy_api, test_pm_policy_next_state_custom)
}
#endif /* CONFIG_PM_POLICY_CUSTOM */

#ifdef CONFIG_PM_POLICY_DEFAULT
/* note: we can't easily mock k_cycle_get_32(), so test is not ideal */
ZTEST(policy_api, test_pm_policy_events)
{
struct pm_policy_event evt1, evt2;
const struct pm_state_info *next;
uint32_t now;

now = k_cyc_to_ticks_ceil32(k_cycle_get_32());

/* events:
* - 10ms from now (time < runtime idle latency)
* - 200ms from now (time > runtime idle, < suspend to ram latencies)
*
* system wakeup:
* - 2s from now (time > suspend to ram latency)
*
* first event wins, so we must stay active
*/
pm_policy_event_register(&evt1, k_ms_to_cyc_floor32(10) + k_cycle_get_32());
pm_policy_event_register(&evt2, k_ms_to_cyc_floor32(200) + k_cycle_get_32());
next = pm_policy_next_state(0U, now + k_sec_to_ticks_floor32(2));
zassert_is_null(next);

/* remove first event so second event now wins, meaning we can now enter
* runtime idle
*/
struct pm_policy_event evt1;
struct pm_policy_event evt2;
uint32_t now_cycle;
uint32_t evt1_1_cycle;
uint32_t evt1_2_cycle;
uint32_t evt2_cycle;

now_cycle = k_cycle_get_32();
evt1_1_cycle = now_cycle + k_ticks_to_cyc_floor32(100);
evt1_2_cycle = now_cycle + k_ticks_to_cyc_floor32(200);
evt2_cycle = now_cycle + k_ticks_to_cyc_floor32(2000);

zassert_equal(pm_policy_next_event_ticks(), -1);
pm_policy_event_register(&evt1, evt1_1_cycle);
pm_policy_event_register(&evt2, evt2_cycle);
zassert_within(pm_policy_next_event_ticks(), 100, 50);
pm_policy_event_unregister(&evt1);
next = pm_policy_next_state(0U, now + k_sec_to_ticks_floor32(2));
zassert_equal(next->state, PM_STATE_RUNTIME_IDLE);

/* remove second event, now we can enter deepest state */
zassert_within(pm_policy_next_event_ticks(), 2000, 50);
pm_policy_event_unregister(&evt2);
next = pm_policy_next_state(0U, now + k_sec_to_ticks_floor32(2));
zassert_equal(next->state, PM_STATE_SUSPEND_TO_RAM);

/* events:
* - 2s from now (time > suspend to ram latency)
*
* system wakeup:
* - 200ms from now (time > runtime idle, < suspend to ram latencies)
*
* system wakeup wins, so we can go up to runtime idle.
*/
pm_policy_event_register(&evt1, k_sec_to_cyc_floor32(2) + k_cycle_get_32());
next = pm_policy_next_state(0U, now + k_ms_to_ticks_floor32(200));
zassert_equal(next->state, PM_STATE_RUNTIME_IDLE);

/* modify event to occur in 10ms, so it now wins system wakeup and
* requires to stay awake
*/
pm_policy_event_update(&evt1, k_ms_to_cyc_floor32(10) + k_cycle_get_32());
next = pm_policy_next_state(0U, now + k_ms_to_ticks_floor32(200));
zassert_is_null(next);

zassert_equal(pm_policy_next_event_ticks(), -1);
pm_policy_event_register(&evt2, evt2_cycle);
zassert_within(pm_policy_next_event_ticks(), 2000, 50);
pm_policy_event_register(&evt1, evt1_1_cycle);
zassert_within(pm_policy_next_event_ticks(), 100, 50);
pm_policy_event_update(&evt1, evt1_2_cycle);
zassert_within(pm_policy_next_event_ticks(), 200, 50);
pm_policy_event_unregister(&evt1);
pm_policy_event_unregister(&evt2);
}
#else
ZTEST(policy_api, test_pm_policy_events)
{
ztest_test_skip();
}
#endif /* CONFIG_PM_POLICY_CUSTOM */

ZTEST_SUITE(policy_api, NULL, NULL, NULL, NULL, NULL);
Loading