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