1 /* 2 * OMAP powerdomain control 3 * 4 * Copyright (C) 2007-2008 Texas Instruments, Inc. 5 * Copyright (C) 2007-2009 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/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 "cm-regbits-44xx.h" 32 #include "prm.h" 33 #include "prm-regbits-34xx.h" 34 #include "prm-regbits-44xx.h" 35 36 #include <plat/cpu.h> 37 #include <plat/powerdomain.h> 38 #include <plat/clockdomain.h> 39 #include <plat/prcm.h> 40 41 #include "pm.h" 42 43 enum { 44 PWRDM_STATE_NOW = 0, 45 PWRDM_STATE_PREV, 46 }; 47 48 /* Variable holding value of the CPU dependent PWRSTCTRL Register Offset */ 49 static u16 pwrstctrl_reg_offs; 50 51 /* Variable holding value of the CPU dependent PWRSTST Register Offset */ 52 static u16 pwrstst_reg_offs; 53 54 /* OMAP3 and OMAP4 specific register bit initialisations 55 * Notice that the names here are not according to each power 56 * domain but the bit mapping used applies to all of them 57 */ 58 59 /* OMAP3 and OMAP4 Memory Onstate Masks (common across all power domains) */ 60 #define OMAP_MEM0_ONSTATE_MASK OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK 61 #define OMAP_MEM1_ONSTATE_MASK OMAP3430_L1FLATMEMONSTATE_MASK 62 #define OMAP_MEM2_ONSTATE_MASK OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK 63 #define OMAP_MEM3_ONSTATE_MASK OMAP3430_L2FLATMEMONSTATE_MASK 64 #define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK 65 66 /* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */ 67 #define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK 68 #define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE_MASK 69 #define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK 70 #define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE_MASK 71 #define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK 72 73 /* OMAP3 and OMAP4 Memory Status bits */ 74 #define OMAP_MEM0_STATEST_MASK OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK 75 #define OMAP_MEM1_STATEST_MASK OMAP3430_L1FLATMEMSTATEST_MASK 76 #define OMAP_MEM2_STATEST_MASK OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK 77 #define OMAP_MEM3_STATEST_MASK OMAP3430_L2FLATMEMSTATEST_MASK 78 #define OMAP_MEM4_STATEST_MASK OMAP4430_OCP_NRET_BANK_STATEST_MASK 79 80 /* pwrdm_list contains all registered struct powerdomains */ 81 static LIST_HEAD(pwrdm_list); 82 83 /* Private functions */ 84 85 static struct powerdomain *_pwrdm_lookup(const char *name) 86 { 87 struct powerdomain *pwrdm, *temp_pwrdm; 88 89 pwrdm = NULL; 90 91 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { 92 if (!strcmp(name, temp_pwrdm->name)) { 93 pwrdm = temp_pwrdm; 94 break; 95 } 96 } 97 98 return pwrdm; 99 } 100 101 /** 102 * _pwrdm_register - register a powerdomain 103 * @pwrdm: struct powerdomain * to register 104 * 105 * Adds a powerdomain to the internal powerdomain list. Returns 106 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is 107 * already registered by the provided name, or 0 upon success. 108 */ 109 static int _pwrdm_register(struct powerdomain *pwrdm) 110 { 111 int i; 112 113 if (!pwrdm) 114 return -EINVAL; 115 116 if (!omap_chip_is(pwrdm->omap_chip)) 117 return -EINVAL; 118 119 if (_pwrdm_lookup(pwrdm->name)) 120 return -EEXIST; 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 pwrdm_wait_transition(pwrdm); 133 pwrdm->state = pwrdm_read_pwrst(pwrdm); 134 pwrdm->state_counter[pwrdm->state] = 1; 135 136 pr_debug("powerdomain: registered %s\n", pwrdm->name); 137 138 return 0; 139 } 140 141 static void _update_logic_membank_counters(struct powerdomain *pwrdm) 142 { 143 int i; 144 u8 prev_logic_pwrst, prev_mem_pwrst; 145 146 prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm); 147 if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) && 148 (prev_logic_pwrst == PWRDM_POWER_OFF)) 149 pwrdm->ret_logic_off_counter++; 150 151 for (i = 0; i < pwrdm->banks; i++) { 152 prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i); 153 154 if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) && 155 (prev_mem_pwrst == PWRDM_POWER_OFF)) 156 pwrdm->ret_mem_off_counter[i]++; 157 } 158 } 159 160 static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) 161 { 162 163 int prev; 164 int state; 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 break; 182 default: 183 return -EINVAL; 184 } 185 186 if (state != prev) 187 pwrdm->state_counter[state]++; 188 189 pm_dbg_update_time(pwrdm, prev); 190 191 pwrdm->state = state; 192 193 return 0; 194 } 195 196 static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused) 197 { 198 pwrdm_clear_all_prev_pwrst(pwrdm); 199 _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); 200 return 0; 201 } 202 203 static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) 204 { 205 _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV); 206 return 0; 207 } 208 209 /* Public functions */ 210 211 /** 212 * pwrdm_init - set up the powerdomain layer 213 * @pwrdm_list: array of struct powerdomain pointers to register 214 * 215 * Loop through the array of powerdomains @pwrdm_list, registering all 216 * that are available on the current CPU. If pwrdm_list is supplied 217 * and not null, all of the referenced powerdomains will be 218 * registered. No return value. XXX pwrdm_list is not really a 219 * "list"; it is an array. Rename appropriately. 220 */ 221 void pwrdm_init(struct powerdomain **pwrdm_list) 222 { 223 struct powerdomain **p = NULL; 224 225 if (cpu_is_omap24xx() || cpu_is_omap34xx()) { 226 pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL; 227 pwrstst_reg_offs = OMAP2_PM_PWSTST; 228 } else if (cpu_is_omap44xx()) { 229 pwrstctrl_reg_offs = OMAP4_PM_PWSTCTRL; 230 pwrstst_reg_offs = OMAP4_PM_PWSTST; 231 } else { 232 printk(KERN_ERR "Power Domain struct not supported for " \ 233 "this CPU\n"); 234 return; 235 } 236 237 if (pwrdm_list) { 238 for (p = pwrdm_list; *p; p++) 239 _pwrdm_register(*p); 240 } 241 } 242 243 /** 244 * pwrdm_lookup - look up a powerdomain by name, return a pointer 245 * @name: name of powerdomain 246 * 247 * Find a registered powerdomain by its name @name. Returns a pointer 248 * to the struct powerdomain if found, or NULL otherwise. 249 */ 250 struct powerdomain *pwrdm_lookup(const char *name) 251 { 252 struct powerdomain *pwrdm; 253 254 if (!name) 255 return NULL; 256 257 pwrdm = _pwrdm_lookup(name); 258 259 return pwrdm; 260 } 261 262 /** 263 * pwrdm_for_each - call function on each registered clockdomain 264 * @fn: callback function * 265 * 266 * Call the supplied function @fn for each registered powerdomain. 267 * The callback function @fn can return anything but 0 to bail out 268 * early from the iterator. Returns the last return value of the 269 * callback function, which should be 0 for success or anything else 270 * to indicate failure; or -EINVAL if the function pointer is null. 271 */ 272 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), 273 void *user) 274 { 275 struct powerdomain *temp_pwrdm; 276 int ret = 0; 277 278 if (!fn) 279 return -EINVAL; 280 281 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { 282 ret = (*fn)(temp_pwrdm, user); 283 if (ret) 284 break; 285 } 286 287 return ret; 288 } 289 290 /** 291 * pwrdm_add_clkdm - add a clockdomain to a powerdomain 292 * @pwrdm: struct powerdomain * to add the clockdomain to 293 * @clkdm: struct clockdomain * to associate with a powerdomain 294 * 295 * Associate the clockdomain @clkdm with a powerdomain @pwrdm. This 296 * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if 297 * presented with invalid pointers; -ENOMEM if memory could not be allocated; 298 * or 0 upon success. 299 */ 300 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) 301 { 302 int i; 303 int ret = -EINVAL; 304 305 if (!pwrdm || !clkdm) 306 return -EINVAL; 307 308 pr_debug("powerdomain: associating clockdomain %s with powerdomain " 309 "%s\n", clkdm->name, pwrdm->name); 310 311 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) { 312 if (!pwrdm->pwrdm_clkdms[i]) 313 break; 314 #ifdef DEBUG 315 if (pwrdm->pwrdm_clkdms[i] == clkdm) { 316 ret = -EINVAL; 317 goto pac_exit; 318 } 319 #endif 320 } 321 322 if (i == PWRDM_MAX_CLKDMS) { 323 pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for " 324 "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name); 325 WARN_ON(1); 326 ret = -ENOMEM; 327 goto pac_exit; 328 } 329 330 pwrdm->pwrdm_clkdms[i] = clkdm; 331 332 ret = 0; 333 334 pac_exit: 335 return ret; 336 } 337 338 /** 339 * pwrdm_del_clkdm - remove a clockdomain from a powerdomain 340 * @pwrdm: struct powerdomain * to add the clockdomain to 341 * @clkdm: struct clockdomain * to associate with a powerdomain 342 * 343 * Dissociate the clockdomain @clkdm from the powerdomain 344 * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT 345 * if @clkdm was not associated with the powerdomain, or 0 upon 346 * success. 347 */ 348 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) 349 { 350 int ret = -EINVAL; 351 int i; 352 353 if (!pwrdm || !clkdm) 354 return -EINVAL; 355 356 pr_debug("powerdomain: dissociating clockdomain %s from powerdomain " 357 "%s\n", clkdm->name, pwrdm->name); 358 359 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) 360 if (pwrdm->pwrdm_clkdms[i] == clkdm) 361 break; 362 363 if (i == PWRDM_MAX_CLKDMS) { 364 pr_debug("powerdomain: clkdm %s not associated with pwrdm " 365 "%s ?!\n", clkdm->name, pwrdm->name); 366 ret = -ENOENT; 367 goto pdc_exit; 368 } 369 370 pwrdm->pwrdm_clkdms[i] = NULL; 371 372 ret = 0; 373 374 pdc_exit: 375 return ret; 376 } 377 378 /** 379 * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm 380 * @pwrdm: struct powerdomain * to iterate over 381 * @fn: callback function * 382 * 383 * Call the supplied function @fn for each clockdomain in the powerdomain 384 * @pwrdm. The callback function can return anything but 0 to bail 385 * out early from the iterator. Returns -EINVAL if presented with 386 * invalid pointers; or passes along the last return value of the 387 * callback function, which should be 0 for success or anything else 388 * to indicate failure. 389 */ 390 int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, 391 int (*fn)(struct powerdomain *pwrdm, 392 struct clockdomain *clkdm)) 393 { 394 int ret = 0; 395 int i; 396 397 if (!fn) 398 return -EINVAL; 399 400 for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++) 401 ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]); 402 403 return ret; 404 } 405 406 /** 407 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain 408 * @pwrdm: struct powerdomain * 409 * 410 * Return the number of controllable memory banks in powerdomain @pwrdm, 411 * starting with 1. Returns -EINVAL if the powerdomain pointer is null. 412 */ 413 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm) 414 { 415 if (!pwrdm) 416 return -EINVAL; 417 418 return pwrdm->banks; 419 } 420 421 /** 422 * pwrdm_set_next_pwrst - set next powerdomain power state 423 * @pwrdm: struct powerdomain * to set 424 * @pwrst: one of the PWRDM_POWER_* macros 425 * 426 * Set the powerdomain @pwrdm's next power state to @pwrst. The powerdomain 427 * may not enter this state immediately if the preconditions for this state 428 * have not been satisfied. Returns -EINVAL if the powerdomain pointer is 429 * null or if the power state is invalid for the powerdomin, or returns 0 430 * upon success. 431 */ 432 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) 433 { 434 if (!pwrdm) 435 return -EINVAL; 436 437 if (!(pwrdm->pwrsts & (1 << pwrst))) 438 return -EINVAL; 439 440 pr_debug("powerdomain: setting next powerstate for %s to %0x\n", 441 pwrdm->name, pwrst); 442 443 prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, 444 (pwrst << OMAP_POWERSTATE_SHIFT), 445 pwrdm->prcm_offs, pwrstctrl_reg_offs); 446 447 return 0; 448 } 449 450 /** 451 * pwrdm_read_next_pwrst - get next powerdomain power state 452 * @pwrdm: struct powerdomain * to get power state 453 * 454 * Return the powerdomain @pwrdm's next power state. Returns -EINVAL 455 * if the powerdomain pointer is null or returns the next power state 456 * upon success. 457 */ 458 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm) 459 { 460 if (!pwrdm) 461 return -EINVAL; 462 463 return prm_read_mod_bits_shift(pwrdm->prcm_offs, 464 pwrstctrl_reg_offs, OMAP_POWERSTATE_MASK); 465 } 466 467 /** 468 * pwrdm_read_pwrst - get current powerdomain power state 469 * @pwrdm: struct powerdomain * to get power state 470 * 471 * Return the powerdomain @pwrdm's current power state. Returns -EINVAL 472 * if the powerdomain pointer is null or returns the current power state 473 * upon success. 474 */ 475 int pwrdm_read_pwrst(struct powerdomain *pwrdm) 476 { 477 if (!pwrdm) 478 return -EINVAL; 479 480 return prm_read_mod_bits_shift(pwrdm->prcm_offs, 481 pwrstst_reg_offs, OMAP_POWERSTATEST_MASK); 482 } 483 484 /** 485 * pwrdm_read_prev_pwrst - get previous powerdomain power state 486 * @pwrdm: struct powerdomain * to get previous power state 487 * 488 * Return the powerdomain @pwrdm's previous power state. Returns -EINVAL 489 * if the powerdomain pointer is null or returns the previous power state 490 * upon success. 491 */ 492 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) 493 { 494 if (!pwrdm) 495 return -EINVAL; 496 497 return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, 498 OMAP3430_LASTPOWERSTATEENTERED_MASK); 499 } 500 501 /** 502 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention 503 * @pwrdm: struct powerdomain * to set 504 * @pwrst: one of the PWRDM_POWER_* macros 505 * 506 * Set the next power state @pwrst that the logic portion of the 507 * powerdomain @pwrdm will enter when the powerdomain enters retention. 508 * This will be either RETENTION or OFF, if supported. Returns 509 * -EINVAL if the powerdomain pointer is null or the target power 510 * state is not not supported, or returns 0 upon success. 511 */ 512 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) 513 { 514 u32 v; 515 516 if (!pwrdm) 517 return -EINVAL; 518 519 if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst))) 520 return -EINVAL; 521 522 pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n", 523 pwrdm->name, pwrst); 524 525 /* 526 * The register bit names below may not correspond to the 527 * actual names of the bits in each powerdomain's register, 528 * but the type of value returned is the same for each 529 * powerdomain. 530 */ 531 v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK); 532 prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v, 533 pwrdm->prcm_offs, pwrstctrl_reg_offs); 534 535 return 0; 536 } 537 538 /** 539 * pwrdm_set_mem_onst - set memory power state while powerdomain ON 540 * @pwrdm: struct powerdomain * to set 541 * @bank: memory bank number to set (0-3) 542 * @pwrst: one of the PWRDM_POWER_* macros 543 * 544 * Set the next power state @pwrst that memory bank @bank of the 545 * powerdomain @pwrdm will enter when the powerdomain enters the ON 546 * state. @bank will be a number from 0 to 3, and represents different 547 * types of memory, depending on the powerdomain. Returns -EINVAL if 548 * the powerdomain pointer is null or the target power state is not 549 * not supported for this memory bank, -EEXIST if the target memory 550 * bank does not exist or is not controllable, or returns 0 upon 551 * success. 552 */ 553 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) 554 { 555 u32 m; 556 557 if (!pwrdm) 558 return -EINVAL; 559 560 if (pwrdm->banks < (bank + 1)) 561 return -EEXIST; 562 563 if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst))) 564 return -EINVAL; 565 566 pr_debug("powerdomain: setting next memory powerstate for domain %s " 567 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst); 568 569 /* 570 * The register bit names below may not correspond to the 571 * actual names of the bits in each powerdomain's register, 572 * but the type of value returned is the same for each 573 * powerdomain. 574 */ 575 switch (bank) { 576 case 0: 577 m = OMAP_MEM0_ONSTATE_MASK; 578 break; 579 case 1: 580 m = OMAP_MEM1_ONSTATE_MASK; 581 break; 582 case 2: 583 m = OMAP_MEM2_ONSTATE_MASK; 584 break; 585 case 3: 586 m = OMAP_MEM3_ONSTATE_MASK; 587 break; 588 case 4: 589 m = OMAP_MEM4_ONSTATE_MASK; 590 break; 591 default: 592 WARN_ON(1); /* should never happen */ 593 return -EEXIST; 594 } 595 596 prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), 597 pwrdm->prcm_offs, pwrstctrl_reg_offs); 598 599 return 0; 600 } 601 602 /** 603 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET 604 * @pwrdm: struct powerdomain * to set 605 * @bank: memory bank number to set (0-3) 606 * @pwrst: one of the PWRDM_POWER_* macros 607 * 608 * Set the next power state @pwrst that memory bank @bank of the 609 * powerdomain @pwrdm will enter when the powerdomain enters the 610 * RETENTION state. Bank will be a number from 0 to 3, and represents 611 * different types of memory, depending on the powerdomain. @pwrst 612 * will be either RETENTION or OFF, if supported. Returns -EINVAL if 613 * the powerdomain pointer is null or the target power state is not 614 * not supported for this memory bank, -EEXIST if the target memory 615 * bank does not exist or is not controllable, or returns 0 upon 616 * success. 617 */ 618 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) 619 { 620 u32 m; 621 622 if (!pwrdm) 623 return -EINVAL; 624 625 if (pwrdm->banks < (bank + 1)) 626 return -EEXIST; 627 628 if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst))) 629 return -EINVAL; 630 631 pr_debug("powerdomain: setting next memory powerstate for domain %s " 632 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst); 633 634 /* 635 * The register bit names below may not correspond to the 636 * actual names of the bits in each powerdomain's register, 637 * but the type of value returned is the same for each 638 * powerdomain. 639 */ 640 switch (bank) { 641 case 0: 642 m = OMAP_MEM0_RETSTATE_MASK; 643 break; 644 case 1: 645 m = OMAP_MEM1_RETSTATE_MASK; 646 break; 647 case 2: 648 m = OMAP_MEM2_RETSTATE_MASK; 649 break; 650 case 3: 651 m = OMAP_MEM3_RETSTATE_MASK; 652 break; 653 case 4: 654 m = OMAP_MEM4_RETSTATE_MASK; 655 break; 656 default: 657 WARN_ON(1); /* should never happen */ 658 return -EEXIST; 659 } 660 661 prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, 662 pwrstctrl_reg_offs); 663 664 return 0; 665 } 666 667 /** 668 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state 669 * @pwrdm: struct powerdomain * to get current logic retention power state 670 * 671 * Return the power state that the logic portion of powerdomain @pwrdm 672 * will enter when the powerdomain enters retention. Returns -EINVAL 673 * if the powerdomain pointer is null or returns the logic retention 674 * power state upon success. 675 */ 676 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) 677 { 678 if (!pwrdm) 679 return -EINVAL; 680 681 return prm_read_mod_bits_shift(pwrdm->prcm_offs, pwrstst_reg_offs, 682 OMAP3430_LOGICSTATEST_MASK); 683 } 684 685 /** 686 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state 687 * @pwrdm: struct powerdomain * to get previous logic power state 688 * 689 * Return the powerdomain @pwrdm's previous logic power state. Returns 690 * -EINVAL if the powerdomain pointer is null or returns the previous 691 * logic power state upon success. 692 */ 693 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) 694 { 695 if (!pwrdm) 696 return -EINVAL; 697 698 /* 699 * The register bit names below may not correspond to the 700 * actual names of the bits in each powerdomain's register, 701 * but the type of value returned is the same for each 702 * powerdomain. 703 */ 704 return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, 705 OMAP3430_LASTLOGICSTATEENTERED_MASK); 706 } 707 708 /** 709 * pwrdm_read_logic_retst - get next powerdomain logic power state 710 * @pwrdm: struct powerdomain * to get next logic power state 711 * 712 * Return the powerdomain pwrdm's logic power state. Returns -EINVAL 713 * if the powerdomain pointer is null or returns the next logic 714 * power state upon success. 715 */ 716 int pwrdm_read_logic_retst(struct powerdomain *pwrdm) 717 { 718 if (!pwrdm) 719 return -EINVAL; 720 721 /* 722 * The register bit names below may not correspond to the 723 * actual names of the bits in each powerdomain's register, 724 * but the type of value returned is the same for each 725 * powerdomain. 726 */ 727 return prm_read_mod_bits_shift(pwrdm->prcm_offs, pwrstctrl_reg_offs, 728 OMAP3430_LOGICSTATEST_MASK); 729 } 730 731 /** 732 * pwrdm_read_mem_pwrst - get current memory bank power state 733 * @pwrdm: struct powerdomain * to get current memory bank power state 734 * @bank: memory bank number (0-3) 735 * 736 * Return the powerdomain @pwrdm's current memory power state for bank 737 * @bank. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if 738 * the target memory bank does not exist or is not controllable, or 739 * returns the current memory power state upon success. 740 */ 741 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 742 { 743 u32 m; 744 745 if (!pwrdm) 746 return -EINVAL; 747 748 if (pwrdm->banks < (bank + 1)) 749 return -EEXIST; 750 751 if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) 752 bank = 1; 753 754 /* 755 * The register bit names below may not correspond to the 756 * actual names of the bits in each powerdomain's register, 757 * but the type of value returned is the same for each 758 * powerdomain. 759 */ 760 switch (bank) { 761 case 0: 762 m = OMAP_MEM0_STATEST_MASK; 763 break; 764 case 1: 765 m = OMAP_MEM1_STATEST_MASK; 766 break; 767 case 2: 768 m = OMAP_MEM2_STATEST_MASK; 769 break; 770 case 3: 771 m = OMAP_MEM3_STATEST_MASK; 772 break; 773 case 4: 774 m = OMAP_MEM4_STATEST_MASK; 775 break; 776 default: 777 WARN_ON(1); /* should never happen */ 778 return -EEXIST; 779 } 780 781 return prm_read_mod_bits_shift(pwrdm->prcm_offs, 782 pwrstst_reg_offs, m); 783 } 784 785 /** 786 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state 787 * @pwrdm: struct powerdomain * to get previous memory bank power state 788 * @bank: memory bank number (0-3) 789 * 790 * Return the powerdomain @pwrdm's previous memory power state for 791 * bank @bank. Returns -EINVAL if the powerdomain pointer is null, 792 * -EEXIST if the target memory bank does not exist or is not 793 * controllable, or returns the previous memory power state upon 794 * success. 795 */ 796 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 797 { 798 u32 m; 799 800 if (!pwrdm) 801 return -EINVAL; 802 803 if (pwrdm->banks < (bank + 1)) 804 return -EEXIST; 805 806 if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) 807 bank = 1; 808 809 /* 810 * The register bit names below may not correspond to the 811 * actual names of the bits in each powerdomain's register, 812 * but the type of value returned is the same for each 813 * powerdomain. 814 */ 815 switch (bank) { 816 case 0: 817 m = OMAP3430_LASTMEM1STATEENTERED_MASK; 818 break; 819 case 1: 820 m = OMAP3430_LASTMEM2STATEENTERED_MASK; 821 break; 822 case 2: 823 m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK; 824 break; 825 case 3: 826 m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK; 827 break; 828 default: 829 WARN_ON(1); /* should never happen */ 830 return -EEXIST; 831 } 832 833 return prm_read_mod_bits_shift(pwrdm->prcm_offs, 834 OMAP3430_PM_PREPWSTST, m); 835 } 836 837 /** 838 * pwrdm_read_mem_retst - get next memory bank power state 839 * @pwrdm: struct powerdomain * to get mext memory bank power state 840 * @bank: memory bank number (0-3) 841 * 842 * Return the powerdomain pwrdm's next memory power state for bank 843 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if 844 * the target memory bank does not exist or is not controllable, or 845 * returns the next memory power state upon success. 846 */ 847 int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) 848 { 849 u32 m; 850 851 if (!pwrdm) 852 return -EINVAL; 853 854 if (pwrdm->banks < (bank + 1)) 855 return -EEXIST; 856 857 /* 858 * The register bit names below may not correspond to the 859 * actual names of the bits in each powerdomain's register, 860 * but the type of value returned is the same for each 861 * powerdomain. 862 */ 863 switch (bank) { 864 case 0: 865 m = OMAP_MEM0_RETSTATE_MASK; 866 break; 867 case 1: 868 m = OMAP_MEM1_RETSTATE_MASK; 869 break; 870 case 2: 871 m = OMAP_MEM2_RETSTATE_MASK; 872 break; 873 case 3: 874 m = OMAP_MEM3_RETSTATE_MASK; 875 break; 876 case 4: 877 m = OMAP_MEM4_RETSTATE_MASK; 878 break; 879 default: 880 WARN_ON(1); /* should never happen */ 881 return -EEXIST; 882 } 883 884 return prm_read_mod_bits_shift(pwrdm->prcm_offs, 885 pwrstctrl_reg_offs, m); 886 } 887 888 /** 889 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm 890 * @pwrdm: struct powerdomain * to clear 891 * 892 * Clear the powerdomain's previous power state register @pwrdm. 893 * Clears the entire register, including logic and memory bank 894 * previous power states. Returns -EINVAL if the powerdomain pointer 895 * is null, or returns 0 upon success. 896 */ 897 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) 898 { 899 if (!pwrdm) 900 return -EINVAL; 901 902 /* 903 * XXX should get the powerdomain's current state here; 904 * warn & fail if it is not ON. 905 */ 906 907 pr_debug("powerdomain: clearing previous power state reg for %s\n", 908 pwrdm->name); 909 910 prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); 911 912 return 0; 913 } 914 915 /** 916 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm 917 * @pwrdm: struct powerdomain * 918 * 919 * Enable automatic context save-and-restore upon power state change 920 * for some devices in the powerdomain @pwrdm. Warning: this only 921 * affects a subset of devices in a powerdomain; check the TRM 922 * closely. Returns -EINVAL if the powerdomain pointer is null or if 923 * the powerdomain does not support automatic save-and-restore, or 924 * returns 0 upon success. 925 */ 926 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) 927 { 928 if (!pwrdm) 929 return -EINVAL; 930 931 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) 932 return -EINVAL; 933 934 pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", 935 pwrdm->name); 936 937 prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 938 pwrdm->prcm_offs, pwrstctrl_reg_offs); 939 940 return 0; 941 } 942 943 /** 944 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm 945 * @pwrdm: struct powerdomain * 946 * 947 * Disable automatic context save-and-restore upon power state change 948 * for some devices in the powerdomain @pwrdm. Warning: this only 949 * affects a subset of devices in a powerdomain; check the TRM 950 * closely. Returns -EINVAL if the powerdomain pointer is null or if 951 * the powerdomain does not support automatic save-and-restore, or 952 * returns 0 upon success. 953 */ 954 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) 955 { 956 if (!pwrdm) 957 return -EINVAL; 958 959 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) 960 return -EINVAL; 961 962 pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", 963 pwrdm->name); 964 965 prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0, 966 pwrdm->prcm_offs, pwrstctrl_reg_offs); 967 968 return 0; 969 } 970 971 /** 972 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR 973 * @pwrdm: struct powerdomain * 974 * 975 * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore 976 * for some devices, or 0 if it does not. 977 */ 978 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) 979 { 980 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; 981 } 982 983 /** 984 * pwrdm_set_lowpwrstchange - Request a low power state change 985 * @pwrdm: struct powerdomain * 986 * 987 * Allows a powerdomain to transtion to a lower power sleep state 988 * from an existing sleep state without waking up the powerdomain. 989 * Returns -EINVAL if the powerdomain pointer is null or if the 990 * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0 991 * upon success. 992 */ 993 int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) 994 { 995 if (!pwrdm) 996 return -EINVAL; 997 998 if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) 999 return -EINVAL; 1000 1001 pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n", 1002 pwrdm->name); 1003 1004 prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK, 1005 (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT), 1006 pwrdm->prcm_offs, pwrstctrl_reg_offs); 1007 1008 return 0; 1009 } 1010 1011 /** 1012 * pwrdm_wait_transition - wait for powerdomain power transition to finish 1013 * @pwrdm: struct powerdomain * to wait for 1014 * 1015 * If the powerdomain @pwrdm is in the process of a state transition, 1016 * spin until it completes the power transition, or until an iteration 1017 * bailout value is reached. Returns -EINVAL if the powerdomain 1018 * pointer is null, -EAGAIN if the bailout value was reached, or 1019 * returns 0 upon success. 1020 */ 1021 int pwrdm_wait_transition(struct powerdomain *pwrdm) 1022 { 1023 u32 c = 0; 1024 1025 if (!pwrdm) 1026 return -EINVAL; 1027 1028 /* 1029 * REVISIT: pwrdm_wait_transition() may be better implemented 1030 * via a callback and a periodic timer check -- how long do we expect 1031 * powerdomain transitions to take? 1032 */ 1033 1034 /* XXX Is this udelay() value meaningful? */ 1035 while ((prm_read_mod_reg(pwrdm->prcm_offs, pwrstst_reg_offs) & 1036 OMAP_INTRANSITION_MASK) && 1037 (c++ < PWRDM_TRANSITION_BAILOUT)) 1038 udelay(1); 1039 1040 if (c > PWRDM_TRANSITION_BAILOUT) { 1041 printk(KERN_ERR "powerdomain: waited too long for " 1042 "powerdomain %s to complete transition\n", pwrdm->name); 1043 return -EAGAIN; 1044 } 1045 1046 pr_debug("powerdomain: completed transition in %d loops\n", c); 1047 1048 return 0; 1049 } 1050 1051 int pwrdm_state_switch(struct powerdomain *pwrdm) 1052 { 1053 return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); 1054 } 1055 1056 int pwrdm_clkdm_state_switch(struct clockdomain *clkdm) 1057 { 1058 if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) { 1059 pwrdm_wait_transition(clkdm->pwrdm.ptr); 1060 return pwrdm_state_switch(clkdm->pwrdm.ptr); 1061 } 1062 1063 return -EINVAL; 1064 } 1065 1066 int pwrdm_pre_transition(void) 1067 { 1068 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); 1069 return 0; 1070 } 1071 1072 int pwrdm_post_transition(void) 1073 { 1074 pwrdm_for_each(_pwrdm_post_transition_cb, NULL); 1075 return 0; 1076 } 1077 1078