powerdomain.c (33999B)
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 40void pwrdms_save_context(void); 41void pwrdms_restore_context(void); 42 43enum { 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 */ 59static LIST_HEAD(pwrdm_list); 60 61static struct pwrdm_ops *arch_pwrdm; 62 63/* Private functions */ 64 65static 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 */ 89static 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); 119skip_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 142static 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 161static 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 (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_rcuidle(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 209static 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 216static 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 */ 236static 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 */ 270static 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 */ 298int 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 */ 321int 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 337static 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 */ 364int 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 */ 390void 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 */ 402void 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 */ 415struct 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 */ 437int 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 */ 465int 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 499pac_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 */ 510int 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 */ 529int 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_rcuidle(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 */ 561int 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 */ 583int 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 */ 607int 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 */ 631int 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 */ 665int 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 */ 703int 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 */ 734int 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 */ 755int 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 */ 776int 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 */ 799int 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 */ 829int 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 */ 858int 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 */ 883int 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 */ 915int 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 */ 944int 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 */ 969bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) 970{ 971 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; 972} 973 974int 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 988int __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 999int 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 1009int 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 */ 1042u8 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 1077up_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 } 1091done: 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 */ 1108int 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 1145osps_out: 1146 pwrdm_unlock(pwrdm); 1147 1148 return ret; 1149} 1150 1151/** 1152 * pwrdm_get_context_loss_count - get powerdomain's context loss count 1153 * @pwrdm: struct powerdomain * to wait for 1154 * 1155 * Context loss count is the sum of powerdomain off-mode counter, the 1156 * logic off counter and the per-bank memory off counter. Returns negative 1157 * (and WARNs) upon error, otherwise, returns the context loss count. 1158 */ 1159int pwrdm_get_context_loss_count(struct powerdomain *pwrdm) 1160{ 1161 int i, count; 1162 1163 if (!pwrdm) { 1164 WARN(1, "powerdomain: %s: pwrdm is null\n", __func__); 1165 return -ENODEV; 1166 } 1167 1168 count = pwrdm->state_counter[PWRDM_POWER_OFF]; 1169 count += pwrdm->ret_logic_off_counter; 1170 1171 for (i = 0; i < pwrdm->banks; i++) 1172 count += pwrdm->ret_mem_off_counter[i]; 1173 1174 /* 1175 * Context loss count has to be a non-negative value. Clear the sign 1176 * bit to get a value range from 0 to INT_MAX. 1177 */ 1178 count &= INT_MAX; 1179 1180 pr_debug("powerdomain: %s: context loss count = %d\n", 1181 pwrdm->name, count); 1182 1183 return count; 1184} 1185 1186/** 1187 * pwrdm_can_ever_lose_context - can this powerdomain ever lose context? 1188 * @pwrdm: struct powerdomain * 1189 * 1190 * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain 1191 * can lose either memory or logic context or if @pwrdm is invalid, or 1192 * returns 0 otherwise. This function is not concerned with how the 1193 * powerdomain registers are programmed (i.e., to go off or not); it's 1194 * concerned with whether it's ever possible for this powerdomain to 1195 * go off while some other part of the chip is active. This function 1196 * assumes that every powerdomain can go to either ON or INACTIVE. 1197 */ 1198bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm) 1199{ 1200 int i; 1201 1202 if (!pwrdm) { 1203 pr_debug("powerdomain: %s: invalid powerdomain pointer\n", 1204 __func__); 1205 return true; 1206 } 1207 1208 if (pwrdm->pwrsts & PWRSTS_OFF) 1209 return true; 1210 1211 if (pwrdm->pwrsts & PWRSTS_RET) { 1212 if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF) 1213 return true; 1214 1215 for (i = 0; i < pwrdm->banks; i++) 1216 if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF) 1217 return true; 1218 } 1219 1220 for (i = 0; i < pwrdm->banks; i++) 1221 if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF) 1222 return true; 1223 1224 return false; 1225} 1226 1227/** 1228 * pwrdm_save_context - save powerdomain registers 1229 * 1230 * Register state is going to be lost due to a suspend or hibernate 1231 * event. Save the powerdomain registers. 1232 */ 1233static int pwrdm_save_context(struct powerdomain *pwrdm, void *unused) 1234{ 1235 if (arch_pwrdm && arch_pwrdm->pwrdm_save_context) 1236 arch_pwrdm->pwrdm_save_context(pwrdm); 1237 return 0; 1238} 1239 1240/** 1241 * pwrdm_save_context - restore powerdomain registers 1242 * 1243 * Restore powerdomain control registers after a suspend or resume 1244 * event. 1245 */ 1246static int pwrdm_restore_context(struct powerdomain *pwrdm, void *unused) 1247{ 1248 if (arch_pwrdm && arch_pwrdm->pwrdm_restore_context) 1249 arch_pwrdm->pwrdm_restore_context(pwrdm); 1250 return 0; 1251} 1252 1253static int pwrdm_lost_power(struct powerdomain *pwrdm, void *unused) 1254{ 1255 int state; 1256 1257 /* 1258 * Power has been lost across all powerdomains, increment the 1259 * counter. 1260 */ 1261 1262 state = pwrdm_read_pwrst(pwrdm); 1263 if (state != PWRDM_POWER_OFF) { 1264 pwrdm->state_counter[state]++; 1265 pwrdm->state_counter[PWRDM_POWER_OFF]++; 1266 } 1267 pwrdm->state = state; 1268 1269 return 0; 1270} 1271 1272void pwrdms_save_context(void) 1273{ 1274 pwrdm_for_each(pwrdm_save_context, NULL); 1275} 1276 1277void pwrdms_restore_context(void) 1278{ 1279 pwrdm_for_each(pwrdm_restore_context, NULL); 1280} 1281 1282void pwrdms_lost_power(void) 1283{ 1284 pwrdm_for_each(pwrdm_lost_power, NULL); 1285}