xref: /optee_os/core/drivers/regulator/regulator.c (revision 8c48c11ba37e0dce3a62d6f165a6543794b30e70)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2023, STMicroelectronics
4  */
5 
6 #include <assert.h>
7 #include <compiler.h>
8 #include <config.h>
9 #include <drivers/regulator.h>
10 #include <initcall.h>
11 #include <keep.h>
12 #include <kernel/boot.h>
13 #include <kernel/delay.h>
14 #include <kernel/mutex_pm_aware.h>
15 #include <kernel/panic.h>
16 #include <kernel/pm.h>
17 #include <kernel/tee_time.h>
18 #include <kernel/thread.h>
19 #include <libfdt.h>
20 #include <limits.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <util.h>
25 
26 static SLIST_HEAD(, regulator) regulator_device_list =
27 	SLIST_HEAD_INITIALIZER(regulator);
28 
29 /* Access protection mutex complying the power state transitions context */
30 static void lock_regulator(struct regulator *regulator)
31 {
32 	mutex_pm_aware_lock(&regulator->mutex);
33 }
34 
35 static void unlock_regulator(struct regulator *regulator)
36 {
37 	mutex_pm_aware_unlock(&regulator->mutex);
38 }
39 
40 static TEE_Result set_state(struct regulator *regulator, bool on_not_off)
41 {
42 	if (!regulator->ops->set_state)
43 		return TEE_SUCCESS;
44 
45 	return regulator->ops->set_state(regulator, on_not_off);
46 }
47 
48 static TEE_Result regulator_refcnt_enable(struct regulator *regulator)
49 {
50 	TEE_Result res = TEE_ERROR_GENERIC;
51 
52 	FMSG("%s", regulator_name(regulator));
53 
54 	if (regulator->supply) {
55 		res = regulator_enable(regulator->supply);
56 		if (res)
57 			return res;
58 	}
59 
60 	lock_regulator(regulator);
61 
62 	if (!regulator->refcount) {
63 		res = set_state(regulator, true);
64 		if (res) {
65 			EMSG("regul %s set state failed with %#"PRIx32,
66 			     regulator_name(regulator), res);
67 
68 			unlock_regulator(regulator);
69 
70 			if (regulator->supply &&
71 			    regulator_disable(regulator->supply))
72 				panic();
73 
74 			return res;
75 		}
76 	}
77 
78 	regulator->refcount++;
79 	if (!regulator->refcount)
80 		panic();
81 
82 	FMSG("%s refcount: %u", regulator_name(regulator), regulator->refcount);
83 
84 	unlock_regulator(regulator);
85 
86 	return TEE_SUCCESS;
87 }
88 
89 TEE_Result regulator_enable(struct regulator *regulator)
90 {
91 	assert(regulator);
92 	FMSG("%s", regulator_name(regulator));
93 
94 	if (regulator_is_always_on(regulator))
95 		return TEE_SUCCESS;
96 
97 	return regulator_refcnt_enable(regulator);
98 }
99 
100 static TEE_Result regulator_refcnt_disable(struct regulator *regulator)
101 {
102 	FMSG("%s", regulator_name(regulator));
103 
104 	lock_regulator(regulator);
105 
106 	if (regulator->refcount == 1) {
107 		TEE_Result res = set_state(regulator, false);
108 
109 		if (res) {
110 			EMSG("regul %s set state failed with %#"PRIx32,
111 			     regulator_name(regulator), res);
112 			unlock_regulator(regulator);
113 			return res;
114 		}
115 	}
116 
117 	if (!regulator->refcount) {
118 		EMSG("Unbalanced %s", regulator_name(regulator));
119 		panic();
120 	}
121 
122 	regulator->refcount--;
123 
124 	FMSG("%s refcount: %u", regulator_name(regulator), regulator->refcount);
125 
126 	unlock_regulator(regulator);
127 
128 	if (regulator->supply && regulator_disable(regulator->supply)) {
129 		/* We can't leave this unbalanced */
130 		EMSG("Can't disable %s", regulator_name(regulator->supply));
131 		panic();
132 	}
133 
134 	return TEE_SUCCESS;
135 }
136 
137 TEE_Result regulator_disable(struct regulator *regulator)
138 {
139 	assert(regulator);
140 	FMSG("%s", regulator_name(regulator));
141 
142 	if (regulator_is_always_on(regulator))
143 		return TEE_SUCCESS;
144 
145 	return regulator_refcnt_disable(regulator);
146 }
147 
148 bool regulator_is_enabled(struct regulator *regulator)
149 {
150 	TEE_Result res = TEE_SUCCESS;
151 	bool enabled = false;
152 
153 	if (!regulator->ops->get_state)
154 		return true;
155 
156 	lock_regulator(regulator);
157 	res = regulator->ops->get_state(regulator, &enabled);
158 	unlock_regulator(regulator);
159 
160 	if (res)
161 		EMSG("regul %s get state failed with %#"PRIx32,
162 		     regulator_name(regulator), res);
163 
164 	return !res && enabled;
165 }
166 
167 int regulator_get_voltage(struct regulator *regulator)
168 {
169 	TEE_Result res = TEE_SUCCESS;
170 	int level_uv = regulator->min_uv;
171 
172 	if (regulator->ops->get_voltage) {
173 		res = regulator->ops->get_voltage(regulator, &level_uv);
174 		if (res) {
175 			EMSG("%s get_voltage failed with %#"PRIx32,
176 			     regulator_name(regulator), res);
177 			level_uv = 0;
178 		}
179 	}
180 
181 	return level_uv;
182 }
183 
184 TEE_Result regulator_set_voltage(struct regulator *regulator, int level_uv)
185 {
186 	TEE_Result res = TEE_ERROR_GENERIC;
187 	int cur_uv = 0;
188 
189 	assert(regulator);
190 	FMSG("%s %duV", regulator_name(regulator), level_uv);
191 
192 	if (level_uv < regulator->min_uv || level_uv > regulator->max_uv)
193 		return TEE_ERROR_BAD_PARAMETERS;
194 
195 	cur_uv = regulator_get_voltage(regulator);
196 	if (level_uv == cur_uv)
197 		return TEE_SUCCESS;
198 
199 	if (!regulator->ops->set_voltage)
200 		return TEE_ERROR_NOT_SUPPORTED;
201 
202 	lock_regulator(regulator);
203 	res = regulator->ops->set_voltage(regulator, level_uv);
204 	unlock_regulator(regulator);
205 
206 	if (res) {
207 		EMSG("regul %s set volt failed with %#"PRIx32,
208 		     regulator_name(regulator), res);
209 		return res;
210 	}
211 
212 	if (regulator->ramp_delay_uv_per_us) {
213 		unsigned int d = 0;
214 
215 		if (cur_uv > level_uv)
216 			d = cur_uv - level_uv;
217 		else
218 			d = level_uv - cur_uv;
219 
220 		d /= regulator->ramp_delay_uv_per_us;
221 
222 		FMSG("%s %"PRIu32"uS", regulator_name(regulator), d);
223 		udelay(d);
224 	}
225 
226 	return TEE_SUCCESS;
227 }
228 
229 TEE_Result regulator_supported_voltages(struct regulator *regulator,
230 					struct regulator_voltages_desc **desc,
231 					const int **levels)
232 {
233 	TEE_Result res = TEE_ERROR_NOT_SUPPORTED;
234 
235 	assert(regulator && desc && levels);
236 
237 	if (regulator->ops->supported_voltages)
238 		res = regulator->ops->supported_voltages(regulator, desc,
239 							 levels);
240 	if (res == TEE_ERROR_NOT_SUPPORTED) {
241 		*desc = &regulator->voltages_fallback.desc;
242 		*levels = regulator->voltages_fallback.levels;
243 	} else if (res) {
244 		return res;
245 	}
246 
247 	if ((*desc)->type == VOLTAGE_TYPE_FULL_LIST) {
248 		assert((*desc)->num_levels);
249 		assert((*levels)[0] >= regulator->min_uv);
250 		assert((*levels)[(*desc)->num_levels - 1] <= regulator->max_uv);
251 	} else if ((*desc)->type == VOLTAGE_TYPE_INCREMENT) {
252 		assert((*levels)[0] >= regulator->min_uv);
253 		assert((*levels)[1] <= regulator->max_uv);
254 	} else {
255 		assert(0);
256 	}
257 
258 	return TEE_SUCCESS;
259 }
260 
261 TEE_Result regulator_register(struct regulator *regulator)
262 {
263 	TEE_Result res = TEE_SUCCESS;
264 	int min_uv = 0;
265 	int max_uv = 0;
266 	int uv = 0;
267 
268 	if (!regulator || !regulator->ops ||
269 	    regulator->flags & ~REGULATOR_FLAGS_MASK)
270 		return TEE_ERROR_BAD_PARAMETERS;
271 
272 	mutex_pm_aware_init(&regulator->mutex);
273 
274 	regulator_get_range(regulator, &min_uv, &max_uv);
275 	if (min_uv > max_uv)
276 		return TEE_ERROR_BAD_PARAMETERS;
277 
278 	/* Sanitize regulator effective level */
279 	uv = regulator_get_voltage(regulator);
280 
281 	if (uv < min_uv || uv > max_uv) {
282 		res = regulator_set_voltage(regulator, min_uv);
283 		if (res)
284 			return res;
285 	}
286 
287 	/* Unbalanced enable refcount to keep always-on regulators enabled */
288 	if (regulator_is_always_on(regulator)) {
289 		res = regulator_refcnt_enable(regulator);
290 		if (res)
291 			return res;
292 	}
293 
294 	/* Preset voltage list in case ops::supported_voltages is NULL */
295 	if (regulator->min_uv == regulator->max_uv) {
296 		regulator->voltages_fallback.desc.type = VOLTAGE_TYPE_FULL_LIST;
297 		regulator->voltages_fallback.desc.num_levels = 1;
298 		regulator->voltages_fallback.levels[0] = regulator->min_uv;
299 	} else {
300 		regulator->voltages_fallback.desc.type = VOLTAGE_TYPE_INCREMENT;
301 		regulator->voltages_fallback.levels[0] = regulator->min_uv;
302 		regulator->voltages_fallback.levels[1] = regulator->max_uv;
303 		regulator->voltages_fallback.levels[2] = 1;
304 	}
305 
306 	SLIST_INSERT_HEAD(&regulator_device_list, regulator, link);
307 
308 	return TEE_SUCCESS;
309 }
310 
311 /*
312  * Clean-up regulators that are not used.
313  */
314 static TEE_Result regulator_core_cleanup(void)
315 {
316 	struct regulator *regulator = NULL;
317 
318 	SLIST_FOREACH(regulator, &regulator_device_list, link) {
319 		if (!regulator->refcount) {
320 			DMSG("disable %s", regulator_name(regulator));
321 			lock_regulator(regulator);
322 			set_state(regulator, false /* disable */);
323 			unlock_regulator(regulator);
324 		}
325 	}
326 
327 	if (TRACE_LEVEL >= TRACE_DEBUG)
328 		regulator_print_tree();
329 
330 	return TEE_SUCCESS;
331 }
332 
333 release_init_resource(regulator_core_cleanup);
334 
335 /* Return updated message buffer position of NULL on failure */
336 static __printf(3, 4) char *add_msg(char *cur, char *end, const char *fmt, ...)
337 {
338 	va_list ap = { };
339 	int max_len = end - cur;
340 	int ret = 0;
341 
342 	va_start(ap, fmt);
343 	ret = vsnprintf(cur, max_len, fmt, ap);
344 	va_end(ap);
345 
346 	if (ret < 0 || ret >= max_len)
347 		return NULL;
348 
349 	return cur + ret;
350 }
351 
352 static struct regulator *find_next_regulator(struct regulator *parent,
353 					     struct regulator *sibling)
354 {
355 	struct regulator *regulator = NULL;
356 
357 	if (sibling)
358 		regulator = SLIST_NEXT(sibling, link);
359 	else
360 		regulator = SLIST_FIRST(&regulator_device_list);
361 
362 	while (regulator && regulator->supply != parent)
363 		regulator = SLIST_NEXT(regulator, link);
364 
365 	return regulator;
366 }
367 
368 /* Regulator is the last supplied one by its supply in the registered list */
369 static bool regulator_is_supply_last_supplied(struct regulator *regulator)
370 {
371 	return !find_next_regulator(regulator->supply, regulator);
372 }
373 
374 /* Supply last node may already be printed for indentation level @cur_indent */
375 static bool indent_with_empty_string(struct regulator *node_regulator,
376 				     int node_indent, int cur_indent)
377 {
378 	struct regulator *r = node_regulator;
379 	int n = 0;
380 
381 	/* Find supply at indentation level @node_indent - @cur_indent - 1 */
382 	for (n = 0; n < node_indent - cur_indent - 1; n++)
383 		r = r->supply;
384 
385 	return regulator_is_supply_last_supplied(r);
386 }
387 
388 static void __maybe_unused print_regulator(struct regulator *regulator,
389 					   int indent)
390 {
391 	static const char * const level_unit[] = { "uV", "mV", "V" };
392 	int max_unit = ARRAY_SIZE(level_unit);
393 	int level_max = 0;
394 	int level_min = 0;
395 	int level_cur = 0;
396 	char msg_buf[128] = { };
397 	char *msg_end = msg_buf + sizeof(msg_buf);
398 	char *msg = msg_buf;
399 	int n_max = 0;
400 	int n_min = 0;
401 	int n_cur = 0;
402 	int n = 0;
403 
404 	if (indent) {
405 		/* Indent for root clock level */
406 		msg = add_msg(msg, msg_end, "   ");
407 		if (!msg)
408 			goto out;
409 
410 		/* Indent for root supply to regulator supply levels */
411 		for (n = 0; n < indent - 1; n++) {
412 			if (indent_with_empty_string(regulator, indent, n))
413 				msg = add_msg(msg, msg_end, "    ");
414 			else
415 				msg = add_msg(msg, msg_end, "|   ");
416 			if (!msg)
417 				goto out;
418 		}
419 
420 		/* Regulator indentation */
421 		if (regulator_is_supply_last_supplied(regulator))
422 			msg = add_msg(msg, msg_end, "`-- ");
423 		else
424 			msg = add_msg(msg, msg_end, "|-- ");
425 
426 		if (!msg)
427 			goto out;
428 	} else {
429 		/* Root supply indentation */
430 		msg = add_msg(msg, msg_end, "o- ");
431 	}
432 
433 	regulator_get_range(regulator, &level_min, &level_max);
434 	level_cur = regulator_get_voltage(regulator);
435 
436 	for (n_cur = 1; !(level_cur % 1000) && n_cur < max_unit; n_cur++)
437 		level_cur /= 1000;
438 	for (n_max = 1; !(level_max % 1000) && n_max < max_unit; n_max++)
439 		level_max /= 1000;
440 	for (n_min = 1; !(level_min % 1000) && n_min < max_unit; n_min++)
441 		level_min /= 1000;
442 
443 	msg = add_msg(msg, msg_end, "%s \t(%3s / refcnt %u / flags %#"PRIx32
444 		      " / %d %s ", regulator_name(regulator),
445 		      regulator_is_enabled(regulator) ? "on " : "off",
446 		      regulator->refcount, regulator->flags,
447 		      level_cur, level_unit[n_cur - 1]);
448 	if (!msg)
449 		goto out;
450 
451 	if (level_min == level_max)
452 		msg = add_msg(msg, msg_end, "fixed)");
453 	else if (level_max == INT_MAX)
454 		msg = add_msg(msg, msg_end, "[%d %s .. MAX])",
455 			      level_min, level_unit[n_min - 1]);
456 	else
457 		msg = add_msg(msg, msg_end, "[%d %s .. %d %s])",
458 			      level_min, level_unit[n_min - 1],
459 			      level_max, level_unit[n_max - 1]);
460 
461 out:
462 	if (!msg)
463 		snprintf(msg_end - 4, 4, "...");
464 
465 	IMSG("%s", msg_buf);
466 }
467 
468 static void print_tree(void)
469 {
470 	struct regulator *regulator = NULL;
471 	struct regulator *parent = NULL;
472 	struct regulator *next = NULL;
473 	int indent = -1;
474 
475 	while (true) {
476 		next = find_next_regulator(parent, regulator);
477 		if (next) {
478 			print_regulator(next, indent + 1);
479 			/* Enter the subtree of the next regulator */
480 			parent = next;
481 			indent++;
482 			regulator = NULL;
483 		} else {
484 			/*
485 			 * We've processed all children at this level.
486 			 * If parent is NULL we're at the top and are done.
487 			 */
488 			if (!parent)
489 				break;
490 			/*
491 			 * Move up one level to resume with the next
492 			 * regulator of the parent.
493 			 */
494 			regulator = parent;
495 			parent = regulator->supply;
496 			indent--;
497 		}
498 	}
499 }
500 
501 void regulator_print_tree(void)
502 {
503 	if (IS_ENABLED(CFG_DRIVERS_REGULATOR_PRINT_TREE) &&
504 	    TRACE_LEVEL >= TRACE_INFO) {
505 		IMSG("Regulator tree summary");
506 		if (SLIST_EMPTY(&regulator_device_list))
507 			IMSG("-- No registered regulator");
508 		else
509 			print_tree();
510 	}
511 }
512