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