xref: /openbmc/u-boot/include/power-domain.h (revision d1e15041)
183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0 */
261f5ddcbSStephen Warren /*
361f5ddcbSStephen Warren  * Copyright (c) 2016, NVIDIA CORPORATION.
461f5ddcbSStephen Warren  */
561f5ddcbSStephen Warren 
661f5ddcbSStephen Warren #ifndef _POWER_DOMAIN_H
761f5ddcbSStephen Warren #define _POWER_DOMAIN_H
861f5ddcbSStephen Warren 
961f5ddcbSStephen Warren /**
1061f5ddcbSStephen Warren  * A power domain is a portion of an SoC or chip that is powered by a
1161f5ddcbSStephen Warren  * switchable source of power. In many cases, software has control over the
1261f5ddcbSStephen Warren  * power domain, and can turn the power source on or off. This is typically
1361f5ddcbSStephen Warren  * done to save power by powering off unused devices, or to enable software
1461f5ddcbSStephen Warren  * sequencing of initial powerup at boot. This API provides a means for
1561f5ddcbSStephen Warren  * drivers to turn power domains on and off.
1661f5ddcbSStephen Warren  *
1761f5ddcbSStephen Warren  * A driver that implements UCLASS_POWER_DOMAIN is a power domain controller or
1861f5ddcbSStephen Warren  * provider. A controller will often implement multiple separate power domains,
1961f5ddcbSStephen Warren  * since the hardware it manages often has this capability.
2061f5ddcbSStephen Warren  * power-domain-uclass.h describes the interface which power domain controllers
2161f5ddcbSStephen Warren  * must implement.
2261f5ddcbSStephen Warren  *
2361f5ddcbSStephen Warren  * Depending on the power domain controller hardware, changing the state of a
2461f5ddcbSStephen Warren  * power domain may require performing related operations on other resources.
2561f5ddcbSStephen Warren  * For example, some power domains may require certain clocks to be enabled
2661f5ddcbSStephen Warren  * whenever the power domain is powered on, or during the time when the power
2761f5ddcbSStephen Warren  * domain is transitioning state. These details are implementation-specific
2861f5ddcbSStephen Warren  * and should ideally be encapsulated entirely within the provider driver, or
2961f5ddcbSStephen Warren  * configured through mechanisms (e.g. device tree) that do not require client
3061f5ddcbSStephen Warren  * drivers to provide extra configuration information.
3161f5ddcbSStephen Warren  *
3261f5ddcbSStephen Warren  * Power domain consumers/clients are the drivers for HW modules within the
3361f5ddcbSStephen Warren  * power domain. This header file describes the API used by those drivers.
3461f5ddcbSStephen Warren  *
3561f5ddcbSStephen Warren  * In many cases, a single complex IO controller (e.g. a PCIe controller) will
3661f5ddcbSStephen Warren  * be the sole logic contained within a power domain. In such cases, it is
3761f5ddcbSStephen Warren  * logical for the relevant device driver to directly control that power
3861f5ddcbSStephen Warren  * domain. In other cases, multiple controllers, each with their own driver,
3961f5ddcbSStephen Warren  * may be contained in a single power domain. Any logic require to co-ordinate
4061f5ddcbSStephen Warren  * between drivers for these multiple controllers is beyond the scope of this
4161f5ddcbSStephen Warren  * API at present. Equally, this API does not define or implement any policy
4261f5ddcbSStephen Warren  * by which power domains are managed.
4361f5ddcbSStephen Warren  */
4461f5ddcbSStephen Warren 
4561f5ddcbSStephen Warren struct udevice;
4661f5ddcbSStephen Warren 
4761f5ddcbSStephen Warren /**
4861f5ddcbSStephen Warren  * struct power_domain - A handle to (allowing control of) a single power domain.
4961f5ddcbSStephen Warren  *
5061f5ddcbSStephen Warren  * Clients provide storage for power domain handles. The content of the
5161f5ddcbSStephen Warren  * structure is managed solely by the power domain API and power domain
5261f5ddcbSStephen Warren  * drivers. A power domain struct is initialized by "get"ing the power domain
5361f5ddcbSStephen Warren  * struct. The power domain struct is passed to all other power domain APIs to
5461f5ddcbSStephen Warren  * identify which power domain to operate upon.
5561f5ddcbSStephen Warren  *
5661f5ddcbSStephen Warren  * @dev: The device which implements the power domain.
5761f5ddcbSStephen Warren  * @id: The power domain ID within the provider.
5861f5ddcbSStephen Warren  *
5961f5ddcbSStephen Warren  * Currently, the power domain API assumes that a single integer ID is enough
6061f5ddcbSStephen Warren  * to identify and configure any power domain for any power domain provider. If
6161f5ddcbSStephen Warren  * this assumption becomes invalid in the future, the struct could be expanded
6261f5ddcbSStephen Warren  * to either (a) add more fields to allow power domain providers to store
6361f5ddcbSStephen Warren  * additional information, or (b) replace the id field with an opaque pointer,
6461f5ddcbSStephen Warren  * which the provider would dynamically allocate during its .of_xlate op, and
6561f5ddcbSStephen Warren  * process during is .request op. This may require the addition of an extra op
6661f5ddcbSStephen Warren  * to clean up the allocation.
6761f5ddcbSStephen Warren  */
6861f5ddcbSStephen Warren struct power_domain {
6961f5ddcbSStephen Warren 	struct udevice *dev;
7061f5ddcbSStephen Warren 	/*
7161f5ddcbSStephen Warren 	 * Written by of_xlate. We assume a single id is enough for now. In the
7261f5ddcbSStephen Warren 	 * future, we might add more fields here.
7361f5ddcbSStephen Warren 	 */
7461f5ddcbSStephen Warren 	unsigned long id;
7561f5ddcbSStephen Warren };
7661f5ddcbSStephen Warren 
7761f5ddcbSStephen Warren /**
7861f5ddcbSStephen Warren  * power_domain_get - Get/request the power domain for a device.
7961f5ddcbSStephen Warren  *
8061f5ddcbSStephen Warren  * This looks up and requests a power domain. Each device is assumed to have
8161f5ddcbSStephen Warren  * a single (or, at least one) power domain associated with it somehow, and
8261f5ddcbSStephen Warren  * that domain, or the first/default domain. The mapping of client device to
8361f5ddcbSStephen Warren  * provider power domain may be via device-tree properties, board-provided
8461f5ddcbSStephen Warren  * mapping tables, or some other mechanism.
8561f5ddcbSStephen Warren  *
8661f5ddcbSStephen Warren  * @dev:	The client device.
8761f5ddcbSStephen Warren  * @power_domain	A pointer to a power domain struct to initialize.
8861f5ddcbSStephen Warren  * @return 0 if OK, or a negative error code.
8961f5ddcbSStephen Warren  */
9058d3de19SPeng Fan #if CONFIG_IS_ENABLED(POWER_DOMAIN)
9161f5ddcbSStephen Warren int power_domain_get(struct udevice *dev, struct power_domain *power_domain);
9258d3de19SPeng Fan #else
9358d3de19SPeng Fan static inline
power_domain_get(struct udevice * dev,struct power_domain * power_domain)9458d3de19SPeng Fan int power_domain_get(struct udevice *dev, struct power_domain *power_domain)
9558d3de19SPeng Fan {
9658d3de19SPeng Fan 	return -ENOSYS;
9758d3de19SPeng Fan }
9858d3de19SPeng Fan #endif
9961f5ddcbSStephen Warren 
10061f5ddcbSStephen Warren /**
101*2618cf36SLokesh Vutla  * power_domain_get_by_index - Get the indexed power domain for a device.
102*2618cf36SLokesh Vutla  *
103*2618cf36SLokesh Vutla  * @dev:		The client device.
104*2618cf36SLokesh Vutla  * @power_domain:	A pointer to a power domain struct to initialize.
105*2618cf36SLokesh Vutla  * @index:		Power domain index to be powered on.
106*2618cf36SLokesh Vutla  *
107*2618cf36SLokesh Vutla  * @return 0 if OK, or a negative error code.
108*2618cf36SLokesh Vutla  */
109*2618cf36SLokesh Vutla #if CONFIG_IS_ENABLED(POWER_DOMAIN)
110*2618cf36SLokesh Vutla int power_domain_get_by_index(struct udevice *dev,
111*2618cf36SLokesh Vutla 			      struct power_domain *power_domain, int index);
112*2618cf36SLokesh Vutla #else
113*2618cf36SLokesh Vutla static inline
power_domain_get_by_index(struct udevice * dev,struct power_domain * power_domain,int index)114*2618cf36SLokesh Vutla int power_domain_get_by_index(struct udevice *dev,
115*2618cf36SLokesh Vutla 			      struct power_domain *power_domain, int index)
116*2618cf36SLokesh Vutla {
117*2618cf36SLokesh Vutla 	return -ENOSYS;
118*2618cf36SLokesh Vutla }
119*2618cf36SLokesh Vutla #endif
120*2618cf36SLokesh Vutla 
121*2618cf36SLokesh Vutla /**
12261f5ddcbSStephen Warren  * power_domain_free - Free a previously requested power domain.
12361f5ddcbSStephen Warren  *
12461f5ddcbSStephen Warren  * @power_domain:	A power domain struct that was previously successfully
12561f5ddcbSStephen Warren  *		requested by power_domain_get().
12661f5ddcbSStephen Warren  * @return 0 if OK, or a negative error code.
12761f5ddcbSStephen Warren  */
12858d3de19SPeng Fan #if CONFIG_IS_ENABLED(POWER_DOMAIN)
12961f5ddcbSStephen Warren int power_domain_free(struct power_domain *power_domain);
13058d3de19SPeng Fan #else
power_domain_free(struct power_domain * power_domain)13158d3de19SPeng Fan static inline int power_domain_free(struct power_domain *power_domain)
13258d3de19SPeng Fan {
13358d3de19SPeng Fan 	return -ENOSYS;
13458d3de19SPeng Fan }
13558d3de19SPeng Fan #endif
13661f5ddcbSStephen Warren 
13761f5ddcbSStephen Warren /**
13861f5ddcbSStephen Warren  * power_domain_on - Enable power to a power domain.
13961f5ddcbSStephen Warren  *
14061f5ddcbSStephen Warren  * @power_domain:	A power domain struct that was previously successfully
14161f5ddcbSStephen Warren  *		requested by power_domain_get().
14261f5ddcbSStephen Warren  * @return 0 if OK, or a negative error code.
14361f5ddcbSStephen Warren  */
14458d3de19SPeng Fan #if CONFIG_IS_ENABLED(POWER_DOMAIN)
14561f5ddcbSStephen Warren int power_domain_on(struct power_domain *power_domain);
14658d3de19SPeng Fan #else
power_domain_on(struct power_domain * power_domain)14758d3de19SPeng Fan static inline int power_domain_on(struct power_domain *power_domain)
14858d3de19SPeng Fan {
14958d3de19SPeng Fan 	return -ENOSYS;
15058d3de19SPeng Fan }
15158d3de19SPeng Fan #endif
15261f5ddcbSStephen Warren 
15361f5ddcbSStephen Warren /**
15461f5ddcbSStephen Warren  * power_domain_off - Disable power ot a power domain.
15561f5ddcbSStephen Warren  *
15661f5ddcbSStephen Warren  * @power_domain:	A power domain struct that was previously successfully
15761f5ddcbSStephen Warren  *		requested by power_domain_get().
15861f5ddcbSStephen Warren  * @return 0 if OK, or a negative error code.
15961f5ddcbSStephen Warren  */
16058d3de19SPeng Fan #if CONFIG_IS_ENABLED(POWER_DOMAIN)
16161f5ddcbSStephen Warren int power_domain_off(struct power_domain *power_domain);
16258d3de19SPeng Fan #else
power_domain_off(struct power_domain * power_domain)16358d3de19SPeng Fan static inline int power_domain_off(struct power_domain *power_domain)
16458d3de19SPeng Fan {
16558d3de19SPeng Fan 	return -ENOSYS;
16658d3de19SPeng Fan }
16758d3de19SPeng Fan #endif
16861f5ddcbSStephen Warren 
16961f5ddcbSStephen Warren #endif
170