1.. _pm-power-domain:
2
3Power Domain
4############
5
6Introduction
7************
8
9The Zephyr power domain abstraction is designed to support groupings of devices
10powered by a common source to be notified of power source state changes in a
11generic fashion. Application code that is using device A does not need to know
12that device B is on the same power domain and should also be configured into a
13low power state.
14
15Power domains are optional on Zephyr, to enable this feature the
16option :kconfig:option:`CONFIG_PM_DEVICE_POWER_DOMAIN` has to be set.
17
18When a power domain turns itself on or off, it is the responsibility of the
19power domain to notify all devices using it through their power management
20callback called with
21:c:enumerator:`PM_DEVICE_ACTION_TURN_ON` or
22:c:enumerator:`PM_DEVICE_ACTION_TURN_OFF` respectively. This
23work flow is illustrated in the diagram below.
24
25.. _pm-domain-work-flow:
26
27.. graphviz::
28   :caption: Power domain work flow
29
30   digraph {
31       rankdir="TB";
32
33       action [style=invis]
34       {
35           rank = same;
36           rankdir="LR"
37           devA [label="gpio0"]
38           devB [label="gpio1"]
39       }
40       domain [label="gpio_domain"]
41
42      action -> devA [label="pm_device_get()"]
43      devA:se -> domain:n [label="pm_device_get()"]
44
45      domain -> devB [label="action_cb(PM_DEVICE_ACTION_TURN_ON)"]
46      domain:sw -> devA:sw [label="action_cb(PM_DEVICE_ACTION_TURN_ON)"]
47   }
48
49Internal Power Domains
50----------------------
51
52Most of the devices in an SoC have independent power control that can
53be turned on or off to reduce power consumption. But there is a
54significant amount of static current leakage that can't be controlled
55only using device power management. To solve this problem, SoCs
56normally are divided into several regions grouping devices that
57are generally used together, so that an unused region can be
58completely powered off to eliminate this leakage. These regions are
59called "power domains", can be present in a hierarchy and can be
60nested.
61
62External Power Domains
63----------------------
64
65Devices external to a SoC can be powered from sources other than the main power
66source of the SoC. These external sources are typically a switch, a regulator,
67or a dedicated power IC. Multiple devices can be powered from the same source,
68and this grouping of devices is typically called a "power domain".
69
70Placing devices on power domains can be done for a variety of reasons,
71including to enable devices with high power consumption in low power mode to be
72completely turned off when not in use.
73
74Implementation guidelines
75*************************
76
77In a first place, a device that acts as a power domain needs to
78declare compatible with ``power-domain``. Taking
79:ref:`pm-domain-work-flow` as example, the following code defines a
80domain called ``gpio_domain``.
81
82.. code-block:: devicetree
83
84	gpio_domain: gpio_domain@4 {
85		compatible = "power-domain";
86		...
87	};
88
89A power domain needs to implement the PM action callback used by the
90PM subsystem to turn devices on and off.
91
92.. code-block:: c
93
94    static int mydomain_pm_action(const struct device *dev,
95                               enum pm_device_action *action)
96    {
97        switch (action) {
98        case PM_DEVICE_ACTION_RESUME:
99            /* resume the domain */
100            ...
101            /* notify children domain is now powered */
102            pm_device_children_action_run(dev, PM_DEVICE_ACTION_TURN_ON, NULL);
103            break;
104        case PM_DEVICE_ACTION_SUSPEND:
105            /* notify children domain is going down */
106            pm_device_children_action_run(dev, PM_DEVICE_ACTION_TURN_OFF, NULL);
107            /* suspend the domain */
108            ...
109            break;
110        case PM_DEVICE_ACTION_TURN_ON:
111            /* turn on the domain (e.g. setup control pins to disabled) */
112            ...
113            break;
114        case PM_DEVICE_ACTION_TURN_OFF:
115            /* turn off the domain (e.g. reset control pins to default state) */
116            ...
117            break;
118        default:
119            return -ENOTSUP;
120        }
121
122        return 0;
123    }
124
125Devices belonging to this device can be declared referring it in the
126``power-domain`` node's property. The example below declares devices
127``gpio0`` and ``gpio1`` belonging to domain ``gpio_domain```.
128
129.. code-block:: devicetree
130
131        &gpio0 {
132                compatible = "zephyr,gpio-emul";
133                gpio-controller;
134                power-domain = <&gpio_domain>;
135        };
136
137        &gpio1 {
138                compatible = "zephyr,gpio-emul";
139                gpio-controller;
140                power-domain = <&gpio_domain>;
141        };
142
143All devices under a domain will be notified when the domain changes
144state. These notifications are sent as actions in the device PM action
145callback and can be used by them to do any additional work required.
146They can safely be ignored though.
147
148.. code-block:: c
149
150    static int mydev_pm_action(const struct device *dev,
151                               enum pm_device_action *action)
152    {
153        switch (action) {
154        case PM_DEVICE_ACTION_SUSPEND:
155            /* suspend the device */
156            ...
157            break;
158        case PM_DEVICE_ACTION_RESUME:
159            /* resume the device */
160            ...
161            break;
162        case PM_DEVICE_ACTION_TURN_ON:
163            /* configure the device into low power mode */
164            ...
165            break;
166        case PM_DEVICE_ACTION_TURN_OFF:
167            /* prepare the device for power down */
168            ...
169            break;
170        default:
171            return -ENOTSUP;
172        }
173
174        return 0;
175    }
176
177.. note::
178
179   It is responsibility of driver or the application to set the domain as
180   "wakeup" source if a device depending on it is used as "wakeup" source.
181