xref: /rk3399_ARM-atf/drivers/ti/pd/ti_device_pm.c (revision a28114d66a6d43db4accef5fd5d6dab6c059e584)
1 /*
2  * Copyright (c) 2025-2026 Texas Instruments Incorporated - https://www.ti.com
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * Device Power Management
9  *
10  * This module handles the main device power management operations including
11  * device enable/disable, state management, retention control, and suspend handling.
12  */
13 
14 #include <assert.h>
15 
16 #include <ti_device.h>
17 #include <ti_device_clk.h>
18 #include <ti_device_pm.h>
19 
20 /**
21  * device_enable() - Enable a device.
22  * @dev: The device to enable.
23  *
24  * Performs the steps necessary to enable a device.
25  */
device_enable(struct ti_device * dev)26 static void device_enable(struct ti_device *dev)
27 {
28 	const struct ti_dev_data *data;
29 	uint16_t i;
30 
31 	assert(dev != NULL);
32 
33 	data = ti_get_dev_data(dev);
34 
35 	for (i = 0U; i < data->n_clocks; i++) {
36 		ti_device_clk_enable(dev, i);
37 	}
38 	ti_soc_device_enable(dev);
39 }
40 
41 /**
42  * ti_device_disable() - Disables a device.
43  * @device: The device to modify.
44  * @domain_reset: True if the device is being disabled due to a domain reset.
45  *
46  * Performs the steps necessary to disable a device.
47  */
ti_device_disable(struct ti_device * dev,bool domain_reset)48 void ti_device_disable(struct ti_device *dev, bool domain_reset)
49 {
50 	const struct ti_dev_data *data;
51 	int32_t i;
52 
53 	assert(dev != NULL);
54 
55 	data = ti_get_dev_data(dev);
56 
57 	ti_soc_device_disable(dev, domain_reset);
58 
59 	for (i = (int32_t) data->n_clocks - 1; i >= 0; i--) {
60 		ti_device_clk_disable(dev, (uint16_t) i);
61 	}
62 }
63 
64 /**
65  * ti_device_clear_flags() - Clear device initialization flags.
66  * @dev: The device to modify.
67  */
ti_device_clear_flags(struct ti_device * dev)68 void ti_device_clear_flags(struct ti_device *dev)
69 {
70 	assert(dev != NULL);
71 
72 	ti_soc_device_clear_flags(dev);
73 }
74 
75 /**
76  * ti_device_set_state() - Set device enabled state.
77  * @device_ptr: The device to modify.
78  * @host_idx: Index of the host making the request.
79  * @enable: True to enable the device, false to disable.
80  */
ti_device_set_state(struct ti_device * device_ptr,uint8_t host_idx,bool enable)81 void ti_device_set_state(struct ti_device *device_ptr, uint8_t host_idx, bool enable)
82 {
83 	bool was_enabled;
84 	bool is_enabled;
85 
86 	assert(device_ptr != NULL);
87 	assert((TI_DEV_FLAG_ENABLED(host_idx) & TI_DEV_FLAG_ENABLED_MASK) != 0UL);
88 
89 	was_enabled = (device_ptr->flags & TI_DEV_FLAG_ENABLED_MASK) != 0UL;
90 
91 	if (enable) {
92 		device_ptr->flags |= (uint32_t)TI_DEV_FLAG_ENABLED(host_idx);
93 	} else {
94 		device_ptr->flags &= ~(uint32_t)TI_DEV_FLAG_ENABLED(host_idx);
95 	}
96 
97 	/*
98 	 * As soon as any host gets or puts a device, we drop the power
99 	 * on enabled flag.
100 	 */
101 	if (host_idx != TI_DEV_POWER_ON_ENABLED_HOST_IDX) {
102 		device_ptr->flags &= ~(uint32_t)TI_DEV_FLAG_POWER_ON_ENABLED;
103 	}
104 
105 	is_enabled = (device_ptr->flags & TI_DEV_FLAG_ENABLED_MASK) != 0UL;
106 	if (was_enabled != is_enabled) {
107 		if (is_enabled) {
108 			device_enable(device_ptr);
109 		} else {
110 			ti_device_disable(device_ptr, false);
111 		}
112 	}
113 }
114 
115 /**
116  * ti_device_set_retention() - Enable or disable device retention.
117  * @device_ptr: The device to modify.
118  * @retention: True to enable retention, false to disable.
119  */
ti_device_set_retention(struct ti_device * device_ptr,bool retention)120 void ti_device_set_retention(struct ti_device *device_ptr, bool retention)
121 {
122 	bool is_retention;
123 
124 	assert(device_ptr != NULL);
125 
126 	is_retention = ((device_ptr->flags & TI_DEV_FLAG_RETENTION) != 0U);
127 
128 	if (retention == is_retention) {
129 		return;
130 	}
131 
132 	if (retention) {
133 		device_ptr->flags |= (uint32_t)TI_DEV_FLAG_RETENTION;
134 		ti_soc_device_ret_enable(device_ptr);
135 	} else {
136 		device_ptr->flags &= ~(uint32_t)TI_DEV_FLAG_RETENTION;
137 		ti_soc_device_ret_disable(device_ptr);
138 	}
139 }
140