LCOV - code coverage report
Current view: top level - zephyr/pm - state.h Hit Total Coverage
Test: new.info Lines: 15 17 88.2 %
Date: 2024-12-22 00:14:23

          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             :  * @}
     375             :  */
     376             : 
     377             : #else  /* CONFIG_PM */
     378             : 
     379             : static inline uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states)
     380             : {
     381             :         ARG_UNUSED(cpu);
     382             :         ARG_UNUSED(states);
     383             : 
     384             :         return 0;
     385             : }
     386             : 
     387             : #endif /* CONFIG_PM */
     388             : 
     389             : #ifdef __cplusplus
     390             : }
     391             : #endif
     392             : 
     393             : #endif

Generated by: LCOV version 1.14