1.. _pm-system:
2
3System Power Management
4#######################
5
6Introduction
7************
8
9The kernel enters the idle state when it has nothing to schedule.
10Enabling :kconfig:option:`CONFIG_PM` allows the kernel to call upon the
11power management subsystem to put an idle system into one of the supported power states.
12The kernel requests an amount of time it would like to suspend, then the PM subsystem decides
13the appropriate power state to transition to based on the configured power management policy.
14
15It is the application's responsibility to set up a wake-up event.
16A wake-up event will typically be an interrupt triggered by an SoC peripheral module.
17Examples include a SysTick, RTC, counter, or GPIO.
18Keep in mind that depending on the SoC and the power mode in question,
19not all peripherals may be active, and therefore
20some wake-up sources may not be usable in all power modes.
21
22The following diagram describes system power management:
23
24.. graphviz::
25   :caption: System power management
26
27   digraph G {
28       compound=true
29       node [height=1.2 style=rounded]
30
31       lock [label="Lock interruptions"]
32       config_pm [label="CONFIG_PM" shape=diamond style="rounded,dashed"]
33       forced_state [label="state forced ?", shape=diamond style="rounded,dashed"]
34       config_system_managed_device_pm [label="CONFIG_PM_DEVICE" shape=diamond style="rounded,dashed"]
35       config_system_managed_device_pm2 [label="CONFIG_PM_DEVICE" shape=diamond style="rounded,dashed"]
36       pm_policy [label="Check policy manager\nfor a power state "]
37       pm_suspend_devices [label="Suspend\ndevices"]
38       pm_resume_devices [label="Resume\ndevices"]
39       pm_state_set [label="Change power state\n(SoC API)" style="rounded,bold"]
40       pm_system_resume [label="Finish wake-up\n(SoC API)\n(restore interruptions)" style="rounded,bold"]
41       k_cpu_idle [label="k_cpu_idle()"]
42
43       subgraph cluster_0 {
44              style=invisible;
45              lock -> config_pm
46       }
47
48       subgraph cluster_1 {
49                style=dashed
50                label = "pm_system_suspend()"
51
52                forced_state -> config_system_managed_device_pm [label="yes"]
53                forced_state -> pm_policy [label="no"]
54                pm_policy -> config_system_managed_device_pm
55                config_system_managed_device_pm -> pm_state_set:e [label="no"]
56                config_system_managed_device_pm -> pm_suspend_devices [label="yes"]
57                pm_suspend_devices -> pm_state_set
58                pm_state_set -> config_system_managed_device_pm2
59                config_system_managed_device_pm2 -> pm_resume_devices [label="yes"]
60                config_system_managed_device_pm2 -> pm_system_resume [label="no"]
61                pm_resume_devices -> pm_system_resume
62        }
63
64        {rankdir=LR k_cpu_idle; forced_state}
65        pm_policy -> k_cpu_idle [label="PM_STATE_ACTIVE\n(no power state meet requirements)"]
66        config_pm -> k_cpu_idle [label="no"]
67        config_pm -> forced_state [label="yes" lhead="cluster_1"]
68        pm_system_resume:e -> lock:e [constraint=false lhed="cluster_0"]
69   }
70
71
72Power States
73============
74
75The power management subsystem defines a set of states described by the
76power consumption and context retention associated with each of them.
77
78The set of power states is defined by :c:enum:`pm_state`. In general, lower power states
79(higher index in the enum) will offer greater power savings and have higher wake latencies.
80
81Power Management Policies
82=========================
83
84The power management subsystem supports the following power management policies:
85
86* Residency based
87* Application defined
88
89The policy manager is the component of the power management subsystem responsible
90for deciding which power state the system should transition to.
91The policy manager can only choose between states that have been defined for the platform.
92Other constraints placed upon the decision may include locks disallowing certain power states,
93or various kinds of minimum and maximum latency values, depending on the policy.
94
95More details on the states definition can be found in the
96:dtcompatible:`zephyr,power-state` binding documentation.
97
98Residency
99---------
100
101Under the residency policy, the system will enter the power state which offers the highest
102power savings, with the constraint that the sum of the minimum residency value (see
103:dtcompatible:`zephyr,power-state`) and the latency to exit the mode must be
104less than or equal to the system idle time duration scheduled by the kernel.
105
106Thus the core logic can be summarized with the following expression:
107
108.. code-block:: c
109
110   if (time_to_next_scheduled_event >= (state.min_residency_us + state.exit_latency)) {
111      return state
112   }
113
114Application
115-----------
116
117The application defines the power management policy by implementing the
118:c:func:`pm_policy_next_state` function. In this policy, the application is free
119to decide which power state the system should transition to based on the
120remaining time until the next scheduled timeout.
121
122An example of an application that defines its own policy can be found in
123:zephyr_file:`tests/subsys/pm/power_mgmt/`.
124
125.. _pm-policy-power-states:
126
127Policy and Power States
128------------------------
129
130The power management subsystem allows different Zephyr components and
131applications to configure the policy manager to block the system from transitioning
132into certain power states. This can be used by devices when executing tasks in
133background to prevent the system from going to a specific state where it would
134lose context. See :c:func:`pm_policy_state_lock_get`.
135
136Examples
137========
138
139Some helpful examples showing different power management features:
140
141* :zephyr_file:`samples/boards/st/power_mgmt/blinky/`
142* :zephyr_file:`samples/boards/espressif/deep_sleep/`
143* :zephyr_file:`samples/subsys/pm/device_pm/`
144* :zephyr_file:`tests/subsys/pm/power_mgmt/`
145* :zephyr_file:`tests/subsys/pm/power_mgmt_soc/`
146* :zephyr_file:`tests/subsys/pm/power_states_api/`
147