LCOV - code coverage report
Current view: top level - zephyr/pm - state.h Coverage Total Hit
Test: new.info Lines: 88.9 % 18 16
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2020 Intel corporation
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_INCLUDE_PM_STATE_H_
       8              : #define ZEPHYR_INCLUDE_PM_STATE_H_
       9              : 
      10              : #include <zephyr/sys/util.h>
      11              : #include <zephyr/devicetree.h>
      12              : 
      13              : #ifdef __cplusplus
      14              : extern "C" {
      15              : #endif
      16              : 
      17              : /**
      18              :  * @brief System Power Management States
      19              :  * @defgroup subsys_pm_states States
      20              :  * @ingroup subsys_pm
      21              :  * @{
      22              :  */
      23              : 
      24              : /**
      25              :  * @enum pm_state Power management state
      26              :  */
      27            1 : enum pm_state {
      28              :         /**
      29              :          * @brief Runtime active state
      30              :          *
      31              :          * The system is fully powered and active.
      32              :          *
      33              :          * @note This state is correlated with ACPI G0/S0 state
      34              :          */
      35              :         PM_STATE_ACTIVE,
      36              :         /**
      37              :          * @brief Runtime idle state
      38              :          *
      39              :          * Runtime idle is a system sleep state in which all of the cores
      40              :          * enter deepest possible idle state and wait for interrupts, no
      41              :          * requirements for the devices, leaving them at the states where
      42              :          * they are.
      43              :          *
      44              :          * @note This state is correlated with ACPI S0ix state
      45              :          */
      46              :         PM_STATE_RUNTIME_IDLE,
      47              :         /**
      48              :          * @brief Suspend to idle state
      49              :          *
      50              :          * The system goes through a normal platform suspend where it puts
      51              :          * all of the cores in deepest possible idle state and *may* puts
      52              :          * peripherals into low-power states. No operating state is lost (ie.
      53              :          * the cpu core does not lose execution context), so the system can go
      54              :          * back to where it left off easily enough.
      55              :          *
      56              :          * @note This state is correlated with ACPI S1 state
      57              :          */
      58              :         PM_STATE_SUSPEND_TO_IDLE,
      59              :         /**
      60              :          * @brief Standby state
      61              :          *
      62              :          * In addition to putting peripherals into low-power states all
      63              :          * non-boot CPUs are powered off. It should allow more energy to be
      64              :          * saved relative to suspend to idle, but the resume latency will
      65              :          * generally be greater than for that state. But it should be the same
      66              :          * state with suspend to idle state on uniprocessor system.
      67              :          *
      68              :          * @note This state is correlated with ACPI S2 state
      69              :          */
      70              :         PM_STATE_STANDBY,
      71              :         /**
      72              :          * @brief Suspend to ram state
      73              :          *
      74              :          * This state offers significant energy savings by powering off as much
      75              :          * of the system as possible, where memory should be placed into the
      76              :          * self-refresh mode to retain its contents. The state of devices and
      77              :          * CPUs is saved and held in memory, and it may require some boot-
      78              :          * strapping code in ROM to resume the system from it.
      79              :          *
      80              :          * @note This state is correlated with ACPI S3 state
      81              :          */
      82              :         PM_STATE_SUSPEND_TO_RAM,
      83              :         /**
      84              :          * @brief Suspend to disk state
      85              :          *
      86              :          * This state offers significant energy savings by powering off as much
      87              :          * of the system as possible, including the memory. The contents of
      88              :          * memory are written to disk or other non-volatile storage, and on
      89              :          * resume it's read back into memory with the help of boot-strapping
      90              :          * code, restores the system to the same point of execution where it
      91              :          * went to suspend to disk.
      92              :          *
      93              :          * @note This state is correlated with ACPI S4 state
      94              :          */
      95              :         PM_STATE_SUSPEND_TO_DISK,
      96              :         /**
      97              :          * @brief Soft off state
      98              :          *
      99              :          * This state consumes a minimal amount of power and requires a large
     100              :          * latency in order to return to runtime active state. The contents of
     101              :          * system(CPU and memory) will not be preserved, so the system will be
     102              :          * restarted as if from initial power-up and kernel boot.
     103              :          *
     104              :          * @note This state is correlated with ACPI G2/S5 state
     105              :          */
     106              :         PM_STATE_SOFT_OFF,
     107              :         /** Number of power management states (internal use) */
     108              :         PM_STATE_COUNT,
     109              : };
     110              : 
     111              : /**
     112              :  * Information about a power management state
     113              :  */
     114            1 : struct pm_state_info {
     115            0 :         enum pm_state state;
     116              : 
     117              :         /**
     118              :          * Some platforms have multiple states that map to
     119              :          * one Zephyr power state. This property allows the platform
     120              :          * distinguish them. e.g:
     121              :          *
     122              :          * @code{.dts}
     123              :          *      power-states {
     124              :          *              state0: state0 {
     125              :          *                      compatible = "zephyr,power-state";
     126              :          *                      power-state-name = "suspend-to-idle";
     127              :          *                      substate-id = <1>;
     128              :          *                      min-residency-us = <10000>;
     129              :          *                      exit-latency-us = <100>;
     130              :          *              };
     131              :          *              state1: state1 {
     132              :          *                      compatible = "zephyr,power-state";
     133              :          *                      power-state-name = "suspend-to-idle";
     134              :          *                      substate-id = <2>;
     135              :          *                      min-residency-us = <20000>;
     136              :          *                      exit-latency-us = <200>;
     137              :          *                      zephyr,pm-device-disabled;
     138              :          *              };
     139              :          *      };
     140              :          * @endcode
     141              :          */
     142            1 :         uint8_t substate_id;
     143              : 
     144              :         /**
     145              :          * Whether or not this state triggers device power management.
     146              :          *
     147              :          * When this property is false the power management subsystem
     148              :          * will suspend devices before entering this state and will
     149              :          * properly resume them when leaving it.
     150              :          */
     151            1 :         bool pm_device_disabled;
     152              : 
     153              :         /**
     154              :          * Minimum residency duration in microseconds. It is the minimum
     155              :          * time for a given idle state to be worthwhile energywise.
     156              :          *
     157              :          * @note 0 means that this property is not available for this state.
     158              :          */
     159            1 :         uint32_t min_residency_us;
     160              : 
     161              :         /**
     162              :          * Worst case latency in microseconds required to exit the idle state.
     163              :          *
     164              :          * @note 0 means that this property is not available for this state.
     165              :          */
     166            1 :         uint32_t exit_latency_us;
     167              : };
     168              : 
     169              : /**
     170              :  * Power state information needed to lock a power state.
     171              :  */
     172            1 : struct pm_state_constraint {
     173              :          /**
     174              :           * Power management state
     175              :           *
     176              :           * @see pm_state
     177              :           **/
     178            1 :         enum pm_state state;
     179              :          /**
     180              :           * Power management sub-state
     181              :           *
     182              :           * @see pm_state
     183              :           **/
     184            1 :         uint8_t substate_id;
     185              : };
     186              : 
     187              : /** @cond INTERNAL_HIDDEN */
     188              : 
     189              : /**
     190              :  * @brief Helper macro that expands to 1 if a phandle node is enabled, 0 otherwise.
     191              :  *
     192              :  * @param node_id Node identifier.
     193              :  * @param prop Property holding phandle-array.
     194              :  * @param idx Index within the array.
     195              :  */
     196              : #define Z_DT_PHANDLE_01(node_id, prop, idx) \
     197              :         COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE_BY_IDX(node_id, prop, idx)), \
     198              :                     (1), (0))
     199              : 
     200              : /**
     201              :  * @brief Helper macro to initialize an entry of a struct pm_state_info array
     202              :  * when using UTIL_LISTIFY in PM_STATE_INFO_LIST_FROM_DT_CPU.
     203              :  *
     204              :  * @note Only enabled states are initialized.
     205              :  *
     206              :  * @param i UTIL_LISTIFY entry index.
     207              :  * @param node_id A node identifier with compatible zephyr,power-state
     208              :  */
     209              : #define Z_PM_STATE_INFO_FROM_DT_CPU(i, node_id)                                                   \
     210              :         COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),     \
     211              :                     (PM_STATE_INFO_DT_INIT(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),), ())
     212              : 
     213              : /**
     214              :  * @brief Helper macro to initialize an entry of a struct pm_state array when
     215              :  * using UTIL_LISTIFY in PM_STATE_LIST_FROM_DT_CPU.
     216              :  *
     217              :  * @note Only enabled states are initialized.
     218              :  *
     219              :  * @param i UTIL_LISTIFY entry index.
     220              :  * @param node_id A node identifier with compatible zephyr,power-state
     221              :  */
     222              : #define Z_PM_STATE_FROM_DT_CPU(i, node_id)                                                        \
     223              :         COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),     \
     224              :                     (PM_STATE_DT_INIT(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),), ())
     225              : 
     226              : /** @endcond */
     227              : 
     228              : /**
     229              :  * @brief Initializer for struct pm_state_info given a DT node identifier with
     230              :  * zephyr,power-state compatible.
     231              :  *
     232              :  * @param node_id A node identifier with compatible zephyr,power-state
     233              :  */
     234            1 : #define PM_STATE_INFO_DT_INIT(node_id)                                         \
     235              :         {                                                                      \
     236              :                 .state = PM_STATE_DT_INIT(node_id),                            \
     237              :                 .substate_id = DT_PROP_OR(node_id, substate_id, 0),            \
     238              :                 .min_residency_us = DT_PROP_OR(node_id, min_residency_us, 0),  \
     239              :                 .exit_latency_us = DT_PROP_OR(node_id, exit_latency_us, 0),    \
     240              :                 .pm_device_disabled = DT_PROP(node_id, zephyr_pm_device_disabled),    \
     241              :         }
     242              : 
     243              : /**
     244              :  * @brief Initializer for enum pm_state given a DT node identifier with
     245              :  * zephyr,power-state compatible.
     246              :  *
     247              :  * @param node_id A node identifier with compatible zephyr,power-state
     248              :  */
     249            1 : #define PM_STATE_DT_INIT(node_id) \
     250              :         DT_ENUM_IDX(node_id, power_state_name)
     251              : 
     252              : /**
     253              :  * @brief Obtain number of CPU power states supported and enabled by the given
     254              :  * CPU node identifier.
     255              :  *
     256              :  * @param node_id A CPU node identifier.
     257              :  * @return Number of supported and enabled CPU power states.
     258              :  */
     259            1 : #define DT_NUM_CPU_POWER_STATES(node_id)                                                           \
     260              :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, cpu_power_states),                                   \
     261              :                     (DT_FOREACH_PROP_ELEM_SEP(node_id, cpu_power_states, Z_DT_PHANDLE_01, (+))),   \
     262              :                     (0))
     263              : 
     264              : /**
     265              :  * @brief Initialize an array of struct pm_state_info with information from all
     266              :  * the states present and enabled in the given CPU node identifier.
     267              :  *
     268              :  * Example devicetree fragment:
     269              :  *
     270              :  * @code{.dts}
     271              :  *      cpus {
     272              :  *              ...
     273              :  *              cpu0: cpu@0 {
     274              :  *                      device_type = "cpu";
     275              :  *                      ...
     276              :  *                      cpu-power-states = <&state0 &state1>;
     277              :  *              };
     278              :  *
     279              :  *              power-states {
     280              :  *                      state0: state0 {
     281              :  *                              compatible = "zephyr,power-state";
     282              :  *                              power-state-name = "suspend-to-idle";
     283              :  *                              min-residency-us = <10000>;
     284              :  *                              exit-latency-us = <100>;
     285              :  *                      };
     286              :  *
     287              :  *                      state1: state1 {
     288              :  *                              compatible = "zephyr,power-state";
     289              :  *                              power-state-name = "suspend-to-ram";
     290              :  *                              min-residency-us = <50000>;
     291              :  *                              exit-latency-us = <500>;
     292              :  *                              zephyr,pm-device-disabled;
     293              :  *                      };
     294              :  *              };
     295              :  *      };
     296              : 
     297              :  * @endcode
     298              :  *
     299              :  * Example usage:
     300              :  *
     301              :  * @code{.c}
     302              :  * const struct pm_state_info states[] =
     303              :  *      PM_STATE_INFO_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0));
     304              :  * @endcode
     305              :  *
     306              :  * @param node_id A CPU node identifier.
     307              :  */
     308            1 : #define PM_STATE_INFO_LIST_FROM_DT_CPU(node_id)                                \
     309              :         {                                                                      \
     310              :                 LISTIFY(DT_PROP_LEN_OR(node_id, cpu_power_states, 0),          \
     311              :                         Z_PM_STATE_INFO_FROM_DT_CPU, (), node_id)              \
     312              :         }
     313              : 
     314              : /**
     315              :  * @brief Initialize an array of struct pm_state with information from all the
     316              :  * states present and enabled in the given CPU node identifier.
     317              :  *
     318              :  * Example devicetree fragment:
     319              :  *
     320              :  * @code{.dts}
     321              :  *      cpus {
     322              :  *              ...
     323              :  *              cpu0: cpu@0 {
     324              :  *                      device_type = "cpu";
     325              :  *                      ...
     326              :  *                      cpu-power-states = <&state0 &state1>;
     327              :  *              };
     328              :  *
     329              :  *              power-states {
     330              :  *                      state0: state0 {
     331              :  *                              compatible = "zephyr,power-state";
     332              :  *                              power-state-name = "suspend-to-idle";
     333              :  *                              min-residency-us = <10000>;
     334              :  *                              exit-latency-us = <100>;
     335              :  *                      };
     336              :  *
     337              :  *                      state1: state1 {
     338              :  *                              compatible = "zephyr,power-state";
     339              :  *                              power-state-name = "suspend-to-ram";
     340              :  *                              min-residency-us = <50000>;
     341              :  *                              exit-latency-us = <500>;
     342              :  *                      };
     343              :  *              };
     344              :  *      };
     345              :  * @endcode
     346              :  *
     347              :  * Example usage:
     348              :  *
     349              :  * @code{.c}
     350              :  * const enum pm_state states[] = PM_STATE_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0));
     351              :  * @endcode
     352              :  *
     353              :  * @param node_id A CPU node identifier.
     354              :  */
     355            1 : #define PM_STATE_LIST_FROM_DT_CPU(node_id)                                     \
     356              :         {                                                                      \
     357              :                 LISTIFY(DT_PROP_LEN_OR(node_id, cpu_power_states, 0),          \
     358              :                         Z_PM_STATE_FROM_DT_CPU, (), node_id)                   \
     359              :         }
     360              : 
     361              : 
     362              : #if defined(CONFIG_PM) || defined(__DOXYGEN__)
     363              : /**
     364              :  * Obtain information about all supported states by a CPU.
     365              :  *
     366              :  * @param cpu CPU index.
     367              :  * @param states Where to store the list of supported states.
     368              :  *
     369              :  * @return Number of supported states.
     370              :  */
     371            1 : uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states);
     372              : 
     373              : /**
     374              :  * Get power state structure.
     375              :  *
     376              :  * Function searches in all states assigned to the CPU and in disabled states.
     377              :  *
     378              :  * @param cpu CPU index.
     379              :  * @param state Power state.
     380              :  * @param substate_id Substate.
     381              :  *
     382              :  * @return Pointer to the power state structure or NULL if state is not found.
     383              :  */
     384            1 : const struct pm_state_info *pm_state_get(uint8_t cpu, enum pm_state state, uint8_t substate_id);
     385              : /**
     386              :  * @}
     387              :  */
     388              : 
     389              : #else  /* CONFIG_PM */
     390              : 
     391              : static inline uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states)
     392              : {
     393              :         ARG_UNUSED(cpu);
     394              :         ARG_UNUSED(states);
     395              : 
     396              :         return 0;
     397              : }
     398              : 
     399              : static inline const struct pm_state_info *pm_state_get(uint8_t cpu,
     400              :                                                        enum pm_state state,
     401              :                                                        uint8_t substate_id)
     402              : {
     403              :         ARG_UNUSED(cpu);
     404              :         ARG_UNUSED(state);
     405              :         ARG_UNUSED(substate_id);
     406              : 
     407              :         return NULL;
     408              : }
     409              : 
     410              : #endif /* CONFIG_PM */
     411              : 
     412              : #ifdef __cplusplus
     413              : }
     414              : #endif
     415              : 
     416              : #endif
        

Generated by: LCOV version 2.0-1