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