1 /* 2 * OMAP powerdomain control 3 * 4 * Copyright (C) 2007-2008 Texas Instruments, Inc. 5 * Copyright (C) 2007-2008 Nokia Corporation 6 * 7 * Written by Paul Walmsley 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 #ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN 14 # define DEBUG 15 #endif 16 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/types.h> 20 #include <linux/delay.h> 21 #include <linux/spinlock.h> 22 #include <linux/list.h> 23 #include <linux/errno.h> 24 #include <linux/err.h> 25 #include <linux/io.h> 26 27 #include <asm/atomic.h> 28 29 #include "cm.h" 30 #include "cm-regbits-34xx.h" 31 #include "prm.h" 32 #include "prm-regbits-34xx.h" 33 34 #include <mach/cpu.h> 35 #include <mach/powerdomain.h> 36 #include <mach/clockdomain.h> 37 38 #include "pm.h" 39 40 enum { 41 PWRDM_STATE_NOW = 0, 42 PWRDM_STATE_PREV, 43 }; 44 45 /* pwrdm_list contains all registered struct powerdomains */ 46 static LIST_HEAD(pwrdm_list); 47 48 /* 49 * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to 50 * protect pwrdm_clkdms[] during clkdm add/del ops 51 */ 52 static DEFINE_RWLOCK(pwrdm_rwlock); 53 54 55 /* Private functions */ 56 57 static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) 58 { 59 u32 v; 60 61 v = prm_read_mod_reg(domain, idx); 62 v &= mask; 63 v >>= __ffs(mask); 64 65 return v; 66 } 67 68 static struct powerdomain *_pwrdm_lookup(const char *name) 69 { 70 struct powerdomain *pwrdm, *temp_pwrdm; 71 72 pwrdm = NULL; 73 74 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { 75 if (!strcmp(name, temp_pwrdm->name)) { 76 pwrdm = temp_pwrdm; 77 break; 78 } 79 } 80 81 return pwrdm; 82 } 83 84 /* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */ 85 static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm, 86 struct pwrdm_dep *deps) 87 { 88 struct pwrdm_dep *pd; 89 90 if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip)) 91 return ERR_PTR(-EINVAL); 92 93 for (pd = deps; pd->pwrdm_name; pd++) { 94 95 if (!omap_chip_is(pd->omap_chip)) 96 continue; 97 98 if (!pd->pwrdm && pd->pwrdm_name) 99 pd->pwrdm = pwrdm_lookup(pd->pwrdm_name); 100 101 if (pd->pwrdm == pwrdm) 102 break; 103 104 } 105 106 if (!pd->pwrdm_name) 107 return ERR_PTR(-ENOENT); 108 109 return pd->pwrdm; 110 } 111 112 static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) 113 { 114 115 int prev; 116 int state; 117 118 if (pwrdm == NULL) 119 return -EINVAL; 120 121 state = pwrdm_read_pwrst(pwrdm); 122 123 switch (flag) { 124 case PWRDM_STATE_NOW: 125 prev = pwrdm->state; 126 break; 127 case PWRDM_STATE_PREV: 128 prev = pwrdm_read_prev_pwrst(pwrdm); 129 if (pwrdm->state != prev) 130 pwrdm->state_counter[prev]++; 131 break; 132 default: 133 return -EINVAL; 134 } 135 136 if (state != prev) 137 pwrdm->state_counter[state]++; 138 139 pm_dbg_update_time(pwrdm, prev); 140 141 pwrdm->state = state; 142 143 return 0; 144 } 145 146 static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused) 147 { 148 pwrdm_clear_all_prev_pwrst(pwrdm); 149 _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); 150 return 0; 151 } 152 153 static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) 154 { 155 _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV); 156 return 0; 157 } 158 159 static __init void _pwrdm_setup(struct powerdomain *pwrdm) 160 { 161 int i; 162 163 for (i = 0; i < 4; i++) 164 pwrdm->state_counter[i] = 0; 165 166 pwrdm_wait_transition(pwrdm); 167 pwrdm->state = pwrdm_read_pwrst(pwrdm); 168 pwrdm->state_counter[pwrdm->state] = 1; 169 170 } 171 172 /* Public functions */ 173 174 /** 175 * pwrdm_init - set up the powerdomain layer 176 * 177 * Loop through the list of powerdomains, registering all that are 178 * available on the current CPU. If pwrdm_list is supplied and not 179 * null, all of the referenced powerdomains will be registered. No 180 * return value. 181 */ 182 void pwrdm_init(struct powerdomain **pwrdm_list) 183 { 184 struct powerdomain **p = NULL; 185 186 if (pwrdm_list) { 187 for (p = pwrdm_list; *p; p++) { 188 pwrdm_register(*p); 189 _pwrdm_setup(*p); 190 } 191 } 192 } 193 194 /** 195 * pwrdm_register - register a powerdomain 196 * @pwrdm: struct powerdomain * to register 197 * 198 * Adds a powerdomain to the internal powerdomain list. Returns 199 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is 200 * already registered by the provided name, or 0 upon success. 201 */ 202 int pwrdm_register(struct powerdomain *pwrdm) 203 { 204 unsigned long flags; 205 int ret = -EINVAL; 206 207 if (!pwrdm) 208 return -EINVAL; 209 210 if (!omap_chip_is(pwrdm->omap_chip)) 211 return -EINVAL; 212 213 write_lock_irqsave(&pwrdm_rwlock, flags); 214 if (_pwrdm_lookup(pwrdm->name)) { 215 ret = -EEXIST; 216 goto pr_unlock; 217 } 218 219 list_add(&pwrdm->node, &pwrdm_list); 220 221 pr_debug("powerdomain: registered %s\n", pwrdm->name); 222 ret = 0; 223 224 pr_unlock: 225 write_unlock_irqrestore(&pwrdm_rwlock, flags); 226 227 return ret; 228 } 229 230 /** 231 * pwrdm_unregister - unregister a powerdomain 232 * @pwrdm: struct powerdomain * to unregister 233 * 234 * Removes a powerdomain from the internal powerdomain list. Returns 235 * -EINVAL if pwrdm argument is NULL. 236 */ 237 int pwrdm_unregister(struct powerdomain *pwrdm) 238 { 239 unsigned long flags; 240 241 if (!pwrdm) 242 return -EINVAL; 243 244 write_lock_irqsave(&pwrdm_rwlock, flags); 245 list_del(&pwrdm->node); 246 write_unlock_irqrestore(&pwrdm_rwlock, flags); 247 248 pr_debug("powerdomain: unregistered %s\n", pwrdm->name); 249 250 return 0; 251 } 252 253 /** 254 * pwrdm_lookup - look up a powerdomain by name, return a pointer 255 * @name: name of powerdomain 256 * 257 * Find a registered powerdomain by its name. Returns a pointer to the 258 * struct powerdomain if found, or NULL otherwise. 259 */ 260 struct powerdomain *pwrdm_lookup(const char *name) 261 { 262 struct powerdomain *pwrdm; 263 unsigned long flags; 264 265 if (!name) 266 return NULL; 267 268 read_lock_irqsave(&pwrdm_rwlock, flags); 269 pwrdm = _pwrdm_lookup(name); 270 read_unlock_irqrestore(&pwrdm_rwlock, flags); 271 272 return pwrdm; 273 } 274 275 /** 276 * pwrdm_for_each - call function on each registered clockdomain 277 * @fn: callback function * 278 * 279 * Call the supplied function for each registered powerdomain. The 280 * callback function can return anything but 0 to bail out early from 281 * the iterator. The callback function is called with the pwrdm_rwlock 282 * held for reading, so no powerdomain structure manipulation 283 * functions should be called from the callback, although hardware 284 * powerdomain control functions are fine. Returns the last return 285 * value of the callback function, which should be 0 for success or 286 * anything else to indicate failure; or -EINVAL if the function 287 * pointer is null. 288 */ 289 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), 290 void *user) 291 { 292 struct powerdomain *temp_pwrdm; 293 unsigned long flags; 294 int ret = 0; 295 296 if (!fn) 297 return -EINVAL; 298 299 read_lock_irqsave(&pwrdm_rwlock, flags); 300 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { 301 ret = (*fn)(temp_pwrdm, user); 302 if (ret) 303 break; 304 } 305 read_unlock_irqrestore(&pwrdm_rwlock, flags); 306 307 return ret; 308 } 309 310 /** 311 * pwrdm_add_clkdm - add a clockdomain to a powerdomain 312 * @pwrdm: struct powerdomain * to add the clockdomain to 313 * @clkdm: struct clockdomain * to associate with a powerdomain 314 * 315 * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'. This 316 * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if 317 * presented with invalid pointers; -ENOMEM if memory could not be allocated; 318 * or 0 upon success. 319 */ 320 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) 321 { 322 unsigned long flags; 323 int i; 324 int ret = -EINVAL; 325 326 if (!pwrdm || !clkdm) 327 return -EINVAL; 328 329 pr_debug("powerdomain: associating clockdomain %s with powerdomain " 330 "%s\n", clkdm->name, pwrdm->name); 331 332 write_lock_irqsave(&pwrdm_rwlock, flags); 333 334 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) { 335 if (!pwrdm->pwrdm_clkdms[i]) 336 break; 337 #ifdef DEBUG 338 if (pwrdm->pwrdm_clkdms[i] == clkdm) { 339 ret = -EINVAL; 340 goto pac_exit; 341 } 342 #endif 343 } 344 345 if (i == PWRDM_MAX_CLKDMS) { 346 pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for " 347 "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name); 348 WARN_ON(1); 349 ret = -ENOMEM; 350 goto pac_exit; 351 } 352 353 pwrdm->pwrdm_clkdms[i] = clkdm; 354 355 ret = 0; 356 357 pac_exit: 358 write_unlock_irqrestore(&pwrdm_rwlock, flags); 359 360 return ret; 361 } 362 363 /** 364 * pwrdm_del_clkdm - remove a clockdomain from a powerdomain 365 * @pwrdm: struct powerdomain * to add the clockdomain to 366 * @clkdm: struct clockdomain * to associate with a powerdomain 367 * 368 * Dissociate the clockdomain 'clkdm' from the powerdomain 369 * 'pwrdm'. Returns -EINVAL if presented with invalid pointers; 370 * -ENOENT if the clkdm was not associated with the powerdomain, or 0 371 * upon success. 372 */ 373 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) 374 { 375 unsigned long flags; 376 int ret = -EINVAL; 377 int i; 378 379 if (!pwrdm || !clkdm) 380 return -EINVAL; 381 382 pr_debug("powerdomain: dissociating clockdomain %s from powerdomain " 383 "%s\n", clkdm->name, pwrdm->name); 384 385 write_lock_irqsave(&pwrdm_rwlock, flags); 386 387 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) 388 if (pwrdm->pwrdm_clkdms[i] == clkdm) 389 break; 390 391 if (i == PWRDM_MAX_CLKDMS) { 392 pr_debug("powerdomain: clkdm %s not associated with pwrdm " 393 "%s ?!\n", clkdm->name, pwrdm->name); 394 ret = -ENOENT; 395 goto pdc_exit; 396 } 397 398 pwrdm->pwrdm_clkdms[i] = NULL; 399 400 ret = 0; 401 402 pdc_exit: 403 write_unlock_irqrestore(&pwrdm_rwlock, flags); 404 405 return ret; 406 } 407 408 /** 409 * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm 410 * @pwrdm: struct powerdomain * to iterate over 411 * @fn: callback function * 412 * 413 * Call the supplied function for each clockdomain in the powerdomain 414 * 'pwrdm'. The callback function can return anything but 0 to bail 415 * out early from the iterator. The callback function is called with 416 * the pwrdm_rwlock held for reading, so no powerdomain structure 417 * manipulation functions should be called from the callback, although 418 * hardware powerdomain control functions are fine. Returns -EINVAL 419 * if presented with invalid pointers; or passes along the last return 420 * value of the callback function, which should be 0 for success or 421 * anything else to indicate failure. 422 */ 423 int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, 424 int (*fn)(struct powerdomain *pwrdm, 425 struct clockdomain *clkdm)) 426 { 427 unsigned long flags; 428 int ret = 0; 429 int i; 430 431 if (!fn) 432 return -EINVAL; 433 434 read_lock_irqsave(&pwrdm_rwlock, flags); 435 436 for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++) 437 ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]); 438 439 read_unlock_irqrestore(&pwrdm_rwlock, flags); 440 441 return ret; 442 } 443 444 445 /** 446 * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1 447 * @pwrdm1: wake this struct powerdomain * up (dependent) 448 * @pwrdm2: when this struct powerdomain * wakes up (source) 449 * 450 * When the powerdomain represented by pwrdm2 wakes up (due to an 451 * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP, 452 * this feature is designed to reduce wakeup latency of the dependent 453 * powerdomain. Returns -EINVAL if presented with invalid powerdomain 454 * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or 455 * 0 upon success. 456 */ 457 int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) 458 { 459 struct powerdomain *p; 460 461 if (!pwrdm1) 462 return -EINVAL; 463 464 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); 465 if (IS_ERR(p)) { 466 pr_debug("powerdomain: hardware cannot set/clear wake up of " 467 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); 468 return IS_ERR(p); 469 } 470 471 pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n", 472 pwrdm1->name, pwrdm2->name); 473 474 prm_set_mod_reg_bits((1 << pwrdm2->dep_bit), 475 pwrdm1->prcm_offs, PM_WKDEP); 476 477 return 0; 478 } 479 480 /** 481 * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1 482 * @pwrdm1: wake this struct powerdomain * up (dependent) 483 * @pwrdm2: when this struct powerdomain * wakes up (source) 484 * 485 * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2 486 * wakes up. Returns -EINVAL if presented with invalid powerdomain 487 * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or 488 * 0 upon success. 489 */ 490 int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) 491 { 492 struct powerdomain *p; 493 494 if (!pwrdm1) 495 return -EINVAL; 496 497 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); 498 if (IS_ERR(p)) { 499 pr_debug("powerdomain: hardware cannot set/clear wake up of " 500 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); 501 return IS_ERR(p); 502 } 503 504 pr_debug("powerdomain: hardware will no longer wake up %s after %s " 505 "wakes up\n", pwrdm1->name, pwrdm2->name); 506 507 prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit), 508 pwrdm1->prcm_offs, PM_WKDEP); 509 510 return 0; 511 } 512 513 /** 514 * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1 515 * @pwrdm1: wake this struct powerdomain * up (dependent) 516 * @pwrdm2: when this struct powerdomain * wakes up (source) 517 * 518 * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be 519 * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL 520 * if either powerdomain pointer is invalid; or -ENOENT if the hardware 521 * is incapable. 522 * 523 * REVISIT: Currently this function only represents software-controllable 524 * wakeup dependencies. Wakeup dependencies fixed in hardware are not 525 * yet handled here. 526 */ 527 int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) 528 { 529 struct powerdomain *p; 530 531 if (!pwrdm1) 532 return -EINVAL; 533 534 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); 535 if (IS_ERR(p)) { 536 pr_debug("powerdomain: hardware cannot set/clear wake up of " 537 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); 538 return IS_ERR(p); 539 } 540 541 return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP, 542 (1 << pwrdm2->dep_bit)); 543 } 544 545 /** 546 * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1 547 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) 548 * @pwrdm2: when this struct powerdomain * is active (source) 549 * 550 * Prevent pwrdm1 from automatically going inactive (and then to 551 * retention or off) if pwrdm2 is still active. Returns -EINVAL if 552 * presented with invalid powerdomain pointers or called on a machine 553 * that does not support software-configurable hardware sleep dependencies, 554 * -ENOENT if the specified dependency cannot be set in hardware, or 555 * 0 upon success. 556 */ 557 int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) 558 { 559 struct powerdomain *p; 560 561 if (!pwrdm1) 562 return -EINVAL; 563 564 if (!cpu_is_omap34xx()) 565 return -EINVAL; 566 567 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); 568 if (IS_ERR(p)) { 569 pr_debug("powerdomain: hardware cannot set/clear sleep " 570 "dependency affecting %s from %s\n", pwrdm1->name, 571 pwrdm2->name); 572 return IS_ERR(p); 573 } 574 575 pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n", 576 pwrdm1->name, pwrdm2->name); 577 578 cm_set_mod_reg_bits((1 << pwrdm2->dep_bit), 579 pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP); 580 581 return 0; 582 } 583 584 /** 585 * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1 586 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) 587 * @pwrdm2: when this struct powerdomain * is active (source) 588 * 589 * Allow pwrdm1 to automatically go inactive (and then to retention or 590 * off), independent of the activity state of pwrdm2. Returns -EINVAL 591 * if presented with invalid powerdomain pointers or called on a machine 592 * that does not support software-configurable hardware sleep dependencies, 593 * -ENOENT if the specified dependency cannot be cleared in hardware, or 594 * 0 upon success. 595 */ 596 int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) 597 { 598 struct powerdomain *p; 599 600 if (!pwrdm1) 601 return -EINVAL; 602 603 if (!cpu_is_omap34xx()) 604 return -EINVAL; 605 606 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); 607 if (IS_ERR(p)) { 608 pr_debug("powerdomain: hardware cannot set/clear sleep " 609 "dependency affecting %s from %s\n", pwrdm1->name, 610 pwrdm2->name); 611 return IS_ERR(p); 612 } 613 614 pr_debug("powerdomain: will no longer prevent %s from sleeping if " 615 "%s is active\n", pwrdm1->name, pwrdm2->name); 616 617 cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit), 618 pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP); 619 620 return 0; 621 } 622 623 /** 624 * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1 625 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) 626 * @pwrdm2: when this struct powerdomain * is active (source) 627 * 628 * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will 629 * not be allowed to automatically go inactive if pwrdm2 is active; 630 * 0 if pwrdm1's automatic power state inactivity transition is independent 631 * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called 632 * on a machine that does not support software-configurable hardware sleep 633 * dependencies; or -ENOENT if the hardware is incapable. 634 * 635 * REVISIT: Currently this function only represents software-controllable 636 * sleep dependencies. Sleep dependencies fixed in hardware are not 637 * yet handled here. 638 */ 639 int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) 640 { 641 struct powerdomain *p; 642 643 if (!pwrdm1) 644 return -EINVAL; 645 646 if (!cpu_is_omap34xx()) 647 return -EINVAL; 648 649 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); 650 if (IS_ERR(p)) { 651 pr_debug("powerdomain: hardware cannot set/clear sleep " 652 "dependency affecting %s from %s\n", pwrdm1->name, 653 pwrdm2->name); 654 return IS_ERR(p); 655 } 656 657 return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP, 658 (1 << pwrdm2->dep_bit)); 659 } 660 661 /** 662 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain 663 * @pwrdm: struct powerdomain * 664 * 665 * Return the number of controllable memory banks in powerdomain pwrdm, 666 * starting with 1. Returns -EINVAL if the powerdomain pointer is null. 667 */ 668 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm) 669 { 670 if (!pwrdm) 671 return -EINVAL; 672 673 return pwrdm->banks; 674 } 675 676 /** 677 * pwrdm_set_next_pwrst - set next powerdomain power state 678 * @pwrdm: struct powerdomain * to set 679 * @pwrst: one of the PWRDM_POWER_* macros 680 * 681 * Set the powerdomain pwrdm's next power state to pwrst. The powerdomain 682 * may not enter this state immediately if the preconditions for this state 683 * have not been satisfied. Returns -EINVAL if the powerdomain pointer is 684 * null or if the power state is invalid for the powerdomin, or returns 0 685 * upon success. 686 */ 687 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) 688 { 689 if (!pwrdm) 690 return -EINVAL; 691 692 if (!(pwrdm->pwrsts & (1 << pwrst))) 693 return -EINVAL; 694 695 pr_debug("powerdomain: setting next powerstate for %s to %0x\n", 696 pwrdm->name, pwrst); 697 698 prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, 699 (pwrst << OMAP_POWERSTATE_SHIFT), 700 pwrdm->prcm_offs, PM_PWSTCTRL); 701 702 return 0; 703 } 704 705 /** 706 * pwrdm_read_next_pwrst - get next powerdomain power state 707 * @pwrdm: struct powerdomain * to get power state 708 * 709 * Return the powerdomain pwrdm's next power state. Returns -EINVAL 710 * if the powerdomain pointer is null or returns the next power state 711 * upon success. 712 */ 713 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm) 714 { 715 if (!pwrdm) 716 return -EINVAL; 717 718 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL, 719 OMAP_POWERSTATE_MASK); 720 } 721 722 /** 723 * pwrdm_read_pwrst - get current powerdomain power state 724 * @pwrdm: struct powerdomain * to get power state 725 * 726 * Return the powerdomain pwrdm's current power state. Returns -EINVAL 727 * if the powerdomain pointer is null or returns the current power state 728 * upon success. 729 */ 730 int pwrdm_read_pwrst(struct powerdomain *pwrdm) 731 { 732 if (!pwrdm) 733 return -EINVAL; 734 735 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, 736 OMAP_POWERSTATEST_MASK); 737 } 738 739 /** 740 * pwrdm_read_prev_pwrst - get previous powerdomain power state 741 * @pwrdm: struct powerdomain * to get previous power state 742 * 743 * Return the powerdomain pwrdm's previous power state. Returns -EINVAL 744 * if the powerdomain pointer is null or returns the previous power state 745 * upon success. 746 */ 747 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) 748 { 749 if (!pwrdm) 750 return -EINVAL; 751 752 return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, 753 OMAP3430_LASTPOWERSTATEENTERED_MASK); 754 } 755 756 /** 757 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention 758 * @pwrdm: struct powerdomain * to set 759 * @pwrst: one of the PWRDM_POWER_* macros 760 * 761 * Set the next power state that the logic portion of the powerdomain 762 * pwrdm will enter when the powerdomain enters retention. This will 763 * be either RETENTION or OFF, if supported. Returns -EINVAL if the 764 * powerdomain pointer is null or the target power state is not not 765 * supported, or returns 0 upon success. 766 */ 767 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) 768 { 769 if (!pwrdm) 770 return -EINVAL; 771 772 if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst))) 773 return -EINVAL; 774 775 pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n", 776 pwrdm->name, pwrst); 777 778 /* 779 * The register bit names below may not correspond to the 780 * actual names of the bits in each powerdomain's register, 781 * but the type of value returned is the same for each 782 * powerdomain. 783 */ 784 prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE, 785 (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)), 786 pwrdm->prcm_offs, PM_PWSTCTRL); 787 788 return 0; 789 } 790 791 /** 792 * pwrdm_set_mem_onst - set memory power state while powerdomain ON 793 * @pwrdm: struct powerdomain * to set 794 * @bank: memory bank number to set (0-3) 795 * @pwrst: one of the PWRDM_POWER_* macros 796 * 797 * Set the next power state that memory bank x of the powerdomain 798 * pwrdm will enter when the powerdomain enters the ON state. Bank 799 * will be a number from 0 to 3, and represents different types of 800 * memory, depending on the powerdomain. Returns -EINVAL if the 801 * powerdomain pointer is null or the target power state is not not 802 * supported for this memory bank, -EEXIST if the target memory bank 803 * does not exist or is not controllable, or returns 0 upon success. 804 */ 805 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) 806 { 807 u32 m; 808 809 if (!pwrdm) 810 return -EINVAL; 811 812 if (pwrdm->banks < (bank + 1)) 813 return -EEXIST; 814 815 if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst))) 816 return -EINVAL; 817 818 pr_debug("powerdomain: setting next memory powerstate for domain %s " 819 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst); 820 821 /* 822 * The register bit names below may not correspond to the 823 * actual names of the bits in each powerdomain's register, 824 * but the type of value returned is the same for each 825 * powerdomain. 826 */ 827 switch (bank) { 828 case 0: 829 m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK; 830 break; 831 case 1: 832 m = OMAP3430_L1FLATMEMONSTATE_MASK; 833 break; 834 case 2: 835 m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK; 836 break; 837 case 3: 838 m = OMAP3430_L2FLATMEMONSTATE_MASK; 839 break; 840 default: 841 WARN_ON(1); /* should never happen */ 842 return -EEXIST; 843 } 844 845 prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), 846 pwrdm->prcm_offs, PM_PWSTCTRL); 847 848 return 0; 849 } 850 851 /** 852 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET 853 * @pwrdm: struct powerdomain * to set 854 * @bank: memory bank number to set (0-3) 855 * @pwrst: one of the PWRDM_POWER_* macros 856 * 857 * Set the next power state that memory bank x of the powerdomain 858 * pwrdm will enter when the powerdomain enters the RETENTION state. 859 * Bank will be a number from 0 to 3, and represents different types 860 * of memory, depending on the powerdomain. pwrst will be either 861 * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain 862 * pointer is null or the target power state is not not supported for 863 * this memory bank, -EEXIST if the target memory bank does not exist 864 * or is not controllable, or returns 0 upon success. 865 */ 866 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) 867 { 868 u32 m; 869 870 if (!pwrdm) 871 return -EINVAL; 872 873 if (pwrdm->banks < (bank + 1)) 874 return -EEXIST; 875 876 if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst))) 877 return -EINVAL; 878 879 pr_debug("powerdomain: setting next memory powerstate for domain %s " 880 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst); 881 882 /* 883 * The register bit names below may not correspond to the 884 * actual names of the bits in each powerdomain's register, 885 * but the type of value returned is the same for each 886 * powerdomain. 887 */ 888 switch (bank) { 889 case 0: 890 m = OMAP3430_SHAREDL1CACHEFLATRETSTATE; 891 break; 892 case 1: 893 m = OMAP3430_L1FLATMEMRETSTATE; 894 break; 895 case 2: 896 m = OMAP3430_SHAREDL2CACHEFLATRETSTATE; 897 break; 898 case 3: 899 m = OMAP3430_L2FLATMEMRETSTATE; 900 break; 901 default: 902 WARN_ON(1); /* should never happen */ 903 return -EEXIST; 904 } 905 906 prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, 907 PM_PWSTCTRL); 908 909 return 0; 910 } 911 912 /** 913 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state 914 * @pwrdm: struct powerdomain * to get current logic retention power state 915 * 916 * Return the current power state that the logic portion of 917 * powerdomain pwrdm will enter 918 * Returns -EINVAL if the powerdomain pointer is null or returns the 919 * current logic retention power state upon success. 920 */ 921 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) 922 { 923 if (!pwrdm) 924 return -EINVAL; 925 926 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, 927 OMAP3430_LOGICSTATEST); 928 } 929 930 /** 931 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state 932 * @pwrdm: struct powerdomain * to get previous logic power state 933 * 934 * Return the powerdomain pwrdm's logic power state. Returns -EINVAL 935 * if the powerdomain pointer is null or returns the previous logic 936 * power state upon success. 937 */ 938 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) 939 { 940 if (!pwrdm) 941 return -EINVAL; 942 943 /* 944 * The register bit names below may not correspond to the 945 * actual names of the bits in each powerdomain's register, 946 * but the type of value returned is the same for each 947 * powerdomain. 948 */ 949 return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, 950 OMAP3430_LASTLOGICSTATEENTERED); 951 } 952 953 /** 954 * pwrdm_read_mem_pwrst - get current memory bank power state 955 * @pwrdm: struct powerdomain * to get current memory bank power state 956 * @bank: memory bank number (0-3) 957 * 958 * Return the powerdomain pwrdm's current memory power state for bank 959 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if 960 * the target memory bank does not exist or is not controllable, or 961 * returns the current memory power state upon success. 962 */ 963 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 964 { 965 u32 m; 966 967 if (!pwrdm) 968 return -EINVAL; 969 970 if (pwrdm->banks < (bank + 1)) 971 return -EEXIST; 972 973 /* 974 * The register bit names below may not correspond to the 975 * actual names of the bits in each powerdomain's register, 976 * but the type of value returned is the same for each 977 * powerdomain. 978 */ 979 switch (bank) { 980 case 0: 981 m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK; 982 break; 983 case 1: 984 m = OMAP3430_L1FLATMEMSTATEST_MASK; 985 break; 986 case 2: 987 m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK; 988 break; 989 case 3: 990 m = OMAP3430_L2FLATMEMSTATEST_MASK; 991 break; 992 default: 993 WARN_ON(1); /* should never happen */ 994 return -EEXIST; 995 } 996 997 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m); 998 } 999 1000 /** 1001 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state 1002 * @pwrdm: struct powerdomain * to get previous memory bank power state 1003 * @bank: memory bank number (0-3) 1004 * 1005 * Return the powerdomain pwrdm's previous memory power state for bank 1006 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if 1007 * the target memory bank does not exist or is not controllable, or 1008 * returns the previous memory power state upon success. 1009 */ 1010 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 1011 { 1012 u32 m; 1013 1014 if (!pwrdm) 1015 return -EINVAL; 1016 1017 if (pwrdm->banks < (bank + 1)) 1018 return -EEXIST; 1019 1020 /* 1021 * The register bit names below may not correspond to the 1022 * actual names of the bits in each powerdomain's register, 1023 * but the type of value returned is the same for each 1024 * powerdomain. 1025 */ 1026 switch (bank) { 1027 case 0: 1028 m = OMAP3430_LASTMEM1STATEENTERED_MASK; 1029 break; 1030 case 1: 1031 m = OMAP3430_LASTMEM2STATEENTERED_MASK; 1032 break; 1033 case 2: 1034 m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK; 1035 break; 1036 case 3: 1037 m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK; 1038 break; 1039 default: 1040 WARN_ON(1); /* should never happen */ 1041 return -EEXIST; 1042 } 1043 1044 return prm_read_mod_bits_shift(pwrdm->prcm_offs, 1045 OMAP3430_PM_PREPWSTST, m); 1046 } 1047 1048 /** 1049 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm 1050 * @pwrdm: struct powerdomain * to clear 1051 * 1052 * Clear the powerdomain's previous power state register. Clears the 1053 * entire register, including logic and memory bank previous power states. 1054 * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon 1055 * success. 1056 */ 1057 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) 1058 { 1059 if (!pwrdm) 1060 return -EINVAL; 1061 1062 /* 1063 * XXX should get the powerdomain's current state here; 1064 * warn & fail if it is not ON. 1065 */ 1066 1067 pr_debug("powerdomain: clearing previous power state reg for %s\n", 1068 pwrdm->name); 1069 1070 prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); 1071 1072 return 0; 1073 } 1074 1075 /** 1076 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm 1077 * @pwrdm: struct powerdomain * 1078 * 1079 * Enable automatic context save-and-restore upon power state change 1080 * for some devices in a powerdomain. Warning: this only affects a 1081 * subset of devices in a powerdomain; check the TRM closely. Returns 1082 * -EINVAL if the powerdomain pointer is null or if the powerdomain 1083 * does not support automatic save-and-restore, or returns 0 upon 1084 * success. 1085 */ 1086 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) 1087 { 1088 if (!pwrdm) 1089 return -EINVAL; 1090 1091 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) 1092 return -EINVAL; 1093 1094 pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", 1095 pwrdm->name); 1096 1097 prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 1098 pwrdm->prcm_offs, PM_PWSTCTRL); 1099 1100 return 0; 1101 } 1102 1103 /** 1104 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm 1105 * @pwrdm: struct powerdomain * 1106 * 1107 * Disable automatic context save-and-restore upon power state change 1108 * for some devices in a powerdomain. Warning: this only affects a 1109 * subset of devices in a powerdomain; check the TRM closely. Returns 1110 * -EINVAL if the powerdomain pointer is null or if the powerdomain 1111 * does not support automatic save-and-restore, or returns 0 upon 1112 * success. 1113 */ 1114 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) 1115 { 1116 if (!pwrdm) 1117 return -EINVAL; 1118 1119 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) 1120 return -EINVAL; 1121 1122 pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", 1123 pwrdm->name); 1124 1125 prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0, 1126 pwrdm->prcm_offs, PM_PWSTCTRL); 1127 1128 return 0; 1129 } 1130 1131 /** 1132 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR 1133 * @pwrdm: struct powerdomain * 1134 * 1135 * Returns 1 if powerdomain 'pwrdm' supports hardware save-and-restore 1136 * for some devices, or 0 if it does not. 1137 */ 1138 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) 1139 { 1140 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; 1141 } 1142 1143 /** 1144 * pwrdm_wait_transition - wait for powerdomain power transition to finish 1145 * @pwrdm: struct powerdomain * to wait for 1146 * 1147 * If the powerdomain pwrdm is in the process of a state transition, 1148 * spin until it completes the power transition, or until an iteration 1149 * bailout value is reached. Returns -EINVAL if the powerdomain 1150 * pointer is null, -EAGAIN if the bailout value was reached, or 1151 * returns 0 upon success. 1152 */ 1153 int pwrdm_wait_transition(struct powerdomain *pwrdm) 1154 { 1155 u32 c = 0; 1156 1157 if (!pwrdm) 1158 return -EINVAL; 1159 1160 /* 1161 * REVISIT: pwrdm_wait_transition() may be better implemented 1162 * via a callback and a periodic timer check -- how long do we expect 1163 * powerdomain transitions to take? 1164 */ 1165 1166 /* XXX Is this udelay() value meaningful? */ 1167 while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) & 1168 OMAP_INTRANSITION) && 1169 (c++ < PWRDM_TRANSITION_BAILOUT)) 1170 udelay(1); 1171 1172 if (c > PWRDM_TRANSITION_BAILOUT) { 1173 printk(KERN_ERR "powerdomain: waited too long for " 1174 "powerdomain %s to complete transition\n", pwrdm->name); 1175 return -EAGAIN; 1176 } 1177 1178 pr_debug("powerdomain: completed transition in %d loops\n", c); 1179 1180 return 0; 1181 } 1182 1183 int pwrdm_state_switch(struct powerdomain *pwrdm) 1184 { 1185 return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); 1186 } 1187 1188 int pwrdm_clkdm_state_switch(struct clockdomain *clkdm) 1189 { 1190 if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) { 1191 pwrdm_wait_transition(clkdm->pwrdm.ptr); 1192 return pwrdm_state_switch(clkdm->pwrdm.ptr); 1193 } 1194 1195 return -EINVAL; 1196 } 1197 int pwrdm_clk_state_switch(struct clk *clk) 1198 { 1199 if (clk != NULL && clk->clkdm != NULL) 1200 return pwrdm_clkdm_state_switch(clk->clkdm); 1201 return -EINVAL; 1202 } 1203 1204 int pwrdm_pre_transition(void) 1205 { 1206 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); 1207 return 0; 1208 } 1209 1210 int pwrdm_post_transition(void) 1211 { 1212 pwrdm_for_each(_pwrdm_post_transition_cb, NULL); 1213 return 0; 1214 } 1215 1216