Prepare v2024.10
[platform/kernel/u-boot.git] / include / power-domain.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2016, NVIDIA CORPORATION.
4  */
5
6 #ifndef _POWER_DOMAIN_H
7 #define _POWER_DOMAIN_H
8
9 #include <linux/errno.h>
10
11 /**
12  * A power domain is a portion of an SoC or chip that is powered by a
13  * switchable source of power. In many cases, software has control over the
14  * power domain, and can turn the power source on or off. This is typically
15  * done to save power by powering off unused devices, or to enable software
16  * sequencing of initial powerup at boot. This API provides a means for
17  * drivers to turn power domains on and off.
18  *
19  * A driver that implements UCLASS_POWER_DOMAIN is a power domain controller or
20  * provider. A controller will often implement multiple separate power domains,
21  * since the hardware it manages often has this capability.
22  * power-domain-uclass.h describes the interface which power domain controllers
23  * must implement.
24  *
25  * Depending on the power domain controller hardware, changing the state of a
26  * power domain may require performing related operations on other resources.
27  * For example, some power domains may require certain clocks to be enabled
28  * whenever the power domain is powered on, or during the time when the power
29  * domain is transitioning state. These details are implementation-specific
30  * and should ideally be encapsulated entirely within the provider driver, or
31  * configured through mechanisms (e.g. device tree) that do not require client
32  * drivers to provide extra configuration information.
33  *
34  * Power domain consumers/clients are the drivers for HW modules within the
35  * power domain. This header file describes the API used by those drivers.
36  *
37  * In many cases, a single complex IO controller (e.g. a PCIe controller) will
38  * be the sole logic contained within a power domain. In such cases, it is
39  * logical for the relevant device driver to directly control that power
40  * domain. In other cases, multiple controllers, each with their own driver,
41  * may be contained in a single power domain. Any logic require to co-ordinate
42  * between drivers for these multiple controllers is beyond the scope of this
43  * API at present. Equally, this API does not define or implement any policy
44  * by which power domains are managed.
45  */
46
47 struct udevice;
48
49 /**
50  * struct power_domain - A handle to (allowing control of) a single power domain.
51  *
52  * Clients provide storage for power domain handles. The content of the
53  * structure is managed solely by the power domain API and power domain
54  * drivers. A power domain struct is initialized by "get"ing the power domain
55  * struct. The power domain struct is passed to all other power domain APIs to
56  * identify which power domain to operate upon.
57  *
58  * @dev: The device which implements the power domain.
59  * @id: The power domain ID within the provider.
60  * @priv: Private data corresponding to each power domain.
61  */
62 struct power_domain {
63         struct udevice *dev;
64         unsigned long id;
65         void *priv;
66 };
67
68 /**
69  * power_domain_get - Get/request the power domain for a device.
70  *
71  * This looks up and requests a power domain. Each device is assumed to have
72  * a single (or, at least one) power domain associated with it somehow, and
73  * that domain, or the first/default domain. The mapping of client device to
74  * provider power domain may be via device-tree properties, board-provided
75  * mapping tables, or some other mechanism.
76  *
77  * @dev:        The client device.
78  * @power_domain        A pointer to a power domain struct to initialize.
79  * Return: 0 if OK, or a negative error code.
80  */
81 #if CONFIG_IS_ENABLED(POWER_DOMAIN)
82 int power_domain_get(struct udevice *dev, struct power_domain *power_domain);
83 #else
84 static inline
85 int power_domain_get(struct udevice *dev, struct power_domain *power_domain)
86 {
87         return -ENOSYS;
88 }
89 #endif
90
91 /**
92  * power_domain_get_by_index - Get the indexed power domain for a device.
93  *
94  * @dev:                The client device.
95  * @power_domain:       A pointer to a power domain struct to initialize.
96  * @index:              Power domain index to be powered on.
97  *
98  * Return: 0 if OK, or a negative error code.
99  */
100 #if CONFIG_IS_ENABLED(POWER_DOMAIN)
101 int power_domain_get_by_index(struct udevice *dev,
102                               struct power_domain *power_domain, int index);
103 #else
104 static inline
105 int power_domain_get_by_index(struct udevice *dev,
106                               struct power_domain *power_domain, int index)
107 {
108         return -ENOSYS;
109 }
110 #endif
111
112 /**
113  * power_domain_get_by_name - Get the named power domain for a device.
114  *
115  * @dev:                The client device.
116  * @power_domain:       A pointer to a power domain struct to initialize.
117  * @name:               Power domain name to be powered on.
118  *
119  * Return: 0 if OK, or a negative error code.
120  */
121 #if CONFIG_IS_ENABLED(POWER_DOMAIN)
122 int power_domain_get_by_name(struct udevice *dev,
123                              struct power_domain *power_domain, const char *name);
124 #else
125 static inline
126 int power_domain_get_by_name(struct udevice *dev,
127                              struct power_domain *power_domain, const char *name)
128 {
129         return -ENOSYS;
130 }
131 #endif
132
133 /**
134  * power_domain_free - Free a previously requested power domain.
135  *
136  * @power_domain:       A power domain struct that was previously successfully
137  *              requested by power_domain_get().
138  * Return: 0 if OK, or a negative error code.
139  */
140 #if CONFIG_IS_ENABLED(POWER_DOMAIN)
141 int power_domain_free(struct power_domain *power_domain);
142 #else
143 static inline int power_domain_free(struct power_domain *power_domain)
144 {
145         return -ENOSYS;
146 }
147 #endif
148
149 /**
150  * power_domain_on - Enable power to a power domain.
151  *
152  * @power_domain:       A power domain struct that was previously successfully
153  *              requested by power_domain_get().
154  * Return: 0 if OK, or a negative error code.
155  */
156 #if CONFIG_IS_ENABLED(POWER_DOMAIN)
157 int power_domain_on(struct power_domain *power_domain);
158 #else
159 static inline int power_domain_on(struct power_domain *power_domain)
160 {
161         return -ENOSYS;
162 }
163 #endif
164
165 /**
166  * power_domain_off - Disable power to a power domain.
167  *
168  * @power_domain:       A power domain struct that was previously successfully
169  *              requested by power_domain_get().
170  * Return: 0 if OK, or a negative error code.
171  */
172 #if CONFIG_IS_ENABLED(POWER_DOMAIN)
173 int power_domain_off(struct power_domain *power_domain);
174 #else
175 static inline int power_domain_off(struct power_domain *power_domain)
176 {
177         return -ENOSYS;
178 }
179 #endif
180
181 /**
182  * dev_power_domain_on - Enable power domains for a device .
183  *
184  * @dev:                The client device.
185  *
186  * Return: 0 if OK, or a negative error code.
187  */
188 #if CONFIG_IS_ENABLED(OF_REAL) && CONFIG_IS_ENABLED(POWER_DOMAIN)
189 int dev_power_domain_on(struct udevice *dev);
190 #else
191 static inline int dev_power_domain_on(struct udevice *dev)
192 {
193         return 0;
194 }
195 #endif
196
197 /**
198  * dev_power_domain_off - Disable power domains for a device .
199  *
200  * @dev:                The client device.
201  *
202  * Return: 0 if OK, or a negative error code.
203  */
204 #if CONFIG_IS_ENABLED(OF_REAL) && CONFIG_IS_ENABLED(POWER_DOMAIN)
205 int dev_power_domain_off(struct udevice *dev);
206 #else
207 static inline int dev_power_domain_off(struct udevice *dev)
208 {
209         return 0;
210 }
211 #endif
212
213 #endif