xref: /optee_os/core/drivers/regulator/stm32_vrefbuf.c (revision 8d541aee2e0fe7242ec6fb57aabc7a04471b2237)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2021-2023, STMicroelectronics
4  */
5 
6 #include <drivers/clk.h>
7 #include <drivers/clk_dt.h>
8 #include <drivers/regulator.h>
9 #include <drivers/stm32_vrefbuf.h>
10 #include <initcall.h>
11 #include <io.h>
12 #include <keep.h>
13 #include <kernel/delay.h>
14 #include <kernel/pm.h>
15 #include <libfdt.h>
16 #include <mm/core_memprot.h>
17 
18 /* STM32 VREFBUF registers */
19 #define VREFBUF_CSR			U(0)
20 
21 /* STM32 VREFBUF CSR bitfields */
22 
23 /* VRS bit 3 is unused because the voltage is not specified */
24 #define VREFBUF_CSR_VRS			GENMASK_32(5, 4)
25 #define VREFBUF_CSR_VRS_SHIFT		U(4)
26 #define INV_VRS(x)			((~(x)) & VREFBUF_CSR_VRS)
27 
28 #define VREFBUF_CSR_VRR			BIT(3)
29 #define VREFBUF_CSR_HIZ			BIT(1)
30 #define VREFBUF_CSR_ENVR			BIT(0)
31 
32 #define TIMEOUT_US_10MS			U(10 * 1000)
33 #define TIMEOUT_US_1MS			U(1 * 1000)
34 
35 #define VREFBUF_LEVELS_COUNT		U(4)
36 
37 /*
38  * struct vrefbuf_compat - Compatibility data
39  * @voltages: Voltage levels supported
40  */
41 struct vrefbuf_compat {
42 	int voltages[VREFBUF_LEVELS_COUNT];
43 };
44 
45 /*
46  * struct vrefbuf_regul - VREFBUF regulator
47  * @base: IO memory base address
48  * @clock: VREFBUF access bus clock
49  * @regulator: Preallocated instance for the regulator
50  * @compat: Compatibility data
51  * @voltages_desc: Supported voltage level description
52  * @voltages_level: Supplorted levels, must follow @voltages_desc
53  */
54 struct vrefbuf_regul {
55 	vaddr_t base;
56 	struct clk *clock;
57 	uint64_t disable_timeout;
58 	struct regulator regulator;
59 	const struct vrefbuf_compat *compat;
60 	struct regulator_voltages voltages_desc;
61 	int supported_levels[VREFBUF_LEVELS_COUNT];
62 };
63 
64 static const struct vrefbuf_compat stm32mp15_vrefbuf_compat = {
65 	.voltages = {
66 		/* Matches resp. VRS = 011b, 010b, 001b, 000b */
67 		1500000, 1800000, 2048000, 2500000,
68 	},
69 };
70 
71 static const struct vrefbuf_compat stm32mp13_vrefbuf_compat = {
72 	.voltages = {
73 		/* Matches resp. VRS = 011b, 010b, 001b, 000b */
74 		1650000, 1800000, 2048000, 2500000,
75 	},
76 };
77 
78 /* Expect at most 1 instance */
79 static struct vrefbuf_regul *stm32_vrefbuf;
80 
81 struct regulator *stm32_vrefbuf_regulator(void)
82 {
83 	if (!stm32_vrefbuf)
84 		return NULL;
85 
86 	return &stm32_vrefbuf->regulator;
87 }
88 
89 static struct vrefbuf_regul *regulator_to_vr(struct regulator *regulator)
90 {
91 	return container_of(regulator, struct vrefbuf_regul, regulator);
92 }
93 
94 static TEE_Result vrefbuf_wait_ready(struct vrefbuf_regul *vr)
95 {
96 	uint32_t val = 0;
97 
98 	if (IO_READ32_POLL_TIMEOUT(vr->base + VREFBUF_CSR, val,
99 				   val & VREFBUF_CSR_VRR, 0, TIMEOUT_US_10MS))
100 		return TEE_ERROR_GENERIC;
101 
102 	return TEE_SUCCESS;
103 }
104 
105 static TEE_Result vrefbuf_set_state(struct regulator *regulator, bool enable)
106 {
107 	struct vrefbuf_regul *vr = regulator_to_vr(regulator);
108 	TEE_Result res = TEE_ERROR_GENERIC;
109 
110 	res = clk_enable(vr->clock);
111 	if (res)
112 		return res;
113 
114 	if (enable) {
115 		io_clrbits32(vr->base + VREFBUF_CSR, VREFBUF_CSR_HIZ);
116 
117 		/*
118 		 * If first enable after boot or if it was disabled since
119 		 * less than 1ms, then wait for 1ms in pull down mode to
120 		 * avoid an overshoot.
121 		 */
122 		if (!vr->disable_timeout ||
123 		    !timeout_elapsed(vr->disable_timeout))
124 			udelay(1000);
125 
126 		io_setbits32(vr->base + VREFBUF_CSR, VREFBUF_CSR_ENVR);
127 
128 		if (vrefbuf_wait_ready(vr) != TEE_SUCCESS) {
129 			clk_disable(vr->clock);
130 
131 			return TEE_ERROR_GENERIC;
132 		}
133 	} else {
134 		io_clrbits32(vr->base + VREFBUF_CSR, VREFBUF_CSR_ENVR);
135 
136 		vr->disable_timeout = timeout_init_us(TIMEOUT_US_1MS);
137 	}
138 
139 	clk_disable(vr->clock);
140 
141 	return TEE_SUCCESS;
142 }
143 
144 static TEE_Result vrefbuf_get_state(struct regulator *regulator, bool *enabled)
145 {
146 	struct vrefbuf_regul *vr = regulator_to_vr(regulator);
147 	TEE_Result res = TEE_ERROR_GENERIC;
148 
149 	res = clk_enable(vr->clock);
150 	if (res)
151 		return res;
152 
153 	*enabled = io_read32(vr->base + VREFBUF_CSR) & VREFBUF_CSR_VRR;
154 
155 	clk_disable(vr->clock);
156 
157 	return TEE_SUCCESS;
158 }
159 
160 static TEE_Result vrefbuf_get_voltage(struct regulator *regulator,
161 				      int *level_uv)
162 {
163 	struct vrefbuf_regul *vr = regulator_to_vr(regulator);
164 	TEE_Result res = TEE_ERROR_GENERIC;
165 	uint32_t index = 0;
166 
167 	res = clk_enable(vr->clock);
168 	if (res)
169 		return res;
170 
171 	index = io_read32(vr->base + VREFBUF_CSR) & VREFBUF_CSR_VRS;
172 	index = INV_VRS(index) >> VREFBUF_CSR_VRS_SHIFT;
173 
174 	clk_disable(vr->clock);
175 
176 	*level_uv = vr->compat->voltages[index];
177 
178 	return TEE_SUCCESS;
179 }
180 
181 static TEE_Result vrefbuf_set_voltage(struct regulator *regulator, int level_uv)
182 {
183 	struct vrefbuf_regul *vr = regulator_to_vr(regulator);
184 	TEE_Result res = TEE_ERROR_GENERIC;
185 	size_t i = 0;
186 
187 	for (i = 0 ; i < ARRAY_SIZE(vr->compat->voltages) ; i++) {
188 		if (vr->compat->voltages[i] == level_uv) {
189 			uint32_t val = INV_VRS(i << VREFBUF_CSR_VRS_SHIFT);
190 
191 			res = clk_enable(vr->clock);
192 			if (res)
193 				return res;
194 
195 			io_clrsetbits32(vr->base + VREFBUF_CSR, VREFBUF_CSR_VRS,
196 					val);
197 
198 			clk_disable(vr->clock);
199 
200 			return TEE_SUCCESS;
201 		}
202 	}
203 
204 	EMSG("Failed to set voltage on vrefbuf");
205 
206 	return TEE_ERROR_BAD_PARAMETERS;
207 }
208 
209 static TEE_Result vrefbuf_list_voltages(struct regulator *regulator __unused,
210 					struct regulator_voltages **voltages)
211 {
212 	struct vrefbuf_regul *vr = regulator_to_vr(regulator);
213 
214 	if (!vr->voltages_desc.type) {
215 		size_t num_levels = ARRAY_SIZE(vr->compat->voltages);
216 		unsigned int index_high = num_levels - 1;
217 		unsigned int index_low = 0;
218 		unsigned int count = 0;
219 		unsigned int n = 0;
220 
221 		for (n = 0; n <= index_high; n++)
222 			if (vr->compat->voltages[n] >= regulator->min_uv)
223 				break;
224 		if (n > index_high)
225 			return TEE_ERROR_GENERIC;
226 		index_low = n;
227 
228 		for (n = index_high; n >= index_low; n--)
229 			if (vr->compat->voltages[n] <= regulator->max_uv)
230 				break;
231 		if (n < index_low)
232 			return TEE_ERROR_GENERIC;
233 		index_high = n;
234 
235 		count = index_high - index_low + 1;
236 
237 		vr->voltages_desc.type = VOLTAGE_TYPE_FULL_LIST;
238 		vr->voltages_desc.num_levels = count;
239 		for (n = 0; n < count; n++)
240 			vr->supported_levels[n] =
241 				vr->compat->voltages[index_low + n];
242 	}
243 
244 	*voltages = &vr->voltages_desc;
245 
246 	return TEE_SUCCESS;
247 }
248 
249 static TEE_Result stm32_vrefbuf_pm(enum pm_op op, unsigned int pm_hint __unused,
250 				   const struct pm_callback_handle *hdl)
251 {
252 	struct regulator *regulator = hdl->handle;
253 	struct vrefbuf_regul *vr = regulator_to_vr(regulator);
254 	vaddr_t csr_va = vr->base + VREFBUF_CSR;
255 	TEE_Result res = TEE_ERROR_GENERIC;
256 	/* Context to save/restore on PM suspend/resume */
257 	static uint32_t pm_val;
258 
259 	assert(op == PM_OP_SUSPEND || op == PM_OP_RESUME);
260 
261 	res = clk_enable(vr->clock);
262 	if (res)
263 		return res;
264 
265 	if (op == PM_OP_SUSPEND) {
266 		pm_val = io_read32(csr_va);
267 
268 		if (pm_val & VREFBUF_CSR_ENVR && vrefbuf_wait_ready(vr)) {
269 			clk_disable(vr->clock);
270 
271 			return TEE_ERROR_GENERIC;
272 		}
273 	} else {
274 		io_clrsetbits32(csr_va, VREFBUF_CSR_VRS, pm_val);
275 
276 		if (pm_val & VREFBUF_CSR_ENVR) {
277 			vr->disable_timeout = 0;
278 			vrefbuf_set_state(&vr->regulator, true);
279 		}
280 	}
281 
282 	clk_disable(vr->clock);
283 
284 	return TEE_SUCCESS;
285 }
286 DECLARE_KEEP_PAGER(stm32_vrefbuf_pm);
287 
288 static TEE_Result stm32_vrefbuf_init(struct regulator *regulator,
289 				     const void *fdt __unused,
290 				     int node __unused)
291 {
292 	register_pm_driver_cb(stm32_vrefbuf_pm, regulator, "stm32-vrefbuf");
293 
294 	return TEE_SUCCESS;
295 }
296 
297 static const struct regulator_ops vrefbuf_ops = {
298 	.set_state = vrefbuf_set_state,
299 	.get_state = vrefbuf_get_state,
300 	.set_voltage = vrefbuf_set_voltage,
301 	.get_voltage = vrefbuf_get_voltage,
302 	.supported_voltages = vrefbuf_list_voltages,
303 	.supplied_init = stm32_vrefbuf_init,
304 };
305 
306 static TEE_Result stm32_vrefbuf_regulator_probe(const void *fdt, int node,
307 						const void *compat_data)
308 {
309 	TEE_Result res = TEE_ERROR_GENERIC;
310 	struct vrefbuf_regul *vr = NULL;
311 	struct regu_dt_desc desc = { };
312 	char *regu_name = NULL;
313 	struct clk *clk = NULL;
314 	paddr_t reg_base = 0;
315 	size_t reg_size = 0;
316 
317 	assert(!stm32_vrefbuf);
318 
319 	res = clk_dt_get_by_index(fdt, node, 0, &clk);
320 	if (res)
321 		return res;
322 
323 	vr = calloc(1, sizeof(*vr));
324 	if (!vr)
325 		panic();
326 
327 	vr->compat = compat_data;
328 
329 	regu_name = strdup(fdt_get_name(fdt, node, NULL));
330 	if (!regu_name)
331 		panic();
332 
333 	reg_base = fdt_reg_base_address(fdt, node);
334 	reg_size = fdt_reg_size(fdt, node);
335 	if (reg_base == DT_INFO_INVALID_REG ||
336 	    reg_size == DT_INFO_INVALID_REG_SIZE)
337 		panic();
338 
339 	vr->base = (vaddr_t)phys_to_virt(reg_base, MEM_AREA_IO_SEC, reg_size);
340 	if (!vr->base)
341 		panic();
342 
343 	vr->clock = clk;
344 
345 	desc = (struct regu_dt_desc){
346 		.name = regu_name,
347 		.ops = &vrefbuf_ops,
348 		.supply_name = "vdda",
349 		.regulator = &vr->regulator,
350 	};
351 
352 	res = regulator_dt_register(fdt, node, node, &desc);
353 	if (res)
354 		panic();
355 
356 	stm32_vrefbuf = vr;
357 
358 	return TEE_SUCCESS;
359 }
360 
361 static const struct dt_device_match stm32_vrefbuf_match_table[] = {
362 	{
363 		.compatible = "st,stm32-vrefbuf",
364 		.compat_data = &stm32mp15_vrefbuf_compat,
365 	},
366 	{
367 		.compatible = "st,stm32mp13-vrefbuf",
368 		.compat_data = &stm32mp13_vrefbuf_compat
369 	},
370 	{ }
371 };
372 
373 DEFINE_DT_DRIVER(stm32_vrefbuf_regulator_dt_driver) = {
374 	.name = "stm32-vrefbuf-regulator",
375 	.match_table = stm32_vrefbuf_match_table,
376 	.probe = &stm32_vrefbuf_regulator_probe,
377 };
378