xref: /rk3399_ARM-atf/drivers/ti/pd/ti_device.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 Initialization and Management
9  *
10  * This module provides core device initialization, deferred initialization
11  * support, and device lifecycle management for the device power management subsystem.
12  */
13 
14 #include <assert.h>
15 #include <errno.h>
16 #include <stddef.h>
17 
18 #include <common/debug.h>
19 #include <ti_clk.h>
20 #include <ti_device.h>
21 #include <ti_device_clk.h>
22 #include <ti_device_pm.h>
23 
24 /* True if deferred (read-write) initialization has been initiated. */
25 static bool devices_rw;
26 
ti_pm_devgroup_is_enabled(devgrp_t groups)27 bool ti_pm_devgroup_is_enabled(devgrp_t groups)
28 {
29 	return true;
30 }
31 
32 /**
33  * device_init() - Initialize a device
34  * @dev: The device to init.
35  *
36  * This performs the necessary device initialization step, including syncing
37  * the flags on the device with the real hardware state and calling the clock
38  * init function for each clock.
39  *
40  * Return: 0 on success, <0 on failure.
41  */
device_init(struct ti_device * dev)42 static int32_t device_init(struct ti_device *dev)
43 {
44 	const struct ti_dev_data *data;
45 	const struct ti_drv *drvp = NULL;
46 	uint16_t i;
47 	int32_t ret;
48 
49 	assert(dev != NULL);
50 
51 	data = ti_get_dev_data(dev);
52 	if (data == NULL) {
53 		return 0;
54 	}
55 
56 	if (((data->flags & TI_DEVD_FLAG_DRV_DATA) != 0U) &&
57 	    ((data->flags & TI_DEVD_FLAG_DO_INIT) != 0U)) {
58 		drvp = ti_to_drv_data(data)->drv;
59 	}
60 
61 	if ((drvp != NULL) && (drvp->pre_init != NULL)) {
62 		ret = drvp->pre_init(dev);
63 		if (ret != 0) {
64 			return ret;
65 		}
66 	}
67 
68 	if (devices_rw == false) {
69 		/* Defer remainder of init */
70 		return 0;
71 	}
72 
73 	ret = ti_soc_device_init(dev);
74 	if (ret != 0) {
75 		return ret;
76 	}
77 
78 	for (i = 0U; i < data->n_clocks; i++) {
79 		ti_device_clk_init(dev, i);
80 	}
81 
82 	/* Calling these multiple times for a deferred device has no effect */
83 	if (ti_device_get_state(dev) != 0U) {
84 		ti_device_set_state(dev, TI_DEV_POWER_ON_ENABLED_HOST_IDX, true);
85 		ti_device_set_retention(dev, true);
86 	}
87 
88 	if ((drvp != NULL) && (drvp->post_init != NULL)) {
89 		ret = drvp->post_init(dev);
90 		if (ret != 0) {
91 			return ret;
92 		}
93 	}
94 
95 	return 0;
96 }
97 
ti_devices_init(void)98 int32_t ti_devices_init(void)
99 {
100 	bool done;
101 	bool progress;
102 	bool contents;
103 	ti_dev_idx_t idx;
104 
105 	contents = false;
106 	do {
107 		struct ti_device *dev;
108 
109 		done = true;
110 		progress = false;
111 
112 		for (idx = 0U; idx < soc_device_count; idx++) {
113 			devgrp_t devgrp;
114 			int32_t ret;
115 
116 			dev = &soc_devices[idx];
117 			if (dev->initialized != 0U) {
118 				continue;
119 			}
120 
121 			if (soc_device_data_arr[idx] == NULL) {
122 				continue;
123 			}
124 
125 			/* Translate compressed internal representation to bitfield */
126 			devgrp = (devgrp_t) BIT(soc_device_data_arr[idx]->pm_devgrp - 1U);
127 
128 			if (ti_pm_devgroup_is_enabled(devgrp) == false) {
129 				continue;
130 			}
131 
132 			contents = true;
133 
134 			ret = device_init(dev);
135 			if (ret == -EAGAIN) {
136 				done = false;
137 				continue;
138 			}
139 
140 			if (ret < 0) {
141 				VERBOSE("ACTION FAIL: DEV_INIT dev_id=%d error=%d\n",
142 					idx, -ret);
143 			}
144 
145 			progress = true;
146 			dev->initialized = 1U;
147 		}
148 	} while (!done && progress);
149 
150 	if (devices_rw == true) {
151 		/* Only necessary after deferred initialization */
152 		ti_clk_drop_pwr_up_en();
153 	}
154 
155 	if ((progress == false) && (contents == true)) {
156 		/* We processed at least one device but didn't make progress */
157 		return -EAGAIN;
158 	}
159 
160 	return 0;
161 }
162 
ti_devices_init_rw(void)163 int32_t ti_devices_init_rw(void)
164 {
165 	if (devices_rw == false) {
166 		uint32_t i;
167 
168 		/*
169 		 * Force reinitialization of all devices to get deferred
170 		 * initialization.
171 		 */
172 		for (i = 0U; i < soc_device_count; i++) {
173 			struct ti_device *dev = &soc_devices[i];
174 
175 			dev->initialized = 0U;
176 		}
177 
178 		devices_rw = true;
179 
180 		/* Perform deferred initialization */
181 		return ti_devices_init();
182 	}
183 
184 	return 0;
185 }
186