blob: 297d28a37680b755838626e2ed836992f802117e [file] [log] [blame]
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +01001/*
2 * Copyright (c) 2018 Intel Corporation.
3 * Copyright (c) 2021 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
Gerard Marull-Paretas5113c142022-05-06 11:12:04 +02008#include <zephyr/pm/state.h>
9#include <zephyr/toolchain.h>
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +010010
Gerard Marull-Paretas7eb50be2021-12-21 11:38:12 +010011BUILD_ASSERT(DT_NODE_EXISTS(DT_PATH(cpus)),
12 "cpus node not defined in Devicetree");
13
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +010014/**
15 * Check CPU power state consistency.
16 *
17 * @param i Power state index.
18 * @param node_id CPU node identifier.
19 */
20#define CHECK_POWER_STATE_CONSISTENCY(i, node_id) \
21 BUILD_ASSERT( \
22 DT_PROP_BY_PHANDLE_IDX_OR(node_id, cpu_power_states, i, \
23 min_residency_us, 0U) >= \
24 DT_PROP_BY_PHANDLE_IDX_OR(node_id, cpu_power_states, i, \
25 exit_latency_us, 0U), \
Krzysztof Chruscinski47ae6562022-02-28 14:06:36 +010026 "Found CPU power state with min_residency < exit_latency")
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +010027
28/**
29 * @brief Check CPU power states consistency
30 *
31 * All states should have a minimum residency >= than the exit latency.
32 *
33 * @param node_id A CPU node identifier.
34 */
35#define CHECK_POWER_STATES_CONSISTENCY(node_id) \
Gerard Marull-Paretasa05371d2023-07-25 11:43:52 +020036 LISTIFY(DT_PROP_LEN_OR(node_id, cpu_power_states, 0), \
Krzysztof Chruscinski47ae6562022-02-28 14:06:36 +010037 CHECK_POWER_STATE_CONSISTENCY, (;), node_id); \
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +010038
39/* Check that all power states are consistent */
Gerard Marull-Paretas7eb50be2021-12-21 11:38:12 +010040DT_FOREACH_CHILD(DT_PATH(cpus), CHECK_POWER_STATES_CONSISTENCY)
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +010041
Andy Ross0c30db12022-01-27 11:07:49 -080042#define DEFINE_CPU_STATES(n) \
43 static const struct pm_state_info pmstates_##n[] \
44 = PM_STATE_INFO_LIST_FROM_DT_CPU(n);
Gerard Marull-Paretas2e0899e2022-07-06 14:57:06 +020045#define CPU_STATE_REF(n) pmstates_##n
Andy Ross0c30db12022-01-27 11:07:49 -080046
47DT_FOREACH_CHILD(DT_PATH(cpus), DEFINE_CPU_STATES);
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +010048
49/** CPU power states information for each CPU */
50static const struct pm_state_info *cpus_states[] = {
Gerard Marull-Paretasa05371d2023-07-25 11:43:52 +020051 DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), CPU_STATE_REF, (,))
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +010052};
53
54/** Number of states for each CPU */
55static const uint8_t states_per_cpu[] = {
Gerard Marull-Paretasa05371d2023-07-25 11:43:52 +020056 DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_NUM_CPU_POWER_STATES, (,))
Gerard Marull-Paretas8385d1b2021-12-20 15:25:19 +010057};
58
59uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states)
60{
61 if (cpu >= ARRAY_SIZE(cpus_states)) {
62 return 0;
63 }
64
65 *states = cpus_states[cpu];
66
67 return states_per_cpu[cpu];
68}