1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * OMAP powerdomain control 4 * 5 * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc. 6 * Copyright (C) 2007-2011 Nokia Corporation 7 * 8 * Written by Paul Walmsley 9 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> 10 * State counting code by Tero Kristo <tero.kristo@nokia.com> 11 */ 12 #undef DEBUG 13 14 #include <linux/cpu_pm.h> 15 #include <linux/kernel.h> 16 #include <linux/types.h> 17 #include <linux/list.h> 18 #include <linux/errno.h> 19 #include <linux/string.h> 20 #include <linux/spinlock.h> 21 #include <trace/events/power.h> 22 23 #include "cm2xxx_3xxx.h" 24 #include "prcm44xx.h" 25 #include "cm44xx.h" 26 #include "prm2xxx_3xxx.h" 27 #include "prm44xx.h" 28 29 #include <asm/cpu.h> 30 31 #include "powerdomain.h" 32 #include "clockdomain.h" 33 #include "voltage.h" 34 35 #include "soc.h" 36 #include "pm.h" 37 38 #define PWRDM_TRACE_STATES_FLAG (1<<31) 39 40 static void pwrdms_save_context(void); 41 static void pwrdms_restore_context(void); 42 43 enum { 44 PWRDM_STATE_NOW = 0, 45 PWRDM_STATE_PREV, 46 }; 47 48 /* 49 * Types of sleep_switch used internally in omap_set_pwrdm_state() 50 * and its associated static functions 51 * 52 * XXX Better documentation is needed here 53 */ 54 #define ALREADYACTIVE_SWITCH 0 55 #define FORCEWAKEUP_SWITCH 1 56 #define LOWPOWERSTATE_SWITCH 2 57 58 /* pwrdm_list contains all registered struct powerdomains */ 59 static LIST_HEAD(pwrdm_list); 60 61 static struct pwrdm_ops *arch_pwrdm; 62 63 /* Private functions */ 64 65 static struct powerdomain *_pwrdm_lookup(const char *name) 66 { 67 struct powerdomain *pwrdm, *temp_pwrdm; 68 69 pwrdm = NULL; 70 71 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { 72 if (!strcmp(name, temp_pwrdm->name)) { 73 pwrdm = temp_pwrdm; 74 break; 75 } 76 } 77 78 return pwrdm; 79 } 80 81 /** 82 * _pwrdm_register - register a powerdomain 83 * @pwrdm: struct powerdomain * to register 84 * 85 * Adds a powerdomain to the internal powerdomain list. Returns 86 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is 87 * already registered by the provided name, or 0 upon success. 88 */ 89 static int _pwrdm_register(struct powerdomain *pwrdm) 90 { 91 int i; 92 struct voltagedomain *voltdm; 93 94 if (!pwrdm || !pwrdm->name) 95 return -EINVAL; 96 97 if (cpu_is_omap44xx() && 98 pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) { 99 pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n", 100 pwrdm->name); 101 return -EINVAL; 102 } 103 104 if (_pwrdm_lookup(pwrdm->name)) 105 return -EEXIST; 106 107 if (arch_pwrdm && arch_pwrdm->pwrdm_has_voltdm) 108 if (!arch_pwrdm->pwrdm_has_voltdm()) 109 goto skip_voltdm; 110 111 voltdm = voltdm_lookup(pwrdm->voltdm.name); 112 if (!voltdm) { 113 pr_err("powerdomain: %s: voltagedomain %s does not exist\n", 114 pwrdm->name, pwrdm->voltdm.name); 115 return -EINVAL; 116 } 117 pwrdm->voltdm.ptr = voltdm; 118 INIT_LIST_HEAD(&pwrdm->voltdm_node); 119 skip_voltdm: 120 spin_lock_init(&pwrdm->_lock); 121 122 list_add(&pwrdm->node, &pwrdm_list); 123 124 /* Initialize the powerdomain's state counter */ 125 for (i = 0; i < PWRDM_MAX_PWRSTS; i++) 126 pwrdm->state_counter[i] = 0; 127 128 pwrdm->ret_logic_off_counter = 0; 129 for (i = 0; i < pwrdm->banks; i++) 130 pwrdm->ret_mem_off_counter[i] = 0; 131 132 if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition) 133 arch_pwrdm->pwrdm_wait_transition(pwrdm); 134 pwrdm->state = pwrdm_read_pwrst(pwrdm); 135 pwrdm->state_counter[pwrdm->state] = 1; 136 137 pr_debug("powerdomain: registered %s\n", pwrdm->name); 138 139 return 0; 140 } 141 142 static void _update_logic_membank_counters(struct powerdomain *pwrdm) 143 { 144 int i; 145 u8 prev_logic_pwrst, prev_mem_pwrst; 146 147 prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm); 148 if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) && 149 (prev_logic_pwrst == PWRDM_POWER_OFF)) 150 pwrdm->ret_logic_off_counter++; 151 152 for (i = 0; i < pwrdm->banks; i++) { 153 prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i); 154 155 if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) && 156 (prev_mem_pwrst == PWRDM_POWER_OFF)) 157 pwrdm->ret_mem_off_counter[i]++; 158 } 159 } 160 161 static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) 162 { 163 164 int prev, next, state, trace_state = 0; 165 166 if (pwrdm == NULL) 167 return -EINVAL; 168 169 state = pwrdm_read_pwrst(pwrdm); 170 171 switch (flag) { 172 case PWRDM_STATE_NOW: 173 prev = pwrdm->state; 174 break; 175 case PWRDM_STATE_PREV: 176 prev = pwrdm_read_prev_pwrst(pwrdm); 177 if (prev >= 0 && pwrdm->state != prev) 178 pwrdm->state_counter[prev]++; 179 if (prev == PWRDM_POWER_RET) 180 _update_logic_membank_counters(pwrdm); 181 /* 182 * If the power domain did not hit the desired state, 183 * generate a trace event with both the desired and hit states 184 */ 185 next = pwrdm_read_next_pwrst(pwrdm); 186 if (next != prev) { 187 trace_state = (PWRDM_TRACE_STATES_FLAG | 188 ((next & OMAP_POWERSTATE_MASK) << 8) | 189 ((prev & OMAP_POWERSTATE_MASK) << 0)); 190 trace_power_domain_target(pwrdm->name, 191 trace_state, 192 raw_smp_processor_id()); 193 } 194 break; 195 default: 196 return -EINVAL; 197 } 198 199 if (state != prev) 200 pwrdm->state_counter[state]++; 201 202 pm_dbg_update_time(pwrdm, prev); 203 204 pwrdm->state = state; 205 206 return 0; 207 } 208 209 static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused) 210 { 211 pwrdm_clear_all_prev_pwrst(pwrdm); 212 _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); 213 return 0; 214 } 215 216 static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) 217 { 218 _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV); 219 return 0; 220 } 221 222 /** 223 * _pwrdm_save_clkdm_state_and_activate - prepare for power state change 224 * @pwrdm: struct powerdomain * to operate on 225 * @curr_pwrst: current power state of @pwrdm 226 * @pwrst: power state to switch to 227 * 228 * Determine whether the powerdomain needs to be turned on before 229 * attempting to switch power states. Called by 230 * omap_set_pwrdm_state(). NOTE that if the powerdomain contains 231 * multiple clockdomains, this code assumes that the first clockdomain 232 * supports software-supervised wakeup mode - potentially a problem. 233 * Returns the power state switch mode currently in use (see the 234 * "Types of sleep_switch" comment above). 235 */ 236 static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, 237 u8 curr_pwrst, u8 pwrst) 238 { 239 u8 sleep_switch; 240 241 if (curr_pwrst < PWRDM_POWER_ON) { 242 if (curr_pwrst > pwrst && 243 pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && 244 arch_pwrdm->pwrdm_set_lowpwrstchange) { 245 sleep_switch = LOWPOWERSTATE_SWITCH; 246 } else { 247 clkdm_deny_idle_nolock(pwrdm->pwrdm_clkdms[0]); 248 sleep_switch = FORCEWAKEUP_SWITCH; 249 } 250 } else { 251 sleep_switch = ALREADYACTIVE_SWITCH; 252 } 253 254 return sleep_switch; 255 } 256 257 /** 258 * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change 259 * @pwrdm: struct powerdomain * to operate on 260 * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate() 261 * 262 * Restore the clockdomain state perturbed by 263 * _pwrdm_save_clkdm_state_and_activate(), and call the power state 264 * bookkeeping code. Called by omap_set_pwrdm_state(). NOTE that if 265 * the powerdomain contains multiple clockdomains, this assumes that 266 * the first associated clockdomain supports either 267 * hardware-supervised idle control in the register, or 268 * software-supervised sleep. No return value. 269 */ 270 static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm, 271 u8 sleep_switch) 272 { 273 switch (sleep_switch) { 274 case FORCEWAKEUP_SWITCH: 275 clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]); 276 break; 277 case LOWPOWERSTATE_SWITCH: 278 if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && 279 arch_pwrdm->pwrdm_set_lowpwrstchange) 280 arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm); 281 pwrdm_state_switch_nolock(pwrdm); 282 break; 283 } 284 } 285 286 /* Public functions */ 287 288 /** 289 * pwrdm_register_platform_funcs - register powerdomain implementation fns 290 * @po: func pointers for arch specific implementations 291 * 292 * Register the list of function pointers used to implement the 293 * powerdomain functions on different OMAP SoCs. Should be called 294 * before any other pwrdm_register*() function. Returns -EINVAL if 295 * @po is null, -EEXIST if platform functions have already been 296 * registered, or 0 upon success. 297 */ 298 int pwrdm_register_platform_funcs(struct pwrdm_ops *po) 299 { 300 if (!po) 301 return -EINVAL; 302 303 if (arch_pwrdm) 304 return -EEXIST; 305 306 arch_pwrdm = po; 307 308 return 0; 309 } 310 311 /** 312 * pwrdm_register_pwrdms - register SoC powerdomains 313 * @ps: pointer to an array of struct powerdomain to register 314 * 315 * Register the powerdomains available on a particular OMAP SoC. Must 316 * be called after pwrdm_register_platform_funcs(). May be called 317 * multiple times. Returns -EACCES if called before 318 * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is 319 * null; or 0 upon success. 320 */ 321 int pwrdm_register_pwrdms(struct powerdomain **ps) 322 { 323 struct powerdomain **p = NULL; 324 325 if (!arch_pwrdm) 326 return -EEXIST; 327 328 if (!ps) 329 return -EINVAL; 330 331 for (p = ps; *p; p++) 332 _pwrdm_register(*p); 333 334 return 0; 335 } 336 337 static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v) 338 { 339 switch (cmd) { 340 case CPU_CLUSTER_PM_ENTER: 341 if (enable_off_mode) 342 pwrdms_save_context(); 343 break; 344 case CPU_CLUSTER_PM_EXIT: 345 if (enable_off_mode) 346 pwrdms_restore_context(); 347 break; 348 } 349 350 return NOTIFY_OK; 351 } 352 353 /** 354 * pwrdm_complete_init - set up the powerdomain layer 355 * 356 * Do whatever is necessary to initialize registered powerdomains and 357 * powerdomain code. Currently, this programs the next power state 358 * for each powerdomain to ON. This prevents powerdomains from 359 * unexpectedly losing context or entering high wakeup latency modes 360 * with non-power-management-enabled kernels. Must be called after 361 * pwrdm_register_pwrdms(). Returns -EACCES if called before 362 * pwrdm_register_pwrdms(), or 0 upon success. 363 */ 364 int pwrdm_complete_init(void) 365 { 366 struct powerdomain *temp_p; 367 static struct notifier_block nb; 368 369 if (list_empty(&pwrdm_list)) 370 return -EACCES; 371 372 list_for_each_entry(temp_p, &pwrdm_list, node) 373 pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON); 374 375 /* Only AM43XX can lose pwrdm context during rtc-ddr suspend */ 376 if (soc_is_am43xx()) { 377 nb.notifier_call = cpu_notifier; 378 cpu_pm_register_notifier(&nb); 379 } 380 381 return 0; 382 } 383 384 /** 385 * pwrdm_lock - acquire a Linux spinlock on a powerdomain 386 * @pwrdm: struct powerdomain * to lock 387 * 388 * Acquire the powerdomain spinlock on @pwrdm. No return value. 389 */ 390 void pwrdm_lock(struct powerdomain *pwrdm) 391 __acquires(&pwrdm->_lock) 392 { 393 spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags); 394 } 395 396 /** 397 * pwrdm_unlock - release a Linux spinlock on a powerdomain 398 * @pwrdm: struct powerdomain * to unlock 399 * 400 * Release the powerdomain spinlock on @pwrdm. No return value. 401 */ 402 void pwrdm_unlock(struct powerdomain *pwrdm) 403 __releases(&pwrdm->_lock) 404 { 405 spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags); 406 } 407 408 /** 409 * pwrdm_lookup - look up a powerdomain by name, return a pointer 410 * @name: name of powerdomain 411 * 412 * Find a registered powerdomain by its name @name. Returns a pointer 413 * to the struct powerdomain if found, or NULL otherwise. 414 */ 415 struct powerdomain *pwrdm_lookup(const char *name) 416 { 417 struct powerdomain *pwrdm; 418 419 if (!name) 420 return NULL; 421 422 pwrdm = _pwrdm_lookup(name); 423 424 return pwrdm; 425 } 426 427 /** 428 * pwrdm_for_each - call function on each registered clockdomain 429 * @fn: callback function * 430 * 431 * Call the supplied function @fn for each registered powerdomain. 432 * The callback function @fn can return anything but 0 to bail out 433 * early from the iterator. Returns the last return value of the 434 * callback function, which should be 0 for success or anything else 435 * to indicate failure; or -EINVAL if the function pointer is null. 436 */ 437 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), 438 void *user) 439 { 440 struct powerdomain *temp_pwrdm; 441 int ret = 0; 442 443 if (!fn) 444 return -EINVAL; 445 446 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { 447 ret = (*fn)(temp_pwrdm, user); 448 if (ret) 449 break; 450 } 451 452 return ret; 453 } 454 455 /** 456 * pwrdm_add_clkdm - add a clockdomain to a powerdomain 457 * @pwrdm: struct powerdomain * to add the clockdomain to 458 * @clkdm: struct clockdomain * to associate with a powerdomain 459 * 460 * Associate the clockdomain @clkdm with a powerdomain @pwrdm. This 461 * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if 462 * presented with invalid pointers; -ENOMEM if memory could not be allocated; 463 * or 0 upon success. 464 */ 465 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) 466 { 467 int i; 468 int ret = -EINVAL; 469 470 if (!pwrdm || !clkdm) 471 return -EINVAL; 472 473 pr_debug("powerdomain: %s: associating clockdomain %s\n", 474 pwrdm->name, clkdm->name); 475 476 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) { 477 if (!pwrdm->pwrdm_clkdms[i]) 478 break; 479 #ifdef DEBUG 480 if (pwrdm->pwrdm_clkdms[i] == clkdm) { 481 ret = -EINVAL; 482 goto pac_exit; 483 } 484 #endif 485 } 486 487 if (i == PWRDM_MAX_CLKDMS) { 488 pr_debug("powerdomain: %s: increase PWRDM_MAX_CLKDMS for clkdm %s\n", 489 pwrdm->name, clkdm->name); 490 WARN_ON(1); 491 ret = -ENOMEM; 492 goto pac_exit; 493 } 494 495 pwrdm->pwrdm_clkdms[i] = clkdm; 496 497 ret = 0; 498 499 pac_exit: 500 return ret; 501 } 502 503 /** 504 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain 505 * @pwrdm: struct powerdomain * 506 * 507 * Return the number of controllable memory banks in powerdomain @pwrdm, 508 * starting with 1. Returns -EINVAL if the powerdomain pointer is null. 509 */ 510 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm) 511 { 512 if (!pwrdm) 513 return -EINVAL; 514 515 return pwrdm->banks; 516 } 517 518 /** 519 * pwrdm_set_next_pwrst - set next powerdomain power state 520 * @pwrdm: struct powerdomain * to set 521 * @pwrst: one of the PWRDM_POWER_* macros 522 * 523 * Set the powerdomain @pwrdm's next power state to @pwrst. The powerdomain 524 * may not enter this state immediately if the preconditions for this state 525 * have not been satisfied. Returns -EINVAL if the powerdomain pointer is 526 * null or if the power state is invalid for the powerdomin, or returns 0 527 * upon success. 528 */ 529 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) 530 { 531 int ret = -EINVAL; 532 533 if (!pwrdm) 534 return -EINVAL; 535 536 if (!(pwrdm->pwrsts & (1 << pwrst))) 537 return -EINVAL; 538 539 pr_debug("powerdomain: %s: setting next powerstate to %0x\n", 540 pwrdm->name, pwrst); 541 542 if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) { 543 /* Trace the pwrdm desired target state */ 544 trace_power_domain_target(pwrdm->name, pwrst, 545 raw_smp_processor_id()); 546 /* Program the pwrdm desired target state */ 547 ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst); 548 } 549 550 return ret; 551 } 552 553 /** 554 * pwrdm_read_next_pwrst - get next powerdomain power state 555 * @pwrdm: struct powerdomain * to get power state 556 * 557 * Return the powerdomain @pwrdm's next power state. Returns -EINVAL 558 * if the powerdomain pointer is null or returns the next power state 559 * upon success. 560 */ 561 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm) 562 { 563 int ret = -EINVAL; 564 565 if (!pwrdm) 566 return -EINVAL; 567 568 if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst) 569 ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm); 570 571 return ret; 572 } 573 574 /** 575 * pwrdm_read_pwrst - get current powerdomain power state 576 * @pwrdm: struct powerdomain * to get power state 577 * 578 * Return the powerdomain @pwrdm's current power state. Returns -EINVAL 579 * if the powerdomain pointer is null or returns the current power state 580 * upon success. Note that if the power domain only supports the ON state 581 * then just return ON as the current state. 582 */ 583 int pwrdm_read_pwrst(struct powerdomain *pwrdm) 584 { 585 int ret = -EINVAL; 586 587 if (!pwrdm) 588 return -EINVAL; 589 590 if (pwrdm->pwrsts == PWRSTS_ON) 591 return PWRDM_POWER_ON; 592 593 if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst) 594 ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm); 595 596 return ret; 597 } 598 599 /** 600 * pwrdm_read_prev_pwrst - get previous powerdomain power state 601 * @pwrdm: struct powerdomain * to get previous power state 602 * 603 * Return the powerdomain @pwrdm's previous power state. Returns -EINVAL 604 * if the powerdomain pointer is null or returns the previous power state 605 * upon success. 606 */ 607 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) 608 { 609 int ret = -EINVAL; 610 611 if (!pwrdm) 612 return -EINVAL; 613 614 if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst) 615 ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm); 616 617 return ret; 618 } 619 620 /** 621 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention 622 * @pwrdm: struct powerdomain * to set 623 * @pwrst: one of the PWRDM_POWER_* macros 624 * 625 * Set the next power state @pwrst that the logic portion of the 626 * powerdomain @pwrdm will enter when the powerdomain enters retention. 627 * This will be either RETENTION or OFF, if supported. Returns 628 * -EINVAL if the powerdomain pointer is null or the target power 629 * state is not supported, or returns 0 upon success. 630 */ 631 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) 632 { 633 int ret = -EINVAL; 634 635 if (!pwrdm) 636 return -EINVAL; 637 638 if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst))) 639 return -EINVAL; 640 641 pr_debug("powerdomain: %s: setting next logic powerstate to %0x\n", 642 pwrdm->name, pwrst); 643 644 if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst) 645 ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst); 646 647 return ret; 648 } 649 650 /** 651 * pwrdm_set_mem_onst - set memory power state while powerdomain ON 652 * @pwrdm: struct powerdomain * to set 653 * @bank: memory bank number to set (0-3) 654 * @pwrst: one of the PWRDM_POWER_* macros 655 * 656 * Set the next power state @pwrst that memory bank @bank of the 657 * powerdomain @pwrdm will enter when the powerdomain enters the ON 658 * state. @bank will be a number from 0 to 3, and represents different 659 * types of memory, depending on the powerdomain. Returns -EINVAL if 660 * the powerdomain pointer is null or the target power state is not 661 * supported for this memory bank, -EEXIST if the target memory 662 * bank does not exist or is not controllable, or returns 0 upon 663 * success. 664 */ 665 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) 666 { 667 int ret = -EINVAL; 668 669 if (!pwrdm) 670 return -EINVAL; 671 672 if (pwrdm->banks < (bank + 1)) 673 return -EEXIST; 674 675 if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst))) 676 return -EINVAL; 677 678 pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-ON to %0x\n", 679 pwrdm->name, bank, pwrst); 680 681 if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst) 682 ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst); 683 684 return ret; 685 } 686 687 /** 688 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET 689 * @pwrdm: struct powerdomain * to set 690 * @bank: memory bank number to set (0-3) 691 * @pwrst: one of the PWRDM_POWER_* macros 692 * 693 * Set the next power state @pwrst that memory bank @bank of the 694 * powerdomain @pwrdm will enter when the powerdomain enters the 695 * RETENTION state. Bank will be a number from 0 to 3, and represents 696 * different types of memory, depending on the powerdomain. @pwrst 697 * will be either RETENTION or OFF, if supported. Returns -EINVAL if 698 * the powerdomain pointer is null or the target power state is not 699 * supported for this memory bank, -EEXIST if the target memory 700 * bank does not exist or is not controllable, or returns 0 upon 701 * success. 702 */ 703 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) 704 { 705 int ret = -EINVAL; 706 707 if (!pwrdm) 708 return -EINVAL; 709 710 if (pwrdm->banks < (bank + 1)) 711 return -EEXIST; 712 713 if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst))) 714 return -EINVAL; 715 716 pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-RET to %0x\n", 717 pwrdm->name, bank, pwrst); 718 719 if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst) 720 ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst); 721 722 return ret; 723 } 724 725 /** 726 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state 727 * @pwrdm: struct powerdomain * to get current logic retention power state 728 * 729 * Return the power state that the logic portion of powerdomain @pwrdm 730 * will enter when the powerdomain enters retention. Returns -EINVAL 731 * if the powerdomain pointer is null or returns the logic retention 732 * power state upon success. 733 */ 734 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) 735 { 736 int ret = -EINVAL; 737 738 if (!pwrdm) 739 return -EINVAL; 740 741 if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst) 742 ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm); 743 744 return ret; 745 } 746 747 /** 748 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state 749 * @pwrdm: struct powerdomain * to get previous logic power state 750 * 751 * Return the powerdomain @pwrdm's previous logic power state. Returns 752 * -EINVAL if the powerdomain pointer is null or returns the previous 753 * logic power state upon success. 754 */ 755 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) 756 { 757 int ret = -EINVAL; 758 759 if (!pwrdm) 760 return -EINVAL; 761 762 if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst) 763 ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm); 764 765 return ret; 766 } 767 768 /** 769 * pwrdm_read_logic_retst - get next powerdomain logic power state 770 * @pwrdm: struct powerdomain * to get next logic power state 771 * 772 * Return the powerdomain pwrdm's logic power state. Returns -EINVAL 773 * if the powerdomain pointer is null or returns the next logic 774 * power state upon success. 775 */ 776 int pwrdm_read_logic_retst(struct powerdomain *pwrdm) 777 { 778 int ret = -EINVAL; 779 780 if (!pwrdm) 781 return -EINVAL; 782 783 if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst) 784 ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm); 785 786 return ret; 787 } 788 789 /** 790 * pwrdm_read_mem_pwrst - get current memory bank power state 791 * @pwrdm: struct powerdomain * to get current memory bank power state 792 * @bank: memory bank number (0-3) 793 * 794 * Return the powerdomain @pwrdm's current memory power state for bank 795 * @bank. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if 796 * the target memory bank does not exist or is not controllable, or 797 * returns the current memory power state upon success. 798 */ 799 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 800 { 801 int ret = -EINVAL; 802 803 if (!pwrdm) 804 return ret; 805 806 if (pwrdm->banks < (bank + 1)) 807 return ret; 808 809 if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) 810 bank = 1; 811 812 if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst) 813 ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank); 814 815 return ret; 816 } 817 818 /** 819 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state 820 * @pwrdm: struct powerdomain * to get previous memory bank power state 821 * @bank: memory bank number (0-3) 822 * 823 * Return the powerdomain @pwrdm's previous memory power state for 824 * bank @bank. Returns -EINVAL if the powerdomain pointer is null, 825 * -EEXIST if the target memory bank does not exist or is not 826 * controllable, or returns the previous memory power state upon 827 * success. 828 */ 829 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 830 { 831 int ret = -EINVAL; 832 833 if (!pwrdm) 834 return ret; 835 836 if (pwrdm->banks < (bank + 1)) 837 return ret; 838 839 if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) 840 bank = 1; 841 842 if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst) 843 ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank); 844 845 return ret; 846 } 847 848 /** 849 * pwrdm_read_mem_retst - get next memory bank power state 850 * @pwrdm: struct powerdomain * to get mext memory bank power state 851 * @bank: memory bank number (0-3) 852 * 853 * Return the powerdomain pwrdm's next memory power state for bank 854 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if 855 * the target memory bank does not exist or is not controllable, or 856 * returns the next memory power state upon success. 857 */ 858 int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) 859 { 860 int ret = -EINVAL; 861 862 if (!pwrdm) 863 return ret; 864 865 if (pwrdm->banks < (bank + 1)) 866 return ret; 867 868 if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst) 869 ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank); 870 871 return ret; 872 } 873 874 /** 875 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm 876 * @pwrdm: struct powerdomain * to clear 877 * 878 * Clear the powerdomain's previous power state register @pwrdm. 879 * Clears the entire register, including logic and memory bank 880 * previous power states. Returns -EINVAL if the powerdomain pointer 881 * is null, or returns 0 upon success. 882 */ 883 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) 884 { 885 int ret = -EINVAL; 886 887 if (!pwrdm) 888 return ret; 889 890 /* 891 * XXX should get the powerdomain's current state here; 892 * warn & fail if it is not ON. 893 */ 894 895 pr_debug("powerdomain: %s: clearing previous power state reg\n", 896 pwrdm->name); 897 898 if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst) 899 ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm); 900 901 return ret; 902 } 903 904 /** 905 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm 906 * @pwrdm: struct powerdomain * 907 * 908 * Enable automatic context save-and-restore upon power state change 909 * for some devices in the powerdomain @pwrdm. Warning: this only 910 * affects a subset of devices in a powerdomain; check the TRM 911 * closely. Returns -EINVAL if the powerdomain pointer is null or if 912 * the powerdomain does not support automatic save-and-restore, or 913 * returns 0 upon success. 914 */ 915 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) 916 { 917 int ret = -EINVAL; 918 919 if (!pwrdm) 920 return ret; 921 922 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) 923 return ret; 924 925 pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", pwrdm->name); 926 927 if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar) 928 ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm); 929 930 return ret; 931 } 932 933 /** 934 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm 935 * @pwrdm: struct powerdomain * 936 * 937 * Disable automatic context save-and-restore upon power state change 938 * for some devices in the powerdomain @pwrdm. Warning: this only 939 * affects a subset of devices in a powerdomain; check the TRM 940 * closely. Returns -EINVAL if the powerdomain pointer is null or if 941 * the powerdomain does not support automatic save-and-restore, or 942 * returns 0 upon success. 943 */ 944 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) 945 { 946 int ret = -EINVAL; 947 948 if (!pwrdm) 949 return ret; 950 951 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) 952 return ret; 953 954 pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", pwrdm->name); 955 956 if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar) 957 ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm); 958 959 return ret; 960 } 961 962 /** 963 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR 964 * @pwrdm: struct powerdomain * 965 * 966 * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore 967 * for some devices, or 0 if it does not. 968 */ 969 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) 970 { 971 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; 972 } 973 974 int pwrdm_state_switch_nolock(struct powerdomain *pwrdm) 975 { 976 int ret; 977 978 if (!pwrdm || !arch_pwrdm) 979 return -EINVAL; 980 981 ret = arch_pwrdm->pwrdm_wait_transition(pwrdm); 982 if (!ret) 983 ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); 984 985 return ret; 986 } 987 988 int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm) 989 { 990 int ret; 991 992 pwrdm_lock(pwrdm); 993 ret = pwrdm_state_switch_nolock(pwrdm); 994 pwrdm_unlock(pwrdm); 995 996 return ret; 997 } 998 999 int pwrdm_pre_transition(struct powerdomain *pwrdm) 1000 { 1001 if (pwrdm) 1002 _pwrdm_pre_transition_cb(pwrdm, NULL); 1003 else 1004 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); 1005 1006 return 0; 1007 } 1008 1009 int pwrdm_post_transition(struct powerdomain *pwrdm) 1010 { 1011 if (pwrdm) 1012 _pwrdm_post_transition_cb(pwrdm, NULL); 1013 else 1014 pwrdm_for_each(_pwrdm_post_transition_cb, NULL); 1015 1016 return 0; 1017 } 1018 1019 /** 1020 * pwrdm_get_valid_lp_state() - Find best match deep power state 1021 * @pwrdm: power domain for which we want to find best match 1022 * @is_logic_state: Are we looking for logic state match here? Should 1023 * be one of PWRDM_xxx macro values 1024 * @req_state: requested power state 1025 * 1026 * Returns: closest match for requested power state. default fallback 1027 * is RET for logic state and ON for power state. 1028 * 1029 * This does a search from the power domain data looking for the 1030 * closest valid power domain state that the hardware can achieve. 1031 * PRCM definitions for PWRSTCTRL allows us to program whatever 1032 * configuration we'd like, and PRCM will actually attempt such 1033 * a transition, however if the powerdomain does not actually support it, 1034 * we endup with a hung system. The valid power domain states are already 1035 * available in our powerdomain data files. So this function tries to do 1036 * the following: 1037 * a) find if we have an exact match to the request - no issues. 1038 * b) else find if a deeper power state is possible. 1039 * c) failing which, it tries to find closest higher power state for the 1040 * request. 1041 */ 1042 u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm, 1043 bool is_logic_state, u8 req_state) 1044 { 1045 u8 pwrdm_states = is_logic_state ? pwrdm->pwrsts_logic_ret : 1046 pwrdm->pwrsts; 1047 /* For logic, ret is highest and others, ON is highest */ 1048 u8 default_pwrst = is_logic_state ? PWRDM_POWER_RET : PWRDM_POWER_ON; 1049 u8 new_pwrst; 1050 bool found; 1051 1052 /* If it is already supported, nothing to search */ 1053 if (pwrdm_states & BIT(req_state)) 1054 return req_state; 1055 1056 if (!req_state) 1057 goto up_search; 1058 1059 /* 1060 * So, we dont have a exact match 1061 * Can we get a deeper power state match? 1062 */ 1063 new_pwrst = req_state - 1; 1064 found = true; 1065 while (!(pwrdm_states & BIT(new_pwrst))) { 1066 /* No match even at OFF? Not available */ 1067 if (new_pwrst == PWRDM_POWER_OFF) { 1068 found = false; 1069 break; 1070 } 1071 new_pwrst--; 1072 } 1073 1074 if (found) 1075 goto done; 1076 1077 up_search: 1078 /* OK, no deeper ones, can we get a higher match? */ 1079 new_pwrst = req_state + 1; 1080 while (!(pwrdm_states & BIT(new_pwrst))) { 1081 if (new_pwrst > PWRDM_POWER_ON) { 1082 WARN(1, "powerdomain: %s: Fix max powerstate to ON\n", 1083 pwrdm->name); 1084 return PWRDM_POWER_ON; 1085 } 1086 1087 if (new_pwrst == default_pwrst) 1088 break; 1089 new_pwrst++; 1090 } 1091 done: 1092 return new_pwrst; 1093 } 1094 1095 /** 1096 * omap_set_pwrdm_state - change a powerdomain's current power state 1097 * @pwrdm: struct powerdomain * to change the power state of 1098 * @pwrst: power state to change to 1099 * 1100 * Change the current hardware power state of the powerdomain 1101 * represented by @pwrdm to the power state represented by @pwrst. 1102 * Returns -EINVAL if @pwrdm is null or invalid or if the 1103 * powerdomain's current power state could not be read, or returns 0 1104 * upon success or if @pwrdm does not support @pwrst or any 1105 * lower-power state. XXX Should not return 0 if the @pwrdm does not 1106 * support @pwrst or any lower-power state: this should be an error. 1107 */ 1108 int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) 1109 { 1110 u8 next_pwrst, sleep_switch; 1111 int curr_pwrst; 1112 int ret = 0; 1113 1114 if (!pwrdm || IS_ERR(pwrdm)) 1115 return -EINVAL; 1116 1117 while (!(pwrdm->pwrsts & (1 << pwrst))) { 1118 if (pwrst == PWRDM_POWER_OFF) 1119 return ret; 1120 pwrst--; 1121 } 1122 1123 pwrdm_lock(pwrdm); 1124 1125 curr_pwrst = pwrdm_read_pwrst(pwrdm); 1126 if (curr_pwrst < 0) { 1127 ret = -EINVAL; 1128 goto osps_out; 1129 } 1130 1131 next_pwrst = pwrdm_read_next_pwrst(pwrdm); 1132 if (curr_pwrst == pwrst && next_pwrst == pwrst) 1133 goto osps_out; 1134 1135 sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst, 1136 pwrst); 1137 1138 ret = pwrdm_set_next_pwrst(pwrdm, pwrst); 1139 if (ret) 1140 pr_err("%s: unable to set power state of powerdomain: %s\n", 1141 __func__, pwrdm->name); 1142 1143 _pwrdm_restore_clkdm_state(pwrdm, sleep_switch); 1144 1145 osps_out: 1146 pwrdm_unlock(pwrdm); 1147 1148 return ret; 1149 } 1150 1151 /** 1152 * pwrdm_save_context - save powerdomain registers 1153 * 1154 * Register state is going to be lost due to a suspend or hibernate 1155 * event. Save the powerdomain registers. 1156 */ 1157 static int pwrdm_save_context(struct powerdomain *pwrdm, void *unused) 1158 { 1159 if (arch_pwrdm && arch_pwrdm->pwrdm_save_context) 1160 arch_pwrdm->pwrdm_save_context(pwrdm); 1161 return 0; 1162 } 1163 1164 /** 1165 * pwrdm_restore_context - restore powerdomain registers 1166 * 1167 * Restore powerdomain control registers after a suspend or resume 1168 * event. 1169 */ 1170 static int pwrdm_restore_context(struct powerdomain *pwrdm, void *unused) 1171 { 1172 if (arch_pwrdm && arch_pwrdm->pwrdm_restore_context) 1173 arch_pwrdm->pwrdm_restore_context(pwrdm); 1174 return 0; 1175 } 1176 1177 static void pwrdms_save_context(void) 1178 { 1179 pwrdm_for_each(pwrdm_save_context, NULL); 1180 } 1181 1182 static void pwrdms_restore_context(void) 1183 { 1184 pwrdm_for_each(pwrdm_restore_context, NULL); 1185 } 1186
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.