1 /*
2 * Copyright (c) 2020 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "test_driver.h"
8
9 #include <zephyr/device.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/ztest.h>
12 #include <zephyr/pm/pm.h>
13
14 /* Last state has not declared a minimum residency, so it should be
15 * set the default 0 value
16 */
17 static struct pm_state_info infos[] = {{PM_STATE_SUSPEND_TO_IDLE, 0, 10000, 100},
18 {PM_STATE_STANDBY, 0, 20000, 200}, {PM_STATE_SUSPEND_TO_RAM, 0, 50000, 500}};
19 static enum pm_state states[] = {PM_STATE_SUSPEND_TO_IDLE,
20 PM_STATE_STANDBY, PM_STATE_SUSPEND_TO_RAM};
21 static enum pm_state wrong_states[] = {PM_STATE_SUSPEND_TO_DISK,
22 PM_STATE_SUSPEND_TO_RAM, PM_STATE_SUSPEND_TO_RAM};
23
24 static uint8_t suspend_to_ram_count;
25
pm_state_set(enum pm_state state,uint8_t substate_id)26 void pm_state_set(enum pm_state state, uint8_t substate_id)
27 {
28 ARG_UNUSED(substate_id);
29
30 if (state == PM_STATE_SUSPEND_TO_RAM) {
31 suspend_to_ram_count++;
32 }
33
34 k_cpu_idle();
35 }
36
pm_state_exit_post_ops(enum pm_state state,uint8_t substate_id)37 void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
38 {
39 ARG_UNUSED(state);
40 ARG_UNUSED(substate_id);
41
42 irq_unlock(0);
43 }
44
ZTEST(power_states_1cpu,test_power_states)45 ZTEST(power_states_1cpu, test_power_states)
46 {
47 uint8_t ret;
48 const struct pm_state_info *cpu_states;
49 enum pm_state dts_states[] =
50 PM_STATE_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0));
51 struct pm_state_info dts_infos[] =
52 PM_STATE_INFO_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0));
53 uint32_t dts_states_len =
54 DT_NUM_CPU_POWER_STATES(DT_NODELABEL(cpu0));
55
56 zassert_true(ARRAY_SIZE(states) == dts_states_len,
57 "Invalid number of pm states");
58 zassert_true(memcmp(infos, dts_infos, ARRAY_SIZE(dts_infos)) == 0,
59 "Invalid pm_state_info array");
60 zassert_true(memcmp(states, dts_states, ARRAY_SIZE(dts_states)) == 0,
61 "Invalid pm-states array");
62
63 zassert_false(memcmp(wrong_states, dts_states, ARRAY_SIZE(dts_states)) == 0,
64 "Invalid pm-states array");
65
66 ret = pm_state_cpu_get_all(CONFIG_MP_MAX_NUM_CPUS + 1, &cpu_states);
67 zassert_true(ret == 0, "Invalid pm_state_cpu_get_all return");
68
69 ret = pm_state_cpu_get_all(0U, &cpu_states);
70 zassert_true(ret == dts_states_len,
71 "Invalid number of pm states");
72 zassert_true(memcmp(cpu_states, dts_infos, ARRAY_SIZE(dts_infos)) == 0,
73 "Invalid pm_state_info array");
74 }
75
ZTEST(power_states_1cpu,test_device_power_state_constraints)76 ZTEST(power_states_1cpu, test_device_power_state_constraints)
77 {
78 static const struct device *const dev =
79 DEVICE_DT_GET(DT_NODELABEL(test_dev));
80 suspend_to_ram_count = 0;
81
82 test_driver_async_operation(dev);
83
84 /** Lets sleep long enough to suspend the CPU with `suspend to ram`
85 * power state. If everything works well the cpu should not use this
86 * state due the constraint set by `test_dev`.
87 */
88 k_sleep(K_USEC(60000));
89
90 zassert_true(suspend_to_ram_count == 0, "Invalid suspend to ram count");
91
92 /** Now lets check ensure that if there is no ongoing work
93 * the cpu will suspend to ram.
94 */
95 k_sleep(K_MSEC(600));
96
97 zassert(suspend_to_ram_count != 0, "Not suspended to ram");
98 }
99
100 ZTEST_SUITE(power_states_1cpu, NULL, NULL, ztest_simple_1cpu_before,
101 ztest_simple_1cpu_after, NULL);
102