aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2010-01-26 22:12:59 -0500
committerPaul Walmsley <paul@pwsan.com>2010-01-26 22:12:59 -0500
commit55ed96945b1f3d0f4ad21a27b32ce4bd99d8c268 (patch)
tree0bec60498742922a9c00f39ff63eb48549d391fc /arch/arm/mach-omap2
parent6b04e0d99d4113ede24e263e3df246a17f490339 (diff)
OMAP2/3 clkdm/pwrdm: move wkdep/sleepdep handling from pwrdm to clkdm
Move clockdomain wakeup dependency and sleep dependency data structures from the powerdomain layer to the clockdomain layer, where they belong. These dependencies were originally placed in the powerdomain layer due to unclear documentation; however, it is clear now that these dependencies are between clockdomains. For OMAP2/3, this is not such a big problem, but for OMAP4 this needs to be fixed. Thanks to Benoît Cousson <b-cousson@ti.com> for his advice on this patch. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Benoît Cousson <b-cousson@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/clockdomain.c368
-rw-r--r--arch/arm/mach-omap2/clockdomains.h378
-rw-r--r--arch/arm/mach-omap2/io.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c10
-rw-r--r--arch/arm/mach-omap2/pm34xx.c10
-rw-r--r--arch/arm/mach-omap2/powerdomain.c259
-rw-r--r--arch/arm/mach-omap2/powerdomains.h88
-rw-r--r--arch/arm/mach-omap2/powerdomains24xx.h87
-rw-r--r--arch/arm/mach-omap2/powerdomains34xx.h145
-rw-r--r--arch/arm/mach-omap2/prcm.c12
10 files changed, 711 insertions, 648 deletions
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 8c9e78c2c17f..a70ba29f66cc 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -27,14 +27,14 @@
27 27
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29 29
30#include <plat/clock.h>
31
32#include "prm.h" 30#include "prm.h"
33#include "prm-regbits-24xx.h" 31#include "prm-regbits-24xx.h"
34#include "cm.h" 32#include "cm.h"
35 33
34#include <plat/clock.h>
36#include <plat/powerdomain.h> 35#include <plat/powerdomain.h>
37#include <plat/clockdomain.h> 36#include <plat/clockdomain.h>
37#include <plat/prcm.h>
38 38
39/* clkdm_list contains all registered struct clockdomains */ 39/* clkdm_list contains all registered struct clockdomains */
40static LIST_HEAD(clkdm_list); 40static LIST_HEAD(clkdm_list);
@@ -42,28 +42,75 @@ static LIST_HEAD(clkdm_list);
42/* clkdm_mutex protects clkdm_list add and del ops */ 42/* clkdm_mutex protects clkdm_list add and del ops */
43static DEFINE_MUTEX(clkdm_mutex); 43static DEFINE_MUTEX(clkdm_mutex);
44 44
45/* array of powerdomain deps to be added/removed when clkdm in hwsup mode */ 45/* array of clockdomain deps to be added/removed when clkdm in hwsup mode */
46static struct clkdm_pwrdm_autodep *autodeps; 46static struct clkdm_autodep *autodeps;
47 47
48 48
49/* Private functions */ 49/* Private functions */
50 50
51static struct clockdomain *_clkdm_lookup(const char *name)
52{
53 struct clockdomain *clkdm, *temp_clkdm;
54
55 if (!name)
56 return NULL;
57
58 clkdm = NULL;
59
60 list_for_each_entry(temp_clkdm, &clkdm_list, node) {
61 if (!strcmp(name, temp_clkdm->name)) {
62 clkdm = temp_clkdm;
63 break;
64 }
65 }
66
67 return clkdm;
68}
69
70/* _clkdm_deps_lookup - look up the specified clockdomain in a clkdm list */
71static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,
72 struct clkdm_dep *deps)
73{
74 struct clkdm_dep *cd;
75
76 if (!clkdm || !deps || !omap_chip_is(clkdm->omap_chip))
77 return ERR_PTR(-EINVAL);
78
79 for (cd = deps; cd->clkdm_name; cd++) {
80
81 if (!omap_chip_is(cd->omap_chip))
82 continue;
83
84 if (!cd->clkdm && cd->clkdm_name)
85 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
86
87 if (cd->clkdm == clkdm)
88 break;
89
90 }
91
92 if (!cd->clkdm_name)
93 return ERR_PTR(-ENOENT);
94
95 return cd;
96}
97
51/* 98/*
52 * _autodep_lookup - resolve autodep pwrdm names to pwrdm pointers; store 99 * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store
53 * @autodep: struct clkdm_pwrdm_autodep * to resolve 100 * @autodep: struct clkdm_autodep * to resolve
54 * 101 *
55 * Resolve autodep powerdomain names to powerdomain pointers via 102 * Resolve autodep clockdomain names to clockdomain pointers via
56 * pwrdm_lookup() and store the pointers in the autodep structure. An 103 * clkdm_lookup() and store the pointers in the autodep structure. An
57 * "autodep" is a powerdomain sleep/wakeup dependency that is 104 * "autodep" is a clockdomain sleep/wakeup dependency that is
58 * automatically added and removed whenever clocks in the associated 105 * automatically added and removed whenever clocks in the associated
59 * clockdomain are enabled or disabled (respectively) when the 106 * clockdomain are enabled or disabled (respectively) when the
60 * clockdomain is in hardware-supervised mode. Meant to be called 107 * clockdomain is in hardware-supervised mode. Meant to be called
61 * once at clockdomain layer initialization, since these should remain 108 * once at clockdomain layer initialization, since these should remain
62 * fixed for a particular architecture. No return value. 109 * fixed for a particular architecture. No return value.
63 */ 110 */
64static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep) 111static void _autodep_lookup(struct clkdm_autodep *autodep)
65{ 112{
66 struct powerdomain *pwrdm; 113 struct clockdomain *clkdm;
67 114
68 if (!autodep) 115 if (!autodep)
69 return; 116 return;
@@ -71,13 +118,13 @@ static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep)
71 if (!omap_chip_is(autodep->omap_chip)) 118 if (!omap_chip_is(autodep->omap_chip))
72 return; 119 return;
73 120
74 pwrdm = pwrdm_lookup(autodep->pwrdm.name); 121 clkdm = clkdm_lookup(autodep->clkdm.name);
75 if (!pwrdm) { 122 if (!clkdm) {
76 pr_err("clockdomain: autodeps: powerdomain %s does not exist\n", 123 pr_err("clockdomain: autodeps: clockdomain %s does not exist\n",
77 autodep->pwrdm.name); 124 autodep->clkdm.name);
78 pwrdm = ERR_PTR(-ENOENT); 125 clkdm = ERR_PTR(-ENOENT);
79 } 126 }
80 autodep->pwrdm.ptr = pwrdm; 127 autodep->clkdm.ptr = clkdm;
81} 128}
82 129
83/* 130/*
@@ -90,21 +137,21 @@ static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep)
90 */ 137 */
91static void _clkdm_add_autodeps(struct clockdomain *clkdm) 138static void _clkdm_add_autodeps(struct clockdomain *clkdm)
92{ 139{
93 struct clkdm_pwrdm_autodep *autodep; 140 struct clkdm_autodep *autodep;
94 141
95 for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) { 142 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
96 if (IS_ERR(autodep->pwrdm.ptr)) 143 if (IS_ERR(autodep->clkdm.ptr))
97 continue; 144 continue;
98 145
99 if (!omap_chip_is(autodep->omap_chip)) 146 if (!omap_chip_is(autodep->omap_chip))
100 continue; 147 continue;
101 148
102 pr_debug("clockdomain: adding %s sleepdep/wkdep for " 149 pr_debug("clockdomain: adding %s sleepdep/wkdep for "
103 "pwrdm %s\n", autodep->pwrdm.ptr->name, 150 "clkdm %s\n", autodep->clkdm.ptr->name,
104 clkdm->pwrdm.ptr->name); 151 clkdm->name);
105 152
106 pwrdm_add_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr); 153 clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr);
107 pwrdm_add_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr); 154 clkdm_add_wkdep(clkdm, autodep->clkdm.ptr);
108 } 155 }
109} 156}
110 157
@@ -118,21 +165,21 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm)
118 */ 165 */
119static void _clkdm_del_autodeps(struct clockdomain *clkdm) 166static void _clkdm_del_autodeps(struct clockdomain *clkdm)
120{ 167{
121 struct clkdm_pwrdm_autodep *autodep; 168 struct clkdm_autodep *autodep;
122 169
123 for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) { 170 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
124 if (IS_ERR(autodep->pwrdm.ptr)) 171 if (IS_ERR(autodep->clkdm.ptr))
125 continue; 172 continue;
126 173
127 if (!omap_chip_is(autodep->omap_chip)) 174 if (!omap_chip_is(autodep->omap_chip))
128 continue; 175 continue;
129 176
130 pr_debug("clockdomain: removing %s sleepdep/wkdep for " 177 pr_debug("clockdomain: removing %s sleepdep/wkdep for "
131 "pwrdm %s\n", autodep->pwrdm.ptr->name, 178 "clkdm %s\n", autodep->clkdm.ptr->name,
132 clkdm->pwrdm.ptr->name); 179 clkdm->name);
133 180
134 pwrdm_del_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr); 181 clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr);
135 pwrdm_del_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr); 182 clkdm_del_wkdep(clkdm, autodep->clkdm.ptr);
136 } 183 }
137} 184}
138 185
@@ -171,25 +218,6 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
171 218
172} 219}
173 220
174static struct clockdomain *_clkdm_lookup(const char *name)
175{
176 struct clockdomain *clkdm, *temp_clkdm;
177
178 if (!name)
179 return NULL;
180
181 clkdm = NULL;
182
183 list_for_each_entry(temp_clkdm, &clkdm_list, node) {
184 if (!strcmp(name, temp_clkdm->name)) {
185 clkdm = temp_clkdm;
186 break;
187 }
188 }
189
190 return clkdm;
191}
192
193 221
194/* Public functions */ 222/* Public functions */
195 223
@@ -200,26 +228,24 @@ static struct clockdomain *_clkdm_lookup(const char *name)
200 * 228 *
201 * Set up internal state. If a pointer to an array of clockdomains 229 * Set up internal state. If a pointer to an array of clockdomains
202 * was supplied, loop through the list of clockdomains, register all 230 * was supplied, loop through the list of clockdomains, register all
203 * that are available on the current platform. Similarly, if a 231 * that are available on the current platform. Similarly, if a pointer
204 * pointer to an array of clockdomain-powerdomain autodependencies was 232 * to an array of clockdomain autodependencies was provided, register
205 * provided, register those. No return value. 233 * those. No return value.
206 */ 234 */
207void clkdm_init(struct clockdomain **clkdms, 235void clkdm_init(struct clockdomain **clkdms,
208 struct clkdm_pwrdm_autodep *init_autodeps) 236 struct clkdm_autodep *init_autodeps)
209{ 237{
210 struct clockdomain **c = NULL; 238 struct clockdomain **c = NULL;
211 struct clkdm_pwrdm_autodep *autodep = NULL; 239 struct clkdm_autodep *autodep = NULL;
212 240
213 if (clkdms) 241 if (clkdms)
214 for (c = clkdms; *c; c++) 242 for (c = clkdms; *c; c++)
215 clkdm_register(*c); 243 clkdm_register(*c);
216 244
217 if (!cpu_is_omap44xx()) { 245 autodeps = init_autodeps;
218 autodeps = init_autodeps; 246 if (autodeps)
219 if (autodeps) 247 for (autodep = autodeps; autodep->clkdm.ptr; autodep++)
220 for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) 248 _autodep_lookup(autodep);
221 _autodep_lookup(autodep);
222 }
223} 249}
224 250
225/** 251/**
@@ -374,6 +400,226 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
374/* Hardware clockdomain control */ 400/* Hardware clockdomain control */
375 401
376/** 402/**
403 * clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1
404 * @clkdm1: wake this struct clockdomain * up (dependent)
405 * @clkdm2: when this struct clockdomain * wakes up (source)
406 *
407 * When the clockdomain represented by @clkdm2 wakes up, wake up
408 * @clkdm1. Implemented in hardware on the OMAP, this feature is
409 * designed to reduce wakeup latency of the dependent clockdomain @clkdm1.
410 * Returns -EINVAL if presented with invalid clockdomain pointers,
411 * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon
412 * success.
413 */
414int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
415{
416 struct clkdm_dep *cd;
417
418 if (!clkdm1 || !clkdm2)
419 return -EINVAL;
420
421 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
422 if (IS_ERR(cd)) {
423 pr_debug("clockdomain: hardware cannot set/clear wake up of "
424 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
425 return PTR_ERR(cd);
426 }
427
428 pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n",
429 clkdm1->name, clkdm2->name);
430
431 prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
432 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
433
434 return 0;
435}
436
437/**
438 * clkdm_del_wkdep - remove a wakeup dependency from clkdm2 to clkdm1
439 * @clkdm1: wake this struct clockdomain * up (dependent)
440 * @clkdm2: when this struct clockdomain * wakes up (source)
441 *
442 * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2
443 * wakes up. Returns -EINVAL if presented with invalid clockdomain
444 * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or
445 * 0 upon success.
446 */
447int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
448{
449 struct clkdm_dep *cd;
450
451 if (!clkdm1 || !clkdm2)
452 return -EINVAL;
453
454 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
455 if (IS_ERR(cd)) {
456 pr_debug("clockdomain: hardware cannot set/clear wake up of "
457 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
458 return PTR_ERR(cd);
459 }
460
461 pr_debug("clockdomain: hardware will no longer wake up %s after %s "
462 "wakes up\n", clkdm1->name, clkdm2->name);
463
464 prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
465 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
466
467 return 0;
468}
469
470/**
471 * clkdm_read_wkdep - read wakeup dependency state from clkdm2 to clkdm1
472 * @clkdm1: wake this struct clockdomain * up (dependent)
473 * @clkdm2: when this struct clockdomain * wakes up (source)
474 *
475 * Return 1 if a hardware wakeup dependency exists wherein @clkdm1 will be
476 * awoken when @clkdm2 wakes up; 0 if dependency is not set; -EINVAL
477 * if either clockdomain pointer is invalid; or -ENOENT if the hardware
478 * is incapable.
479 *
480 * REVISIT: Currently this function only represents software-controllable
481 * wakeup dependencies. Wakeup dependencies fixed in hardware are not
482 * yet handled here.
483 */
484int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
485{
486 struct clkdm_dep *cd;
487
488 if (!clkdm1 || !clkdm2)
489 return -EINVAL;
490
491 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
492 if (IS_ERR(cd)) {
493 pr_debug("clockdomain: hardware cannot set/clear wake up of "
494 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
495 return PTR_ERR(cd);
496 }
497
498 return prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP,
499 (1 << clkdm2->dep_bit));
500}
501
502/**
503 * clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1
504 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
505 * @clkdm2: when this struct clockdomain * is active (source)
506 *
507 * Prevent @clkdm1 from automatically going inactive (and then to
508 * retention or off) if @clkdm2 is active. Returns -EINVAL if
509 * presented with invalid clockdomain pointers or called on a machine
510 * that does not support software-configurable hardware sleep
511 * dependencies, -ENOENT if the specified dependency cannot be set in
512 * hardware, or 0 upon success.
513 */
514int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
515{
516 struct clkdm_dep *cd;
517
518 if (!cpu_is_omap34xx())
519 return -EINVAL;
520
521 if (!clkdm1 || !clkdm2)
522 return -EINVAL;
523
524 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
525 if (IS_ERR(cd)) {
526 pr_debug("clockdomain: hardware cannot set/clear sleep "
527 "dependency affecting %s from %s\n", clkdm1->name,
528 clkdm2->name);
529 return PTR_ERR(cd);
530 }
531
532 pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n",
533 clkdm1->name, clkdm2->name);
534
535 cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
536 clkdm1->pwrdm.ptr->prcm_offs,
537 OMAP3430_CM_SLEEPDEP);
538
539 return 0;
540}
541
542/**
543 * clkdm_del_sleepdep - remove a sleep dependency from clkdm2 to clkdm1
544 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
545 * @clkdm2: when this struct clockdomain * is active (source)
546 *
547 * Allow @clkdm1 to automatically go inactive (and then to retention or
548 * off), independent of the activity state of @clkdm2. Returns -EINVAL
549 * if presented with invalid clockdomain pointers or called on a machine
550 * that does not support software-configurable hardware sleep dependencies,
551 * -ENOENT if the specified dependency cannot be cleared in hardware, or
552 * 0 upon success.
553 */
554int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
555{
556 struct clkdm_dep *cd;
557
558 if (!cpu_is_omap34xx())
559 return -EINVAL;
560
561 if (!clkdm1 || !clkdm2)
562 return -EINVAL;
563
564 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
565 if (IS_ERR(cd)) {
566 pr_debug("clockdomain: hardware cannot set/clear sleep "
567 "dependency affecting %s from %s\n", clkdm1->name,
568 clkdm2->name);
569 return PTR_ERR(cd);
570 }
571
572 pr_debug("clockdomain: will no longer prevent %s from sleeping if "
573 "%s is active\n", clkdm1->name, clkdm2->name);
574
575 cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
576 clkdm1->pwrdm.ptr->prcm_offs,
577 OMAP3430_CM_SLEEPDEP);
578
579 return 0;
580}
581
582/**
583 * clkdm_read_sleepdep - read sleep dependency state from clkdm2 to clkdm1
584 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
585 * @clkdm2: when this struct clockdomain * is active (source)
586 *
587 * Return 1 if a hardware sleep dependency exists wherein @clkdm1 will
588 * not be allowed to automatically go inactive if @clkdm2 is active;
589 * 0 if @clkdm1's automatic power state inactivity transition is independent
590 * of @clkdm2's; -EINVAL if either clockdomain pointer is invalid or called
591 * on a machine that does not support software-configurable hardware sleep
592 * dependencies; or -ENOENT if the hardware is incapable.
593 *
594 * REVISIT: Currently this function only represents software-controllable
595 * sleep dependencies. Sleep dependencies fixed in hardware are not
596 * yet handled here.
597 */
598int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
599{
600 struct clkdm_dep *cd;
601
602 if (!cpu_is_omap34xx())
603 return -EINVAL;
604
605 if (!clkdm1 || !clkdm2)
606 return -EINVAL;
607
608 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
609 if (IS_ERR(cd)) {
610 pr_debug("clockdomain: hardware cannot set/clear sleep "
611 "dependency affecting %s from %s\n", clkdm1->name,
612 clkdm2->name);
613 return PTR_ERR(cd);
614 }
615
616 return prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
617 OMAP3430_CM_SLEEPDEP,
618 (1 << clkdm2->dep_bit));
619}
620
621
622/**
377 * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode 623 * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode
378 * @clk: struct clk * of a clockdomain 624 * @clk: struct clk * of a clockdomain
379 * 625 *
diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains.h
index 6dc5ddc9a3a4..ff216f24f1a0 100644
--- a/arch/arm/mach-omap2/clockdomains.h
+++ b/arch/arm/mach-omap2/clockdomains.h
@@ -2,9 +2,28 @@
2 * OMAP2/3 clockdomains 2 * OMAP2/3 clockdomains
3 * 3 *
4 * Copyright (C) 2008 Texas Instruments, Inc. 4 * Copyright (C) 2008 Texas Instruments, Inc.
5 * Copyright (C) 2008 Nokia Corporation 5 * Copyright (C) 2008-2009 Nokia Corporation
6 * 6 *
7 * Written by Paul Walmsley 7 * Written by Paul Walmsley and Jouni Högander
8 *
9 * This file contains clockdomains and clockdomain wakeup/sleep
10 * dependencies for the OMAP2/3 chips. Some notes:
11 *
12 * A useful validation rule for struct clockdomain: Any clockdomain
13 * referenced by a wkdep_srcs or sleepdep_srcs array must have a
14 * dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just
15 * software-controllable dependencies. Non-software-controllable
16 * dependencies do exist, but they are not encoded below (yet).
17 *
18 * 24xx does not support programmable sleep dependencies (SLEEPDEP)
19 *
20 * The overly-specific dep_bit names are due to a bit name collision
21 * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
22 * value are the same for all powerdomains: 2
23 *
24 * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
25 * sanity check?
26 * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
8 */ 27 */
9 28
10/* 29/*
@@ -21,6 +40,287 @@
21#include "prm.h" 40#include "prm.h"
22 41
23/* 42/*
43 * Clockdomain dependencies for wkdeps/sleepdeps
44 *
45 * XXX Hardware dependencies (e.g., dependencies that cannot be
46 * changed in software) are not included here yet, but should be.
47 */
48
49/* OMAP2/3-common wakeup dependencies */
50
51/*
52 * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
53 * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
54 * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
55 */
56static struct clkdm_dep gfx_sgx_wkdeps[] = {
57 {
58 .clkdm_name = "core_l3_clkdm",
59 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
60 },
61 {
62 .clkdm_name = "core_l4_clkdm",
63 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
64 },
65 {
66 .clkdm_name = "iva2_clkdm",
67 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
68 },
69 {
70 .clkdm_name = "mpu_clkdm",
71 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
72 CHIP_IS_OMAP3430)
73 },
74 {
75 .clkdm_name = "wkup_clkdm",
76 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
77 CHIP_IS_OMAP3430)
78 },
79 { NULL },
80};
81
82
83/* 24XX-specific possible dependencies */
84
85#ifdef CONFIG_ARCH_OMAP24XX
86
87/* Wakeup dependency source arrays */
88
89/*
90 * 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP
91 * 2420/2430 PM_WKDEP_MDM: same as DSP
92 */
93static struct clkdm_dep dsp_mdm_24xx_wkdeps[] = {
94 {
95 .clkdm_name = "core_l3_clkdm",
96 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
97 },
98 {
99 .clkdm_name = "core_l4_clkdm",
100 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
101 },
102 {
103 .clkdm_name = "mpu_clkdm",
104 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
105 },
106 {
107 .clkdm_name = "wkup_clkdm",
108 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
109 },
110 { NULL },
111};
112
113/*
114 * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
115 * 2430 adds MDM
116 */
117static struct clkdm_dep mpu_24xx_wkdeps[] = {
118 {
119 .clkdm_name = "core_l3_clkdm",
120 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
121 },
122 {
123 .clkdm_name = "core_l4_clkdm",
124 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
125 },
126 {
127 .clkdm_name = "dsp_clkdm",
128 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
129 },
130 {
131 .clkdm_name = "wkup_clkdm",
132 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
133 },
134 {
135 .clkdm_name = "mdm_clkdm",
136 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
137 },
138 { NULL },
139};
140
141/*
142 * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
143 * 2430 adds MDM
144 */
145static struct clkdm_dep core_24xx_wkdeps[] = {
146 {
147 .clkdm_name = "dsp_clkdm",
148 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
149 },
150 {
151 .clkdm_name = "gfx_clkdm",
152 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
153 },
154 {
155 .clkdm_name = "mpu_clkdm",
156 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
157 },
158 {
159 .clkdm_name = "wkup_clkdm",
160 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
161 },
162 {
163 .clkdm_name = "mdm_clkdm",
164 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
165 },
166 { NULL },
167};
168
169#endif
170
171/* 34XX-specific possible dependencies */
172
173#ifdef CONFIG_ARCH_OMAP34XX
174
175/*
176 * 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP
177 * (USBHOST is ES2 only)
178 */
179static struct clkdm_dep per_usbhost_wkdeps[] = {
180 {
181 .clkdm_name = "core_l3_clkdm",
182 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
183 },
184 {
185 .clkdm_name = "core_l4_clkdm",
186 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
187 },
188 {
189 .clkdm_name = "iva2_clkdm",
190 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
191 },
192 {
193 .clkdm_name = "mpu_clkdm",
194 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
195 },
196 {
197 .clkdm_name = "wkup_clkdm",
198 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
199 },
200 { NULL },
201};
202
203/*
204 * 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER
205 */
206static struct clkdm_dep mpu_34xx_wkdeps[] = {
207 {
208 .clkdm_name = "core_l3_clkdm",
209 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
210 },
211 {
212 .clkdm_name = "core_l4_clkdm",
213 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
214 },
215 {
216 .clkdm_name = "iva2_clkdm",
217 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
218 },
219 {
220 .clkdm_name = "dss_clkdm",
221 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
222 },
223 {
224 .clkdm_name = "per_clkdm",
225 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
226 },
227 { NULL },
228};
229
230/*
231 * 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER
232 */
233static struct clkdm_dep iva2_wkdeps[] = {
234 {
235 .clkdm_name = "core_l3_clkdm",
236 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
237 },
238 {
239 .clkdm_name = "core_l4_clkdm",
240 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
241 },
242 {
243 .clkdm_name = "mpu_clkdm",
244 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
245 },
246 {
247 .clkdm_name = "wkup_clkdm",
248 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
249 },
250 {
251 .clkdm_name = "dss_clkdm",
252 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
253 },
254 {
255 .clkdm_name = "per_clkdm",
256 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
257 },
258 { NULL },
259};
260
261
262/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */
263static struct clkdm_dep cam_dss_wkdeps[] = {
264 {
265 .clkdm_name = "iva2_clkdm",
266 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
267 },
268 {
269 .clkdm_name = "mpu_clkdm",
270 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
271 },
272 {
273 .clkdm_name = "wkup_clkdm",
274 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
275 },
276 { NULL },
277};
278
279/* 3430: PM_WKDEP_NEON: MPU */
280static struct clkdm_dep neon_wkdeps[] = {
281 {
282 .clkdm_name = "mpu_clkdm",
283 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
284 },
285 { NULL },
286};
287
288
289/* Sleep dependency source arrays for 34xx-specific clkdms - 34XX only */
290
291/*
292 * 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA
293 * 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA
294 */
295static struct clkdm_dep dss_per_usbhost_sleepdeps[] = {
296 {
297 .clkdm_name = "mpu_clkdm",
298 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
299 },
300 {
301 .clkdm_name = "iva2_clkdm",
302 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
303 },
304 { NULL },
305};
306
307/*
308 * 3430: CM_SLEEPDEP_CAM: MPU
309 * 3430ES1: CM_SLEEPDEP_GFX: MPU
310 * 3430ES2: CM_SLEEPDEP_SGX: MPU
311 */
312static struct clkdm_dep cam_gfx_sleepdeps[] = {
313 {
314 .clkdm_name = "mpu_clkdm",
315 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
316 },
317 { NULL },
318};
319
320#endif /* CONFIG_ARCH_OMAP34XX */
321
322
323/*
24 * OMAP2/3-common clockdomains 324 * OMAP2/3-common clockdomains
25 * 325 *
26 * Even though the 2420 has a single PRCM module from the 326 * Even though the 2420 has a single PRCM module from the
@@ -35,6 +335,7 @@
35static struct clockdomain wkup_clkdm = { 335static struct clockdomain wkup_clkdm = {
36 .name = "wkup_clkdm", 336 .name = "wkup_clkdm",
37 .pwrdm = { .name = "wkup_pwrdm" }, 337 .pwrdm = { .name = "wkup_pwrdm" },
338 .dep_bit = OMAP_EN_WKUP_SHIFT,
38 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430), 339 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
39}; 340};
40 341
@@ -63,6 +364,7 @@ static struct clockdomain mpu_2420_clkdm = {
63 .pwrdm = { .name = "mpu_pwrdm" }, 364 .pwrdm = { .name = "mpu_pwrdm" },
64 .flags = CLKDM_CAN_HWSUP, 365 .flags = CLKDM_CAN_HWSUP,
65 .clkstctrl_reg = OMAP2420_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL), 366 .clkstctrl_reg = OMAP2420_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL),
367 .wkdep_srcs = mpu_24xx_wkdeps,
66 .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK, 368 .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
67 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), 369 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
68}; 370};
@@ -73,6 +375,8 @@ static struct clockdomain iva1_2420_clkdm = {
73 .flags = CLKDM_CAN_HWSUP_SWSUP, 375 .flags = CLKDM_CAN_HWSUP_SWSUP,
74 .clkstctrl_reg = OMAP2420_CM_REGADDR(OMAP24XX_DSP_MOD, 376 .clkstctrl_reg = OMAP2420_CM_REGADDR(OMAP24XX_DSP_MOD,
75 OMAP2_CM_CLKSTCTRL), 377 OMAP2_CM_CLKSTCTRL),
378 .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
379 .wkdep_srcs = dsp_mdm_24xx_wkdeps,
76 .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK, 380 .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
77 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), 381 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
78}; 382};
@@ -92,6 +396,7 @@ static struct clockdomain gfx_2420_clkdm = {
92 .pwrdm = { .name = "gfx_pwrdm" }, 396 .pwrdm = { .name = "gfx_pwrdm" },
93 .flags = CLKDM_CAN_HWSUP_SWSUP, 397 .flags = CLKDM_CAN_HWSUP_SWSUP,
94 .clkstctrl_reg = OMAP2420_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL), 398 .clkstctrl_reg = OMAP2420_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
399 .wkdep_srcs = gfx_sgx_wkdeps,
95 .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK, 400 .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
96 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), 401 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
97}; 402};
@@ -101,6 +406,7 @@ static struct clockdomain core_l3_2420_clkdm = {
101 .pwrdm = { .name = "core_pwrdm" }, 406 .pwrdm = { .name = "core_pwrdm" },
102 .flags = CLKDM_CAN_HWSUP, 407 .flags = CLKDM_CAN_HWSUP,
103 .clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL), 408 .clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
409 .wkdep_srcs = core_24xx_wkdeps,
104 .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK, 410 .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
105 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), 411 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
106}; 412};
@@ -110,6 +416,7 @@ static struct clockdomain core_l4_2420_clkdm = {
110 .pwrdm = { .name = "core_pwrdm" }, 416 .pwrdm = { .name = "core_pwrdm" },
111 .flags = CLKDM_CAN_HWSUP, 417 .flags = CLKDM_CAN_HWSUP,
112 .clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL), 418 .clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
419 .wkdep_srcs = core_24xx_wkdeps,
113 .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK, 420 .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
114 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), 421 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
115}; 422};
@@ -138,16 +445,20 @@ static struct clockdomain mpu_2430_clkdm = {
138 .flags = CLKDM_CAN_HWSUP_SWSUP, 445 .flags = CLKDM_CAN_HWSUP_SWSUP,
139 .clkstctrl_reg = OMAP2430_CM_REGADDR(MPU_MOD, 446 .clkstctrl_reg = OMAP2430_CM_REGADDR(MPU_MOD,
140 OMAP2_CM_CLKSTCTRL), 447 OMAP2_CM_CLKSTCTRL),
448 .wkdep_srcs = mpu_24xx_wkdeps,
141 .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK, 449 .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
142 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), 450 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
143}; 451};
144 452
453/* Another case of bit name collisions between several registers: EN_MDM */
145static struct clockdomain mdm_clkdm = { 454static struct clockdomain mdm_clkdm = {
146 .name = "mdm_clkdm", 455 .name = "mdm_clkdm",
147 .pwrdm = { .name = "mdm_pwrdm" }, 456 .pwrdm = { .name = "mdm_pwrdm" },
148 .flags = CLKDM_CAN_HWSUP_SWSUP, 457 .flags = CLKDM_CAN_HWSUP_SWSUP,
149 .clkstctrl_reg = OMAP2430_CM_REGADDR(OMAP2430_MDM_MOD, 458 .clkstctrl_reg = OMAP2430_CM_REGADDR(OMAP2430_MDM_MOD,
150 OMAP2_CM_CLKSTCTRL), 459 OMAP2_CM_CLKSTCTRL),
460 .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
461 .wkdep_srcs = dsp_mdm_24xx_wkdeps,
151 .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK, 462 .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
152 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), 463 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
153}; 464};
@@ -158,6 +469,8 @@ static struct clockdomain dsp_2430_clkdm = {
158 .flags = CLKDM_CAN_HWSUP_SWSUP, 469 .flags = CLKDM_CAN_HWSUP_SWSUP,
159 .clkstctrl_reg = OMAP2430_CM_REGADDR(OMAP24XX_DSP_MOD, 470 .clkstctrl_reg = OMAP2430_CM_REGADDR(OMAP24XX_DSP_MOD,
160 OMAP2_CM_CLKSTCTRL), 471 OMAP2_CM_CLKSTCTRL),
472 .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
473 .wkdep_srcs = dsp_mdm_24xx_wkdeps,
161 .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK, 474 .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
162 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), 475 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
163}; 476};
@@ -167,24 +480,39 @@ static struct clockdomain gfx_2430_clkdm = {
167 .pwrdm = { .name = "gfx_pwrdm" }, 480 .pwrdm = { .name = "gfx_pwrdm" },
168 .flags = CLKDM_CAN_HWSUP_SWSUP, 481 .flags = CLKDM_CAN_HWSUP_SWSUP,
169 .clkstctrl_reg = OMAP2430_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL), 482 .clkstctrl_reg = OMAP2430_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
483 .wkdep_srcs = gfx_sgx_wkdeps,
170 .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK, 484 .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
171 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), 485 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
172}; 486};
173 487
488/*
489 * XXX add usecounting for clkdm dependencies, otherwise the presence
490 * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
491 * could cause trouble
492 */
174static struct clockdomain core_l3_2430_clkdm = { 493static struct clockdomain core_l3_2430_clkdm = {
175 .name = "core_l3_clkdm", 494 .name = "core_l3_clkdm",
176 .pwrdm = { .name = "core_pwrdm" }, 495 .pwrdm = { .name = "core_pwrdm" },
177 .flags = CLKDM_CAN_HWSUP, 496 .flags = CLKDM_CAN_HWSUP,
178 .clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL), 497 .clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
498 .dep_bit = OMAP24XX_EN_CORE_SHIFT,
499 .wkdep_srcs = core_24xx_wkdeps,
179 .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK, 500 .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
180 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), 501 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
181}; 502};
182 503
504/*
505 * XXX add usecounting for clkdm dependencies, otherwise the presence
506 * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
507 * could cause trouble
508 */
183static struct clockdomain core_l4_2430_clkdm = { 509static struct clockdomain core_l4_2430_clkdm = {
184 .name = "core_l4_clkdm", 510 .name = "core_l4_clkdm",
185 .pwrdm = { .name = "core_pwrdm" }, 511 .pwrdm = { .name = "core_pwrdm" },
186 .flags = CLKDM_CAN_HWSUP, 512 .flags = CLKDM_CAN_HWSUP,
187 .clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL), 513 .clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
514 .dep_bit = OMAP24XX_EN_CORE_SHIFT,
515 .wkdep_srcs = core_24xx_wkdeps,
188 .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK, 516 .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
189 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), 517 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
190}; 518};
@@ -212,6 +540,8 @@ static struct clockdomain mpu_34xx_clkdm = {
212 .pwrdm = { .name = "mpu_pwrdm" }, 540 .pwrdm = { .name = "mpu_pwrdm" },
213 .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP, 541 .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
214 .clkstctrl_reg = OMAP34XX_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL), 542 .clkstctrl_reg = OMAP34XX_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL),
543 .dep_bit = OMAP3430_EN_MPU_SHIFT,
544 .wkdep_srcs = mpu_34xx_wkdeps,
215 .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK, 545 .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
216 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 546 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
217}; 547};
@@ -222,6 +552,7 @@ static struct clockdomain neon_clkdm = {
222 .flags = CLKDM_CAN_HWSUP_SWSUP, 552 .flags = CLKDM_CAN_HWSUP_SWSUP,
223 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_NEON_MOD, 553 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_NEON_MOD,
224 OMAP2_CM_CLKSTCTRL), 554 OMAP2_CM_CLKSTCTRL),
555 .wkdep_srcs = neon_wkdeps,
225 .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK, 556 .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
226 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 557 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
227}; 558};
@@ -232,6 +563,8 @@ static struct clockdomain iva2_clkdm = {
232 .flags = CLKDM_CAN_HWSUP_SWSUP, 563 .flags = CLKDM_CAN_HWSUP_SWSUP,
233 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD, 564 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD,
234 OMAP2_CM_CLKSTCTRL), 565 OMAP2_CM_CLKSTCTRL),
566 .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
567 .wkdep_srcs = iva2_wkdeps,
235 .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK, 568 .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
236 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 569 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
237}; 570};
@@ -241,6 +574,8 @@ static struct clockdomain gfx_3430es1_clkdm = {
241 .pwrdm = { .name = "gfx_pwrdm" }, 574 .pwrdm = { .name = "gfx_pwrdm" },
242 .flags = CLKDM_CAN_HWSUP_SWSUP, 575 .flags = CLKDM_CAN_HWSUP_SWSUP,
243 .clkstctrl_reg = OMAP34XX_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL), 576 .clkstctrl_reg = OMAP34XX_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
577 .wkdep_srcs = gfx_sgx_wkdeps,
578 .sleepdep_srcs = cam_gfx_sleepdeps,
244 .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK, 579 .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
245 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1), 580 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
246}; 581};
@@ -251,6 +586,8 @@ static struct clockdomain sgx_clkdm = {
251 .flags = CLKDM_CAN_HWSUP_SWSUP, 586 .flags = CLKDM_CAN_HWSUP_SWSUP,
252 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430ES2_SGX_MOD, 587 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430ES2_SGX_MOD,
253 OMAP2_CM_CLKSTCTRL), 588 OMAP2_CM_CLKSTCTRL),
589 .wkdep_srcs = gfx_sgx_wkdeps,
590 .sleepdep_srcs = cam_gfx_sleepdeps,
254 .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK, 591 .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
255 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2), 592 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
256}; 593};
@@ -271,30 +608,46 @@ static struct clockdomain d2d_clkdm = {
271 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 608 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
272}; 609};
273 610
611/*
612 * XXX add usecounting for clkdm dependencies, otherwise the presence
613 * of a single dep bit for core_l3_34xx_clkdm and core_l4_34xx_clkdm
614 * could cause trouble
615 */
274static struct clockdomain core_l3_34xx_clkdm = { 616static struct clockdomain core_l3_34xx_clkdm = {
275 .name = "core_l3_clkdm", 617 .name = "core_l3_clkdm",
276 .pwrdm = { .name = "core_pwrdm" }, 618 .pwrdm = { .name = "core_pwrdm" },
277 .flags = CLKDM_CAN_HWSUP, 619 .flags = CLKDM_CAN_HWSUP,
278 .clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL), 620 .clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
621 .dep_bit = OMAP3430_EN_CORE_SHIFT,
279 .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK, 622 .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
280 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 623 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
281}; 624};
282 625
626/*
627 * XXX add usecounting for clkdm dependencies, otherwise the presence
628 * of a single dep bit for core_l3_34xx_clkdm and core_l4_34xx_clkdm
629 * could cause trouble
630 */
283static struct clockdomain core_l4_34xx_clkdm = { 631static struct clockdomain core_l4_34xx_clkdm = {
284 .name = "core_l4_clkdm", 632 .name = "core_l4_clkdm",
285 .pwrdm = { .name = "core_pwrdm" }, 633 .pwrdm = { .name = "core_pwrdm" },
286 .flags = CLKDM_CAN_HWSUP, 634 .flags = CLKDM_CAN_HWSUP,
287 .clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL), 635 .clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
636 .dep_bit = OMAP3430_EN_CORE_SHIFT,
288 .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK, 637 .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
289 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 638 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
290}; 639};
291 640
641/* Another case of bit name collisions between several registers: EN_DSS */
292static struct clockdomain dss_34xx_clkdm = { 642static struct clockdomain dss_34xx_clkdm = {
293 .name = "dss_clkdm", 643 .name = "dss_clkdm",
294 .pwrdm = { .name = "dss_pwrdm" }, 644 .pwrdm = { .name = "dss_pwrdm" },
295 .flags = CLKDM_CAN_HWSUP_SWSUP, 645 .flags = CLKDM_CAN_HWSUP_SWSUP,
296 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 646 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD,
297 OMAP2_CM_CLKSTCTRL), 647 OMAP2_CM_CLKSTCTRL),
648 .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
649 .wkdep_srcs = cam_dss_wkdeps,
650 .sleepdep_srcs = dss_per_usbhost_sleepdeps,
298 .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK, 651 .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
299 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 652 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
300}; 653};
@@ -305,6 +658,8 @@ static struct clockdomain cam_clkdm = {
305 .flags = CLKDM_CAN_HWSUP_SWSUP, 658 .flags = CLKDM_CAN_HWSUP_SWSUP,
306 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_CAM_MOD, 659 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_CAM_MOD,
307 OMAP2_CM_CLKSTCTRL), 660 OMAP2_CM_CLKSTCTRL),
661 .wkdep_srcs = cam_dss_wkdeps,
662 .sleepdep_srcs = cam_gfx_sleepdeps,
308 .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK, 663 .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
309 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 664 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
310}; 665};
@@ -315,6 +670,8 @@ static struct clockdomain usbhost_clkdm = {
315 .flags = CLKDM_CAN_HWSUP_SWSUP, 670 .flags = CLKDM_CAN_HWSUP_SWSUP,
316 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, 671 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430ES2_USBHOST_MOD,
317 OMAP2_CM_CLKSTCTRL), 672 OMAP2_CM_CLKSTCTRL),
673 .wkdep_srcs = per_usbhost_wkdeps,
674 .sleepdep_srcs = dss_per_usbhost_sleepdeps,
318 .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK, 675 .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
319 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2), 676 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
320}; 677};
@@ -325,6 +682,9 @@ static struct clockdomain per_clkdm = {
325 .flags = CLKDM_CAN_HWSUP_SWSUP, 682 .flags = CLKDM_CAN_HWSUP_SWSUP,
326 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD, 683 .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD,
327 OMAP2_CM_CLKSTCTRL), 684 OMAP2_CM_CLKSTCTRL),
685 .dep_bit = OMAP3430_EN_PER_SHIFT,
686 .wkdep_srcs = per_usbhost_wkdeps,
687 .sleepdep_srcs = dss_per_usbhost_sleepdeps,
328 .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK, 688 .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
329 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 689 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
330}; 690};
@@ -378,25 +738,21 @@ static struct clockdomain dpll5_clkdm = {
378#include "clockdomains44xx.h" 738#include "clockdomains44xx.h"
379 739
380/* 740/*
381 * Clockdomain-powerdomain hwsup dependencies (34XX only) 741 * Clockdomain hwsup dependencies (34XX only)
382 */ 742 */
383 743
384static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = { 744static struct clkdm_autodep clkdm_autodeps[] = {
385
386#ifdef CONFIG_ARCH_OMAP34XX
387 { 745 {
388 .pwrdm = { .name = "mpu_pwrdm" }, 746 .clkdm = { .name = "mpu_clkdm" },
389 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) 747 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
390 }, 748 },
391 { 749 {
392 .pwrdm = { .name = "iva2_pwrdm" }, 750 .clkdm = { .name = "iva2_clkdm" },
393 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) 751 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
394 }, 752 },
395 { 753 {
396 .pwrdm = { .name = NULL }, 754 .clkdm = { .name = NULL },
397 } 755 }
398#endif
399
400}; 756};
401 757
402/* 758/*
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 51d7453f406d..8c58699083f6 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -313,7 +313,7 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
313 hwmods = omap34xx_hwmods; 313 hwmods = omap34xx_hwmods;
314 314
315 pwrdm_init(powerdomains_omap); 315 pwrdm_init(powerdomains_omap);
316 clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); 316 clkdm_init(clockdomains_omap, clkdm_autodeps);
317#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ 317#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
318 /* The OPP tables have to be registered before a clk init */ 318 /* The OPP tables have to be registered before a clk init */
319 omap_hwmod_init(hwmods); 319 omap_hwmod_init(hwmods);
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 478ae585ca39..ad884c0aaa42 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -299,15 +299,14 @@ static int _disable_wakeup(struct omap_hwmod *oh)
299 * be accessed by the IVA, there should be a sleepdep between the IVA 299 * be accessed by the IVA, there should be a sleepdep between the IVA
300 * initiator and the module). Only applies to modules in smart-idle 300 * initiator and the module). Only applies to modules in smart-idle
301 * mode. Returns -EINVAL upon error or passes along 301 * mode. Returns -EINVAL upon error or passes along
302 * pwrdm_add_sleepdep() value upon success. 302 * clkdm_add_sleepdep() value upon success.
303 */ 303 */
304static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) 304static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
305{ 305{
306 if (!oh->_clk) 306 if (!oh->_clk)
307 return -EINVAL; 307 return -EINVAL;
308 308
309 return pwrdm_add_sleepdep(oh->_clk->clkdm->pwrdm.ptr, 309 return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
310 init_oh->_clk->clkdm->pwrdm.ptr);
311} 310}
312 311
313/** 312/**
@@ -320,15 +319,14 @@ static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
320 * be accessed by the IVA, there should be no sleepdep between the IVA 319 * be accessed by the IVA, there should be no sleepdep between the IVA
321 * initiator and the module). Only applies to modules in smart-idle 320 * initiator and the module). Only applies to modules in smart-idle
322 * mode. Returns -EINVAL upon error or passes along 321 * mode. Returns -EINVAL upon error or passes along
323 * pwrdm_add_sleepdep() value upon success. 322 * clkdm_del_sleepdep() value upon success.
324 */ 323 */
325static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) 324static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
326{ 325{
327 if (!oh->_clk) 326 if (!oh->_clk)
328 return -EINVAL; 327 return -EINVAL;
329 328
330 return pwrdm_del_sleepdep(oh->_clk->clkdm->pwrdm.ptr, 329 return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
331 init_oh->_clk->clkdm->pwrdm.ptr);
332} 330}
333 331
334/** 332/**
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index f841a6e33611..5f59df87abf7 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -1018,6 +1018,7 @@ void omap_push_sram_idle(void)
1018static int __init omap3_pm_init(void) 1018static int __init omap3_pm_init(void)
1019{ 1019{
1020 struct power_state *pwrst, *tmp; 1020 struct power_state *pwrst, *tmp;
1021 struct clockdomain *neon_clkdm, *per_clkdm, *mpu_clkdm, *core_clkdm;
1021 int ret; 1022 int ret;
1022 1023
1023 if (!cpu_is_omap34xx()) 1024 if (!cpu_is_omap34xx())
@@ -1057,6 +1058,11 @@ static int __init omap3_pm_init(void)
1057 core_pwrdm = pwrdm_lookup("core_pwrdm"); 1058 core_pwrdm = pwrdm_lookup("core_pwrdm");
1058 cam_pwrdm = pwrdm_lookup("cam_pwrdm"); 1059 cam_pwrdm = pwrdm_lookup("cam_pwrdm");
1059 1060
1061 neon_clkdm = clkdm_lookup("neon_clkdm");
1062 mpu_clkdm = clkdm_lookup("mpu_clkdm");
1063 per_clkdm = clkdm_lookup("per_clkdm");
1064 core_clkdm = clkdm_lookup("core_clkdm");
1065
1060 omap_push_sram_idle(); 1066 omap_push_sram_idle();
1061#ifdef CONFIG_SUSPEND 1067#ifdef CONFIG_SUSPEND
1062 suspend_set_ops(&omap_pm_ops); 1068 suspend_set_ops(&omap_pm_ops);
@@ -1065,14 +1071,14 @@ static int __init omap3_pm_init(void)
1065 pm_idle = omap3_pm_idle; 1071 pm_idle = omap3_pm_idle;
1066 omap3_idle_init(); 1072 omap3_idle_init();
1067 1073
1068 pwrdm_add_wkdep(neon_pwrdm, mpu_pwrdm); 1074 clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
1069 /* 1075 /*
1070 * REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for 1076 * REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for
1071 * IO-pad wakeup. Otherwise it will unnecessarily waste power 1077 * IO-pad wakeup. Otherwise it will unnecessarily waste power
1072 * waking up PER with every CORE wakeup - see 1078 * waking up PER with every CORE wakeup - see
1073 * http://marc.info/?l=linux-omap&m=121852150710062&w=2 1079 * http://marc.info/?l=linux-omap&m=121852150710062&w=2
1074 */ 1080 */
1075 pwrdm_add_wkdep(per_pwrdm, core_pwrdm); 1081 clkdm_add_wkdep(per_clkdm, core_clkdm);
1076 1082
1077 if (omap_type() != OMAP2_DEVICE_TYPE_GP) { 1083 if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
1078 omap3_secure_ram_storage = 1084 omap3_secure_ram_storage =
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index c0de05097b5d..e8e8d8872a0e 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -2,7 +2,7 @@
2 * OMAP powerdomain control 2 * OMAP powerdomain control
3 * 3 *
4 * Copyright (C) 2007-2008 Texas Instruments, Inc. 4 * Copyright (C) 2007-2008 Texas Instruments, Inc.
5 * Copyright (C) 2007-2008 Nokia Corporation 5 * Copyright (C) 2007-2009 Nokia Corporation
6 * 6 *
7 * Written by Paul Walmsley 7 * Written by Paul Walmsley
8 * 8 *
@@ -36,6 +36,7 @@
36#include <plat/cpu.h> 36#include <plat/cpu.h>
37#include <plat/powerdomain.h> 37#include <plat/powerdomain.h>
38#include <plat/clockdomain.h> 38#include <plat/clockdomain.h>
39#include <plat/prcm.h>
39 40
40#include "pm.h" 41#include "pm.h"
41 42
@@ -88,17 +89,6 @@ static DEFINE_RWLOCK(pwrdm_rwlock);
88 89
89/* Private functions */ 90/* Private functions */
90 91
91static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
92{
93 u32 v;
94
95 v = prm_read_mod_reg(domain, idx);
96 v &= mask;
97 v >>= __ffs(mask);
98
99 return v;
100}
101
102static struct powerdomain *_pwrdm_lookup(const char *name) 92static struct powerdomain *_pwrdm_lookup(const char *name)
103{ 93{
104 struct powerdomain *pwrdm, *temp_pwrdm; 94 struct powerdomain *pwrdm, *temp_pwrdm;
@@ -115,34 +105,6 @@ static struct powerdomain *_pwrdm_lookup(const char *name)
115 return pwrdm; 105 return pwrdm;
116} 106}
117 107
118/* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */
119static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
120 struct pwrdm_dep *deps)
121{
122 struct pwrdm_dep *pd;
123
124 if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
125 return ERR_PTR(-EINVAL);
126
127 for (pd = deps; pd->pwrdm_name; pd++) {
128
129 if (!omap_chip_is(pd->omap_chip))
130 continue;
131
132 if (!pd->pwrdm && pd->pwrdm_name)
133 pd->pwrdm = pwrdm_lookup(pd->pwrdm_name);
134
135 if (pd->pwrdm == pwrdm)
136 break;
137
138 }
139
140 if (!pd->pwrdm_name)
141 return ERR_PTR(-ENOENT);
142
143 return pd->pwrdm;
144}
145
146static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) 108static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
147{ 109{
148 110
@@ -502,223 +464,6 @@ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
502 return ret; 464 return ret;
503} 465}
504 466
505
506/**
507 * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
508 * @pwrdm1: wake this struct powerdomain * up (dependent)
509 * @pwrdm2: when this struct powerdomain * wakes up (source)
510 *
511 * When the powerdomain represented by pwrdm2 wakes up (due to an
512 * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP,
513 * this feature is designed to reduce wakeup latency of the dependent
514 * powerdomain. Returns -EINVAL if presented with invalid powerdomain
515 * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
516 * 0 upon success.
517 */
518int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
519{
520 struct powerdomain *p;
521
522 if (!pwrdm1)
523 return -EINVAL;
524
525 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
526 if (IS_ERR(p)) {
527 pr_debug("powerdomain: hardware cannot set/clear wake up of "
528 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
529 return PTR_ERR(p);
530 }
531
532 pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
533 pwrdm1->name, pwrdm2->name);
534
535 prm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
536 pwrdm1->prcm_offs, PM_WKDEP);
537
538 return 0;
539}
540
541/**
542 * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1
543 * @pwrdm1: wake this struct powerdomain * up (dependent)
544 * @pwrdm2: when this struct powerdomain * wakes up (source)
545 *
546 * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2
547 * wakes up. Returns -EINVAL if presented with invalid powerdomain
548 * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
549 * 0 upon success.
550 */
551int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
552{
553 struct powerdomain *p;
554
555 if (!pwrdm1)
556 return -EINVAL;
557
558 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
559 if (IS_ERR(p)) {
560 pr_debug("powerdomain: hardware cannot set/clear wake up of "
561 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
562 return PTR_ERR(p);
563 }
564
565 pr_debug("powerdomain: hardware will no longer wake up %s after %s "
566 "wakes up\n", pwrdm1->name, pwrdm2->name);
567
568 prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
569 pwrdm1->prcm_offs, PM_WKDEP);
570
571 return 0;
572}
573
574/**
575 * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1
576 * @pwrdm1: wake this struct powerdomain * up (dependent)
577 * @pwrdm2: when this struct powerdomain * wakes up (source)
578 *
579 * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be
580 * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL
581 * if either powerdomain pointer is invalid; or -ENOENT if the hardware
582 * is incapable.
583 *
584 * REVISIT: Currently this function only represents software-controllable
585 * wakeup dependencies. Wakeup dependencies fixed in hardware are not
586 * yet handled here.
587 */
588int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
589{
590 struct powerdomain *p;
591
592 if (!pwrdm1)
593 return -EINVAL;
594
595 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
596 if (IS_ERR(p)) {
597 pr_debug("powerdomain: hardware cannot set/clear wake up of "
598 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
599 return PTR_ERR(p);
600 }
601
602 return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
603 (1 << pwrdm2->dep_bit));
604}
605
606/**
607 * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1
608 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
609 * @pwrdm2: when this struct powerdomain * is active (source)
610 *
611 * Prevent pwrdm1 from automatically going inactive (and then to
612 * retention or off) if pwrdm2 is still active. Returns -EINVAL if
613 * presented with invalid powerdomain pointers or called on a machine
614 * that does not support software-configurable hardware sleep dependencies,
615 * -ENOENT if the specified dependency cannot be set in hardware, or
616 * 0 upon success.
617 */
618int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
619{
620 struct powerdomain *p;
621
622 if (!cpu_is_omap34xx())
623 return -EINVAL;
624
625 if (!pwrdm1)
626 return -EINVAL;
627
628 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
629 if (IS_ERR(p)) {
630 pr_debug("powerdomain: hardware cannot set/clear sleep "
631 "dependency affecting %s from %s\n", pwrdm1->name,
632 pwrdm2->name);
633 return PTR_ERR(p);
634 }
635
636 pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
637 pwrdm1->name, pwrdm2->name);
638
639 cm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
640 pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
641
642 return 0;
643}
644
645/**
646 * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1
647 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
648 * @pwrdm2: when this struct powerdomain * is active (source)
649 *
650 * Allow pwrdm1 to automatically go inactive (and then to retention or
651 * off), independent of the activity state of pwrdm2. Returns -EINVAL
652 * if presented with invalid powerdomain pointers or called on a machine
653 * that does not support software-configurable hardware sleep dependencies,
654 * -ENOENT if the specified dependency cannot be cleared in hardware, or
655 * 0 upon success.
656 */
657int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
658{
659 struct powerdomain *p;
660
661 if (!cpu_is_omap34xx())
662 return -EINVAL;
663
664 if (!pwrdm1)
665 return -EINVAL;
666
667 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
668 if (IS_ERR(p)) {
669 pr_debug("powerdomain: hardware cannot set/clear sleep "
670 "dependency affecting %s from %s\n", pwrdm1->name,
671 pwrdm2->name);
672 return PTR_ERR(p);
673 }
674
675 pr_debug("powerdomain: will no longer prevent %s from sleeping if "
676 "%s is active\n", pwrdm1->name, pwrdm2->name);
677
678 cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
679 pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
680
681 return 0;
682}
683
684/**
685 * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1
686 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
687 * @pwrdm2: when this struct powerdomain * is active (source)
688 *
689 * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will
690 * not be allowed to automatically go inactive if pwrdm2 is active;
691 * 0 if pwrdm1's automatic power state inactivity transition is independent
692 * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called
693 * on a machine that does not support software-configurable hardware sleep
694 * dependencies; or -ENOENT if the hardware is incapable.
695 *
696 * REVISIT: Currently this function only represents software-controllable
697 * sleep dependencies. Sleep dependencies fixed in hardware are not
698 * yet handled here.
699 */
700int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
701{
702 struct powerdomain *p;
703
704 if (!cpu_is_omap34xx())
705 return -EINVAL;
706
707 if (!pwrdm1)
708 return -EINVAL;
709
710 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
711 if (IS_ERR(p)) {
712 pr_debug("powerdomain: hardware cannot set/clear sleep "
713 "dependency affecting %s from %s\n", pwrdm1->name,
714 pwrdm2->name);
715 return PTR_ERR(p);
716 }
717
718 return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
719 (1 << pwrdm2->dep_bit));
720}
721
722/** 467/**
723 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain 468 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
724 * @pwrdm: struct powerdomain * 469 * @pwrdm: struct powerdomain *
diff --git a/arch/arm/mach-omap2/powerdomains.h b/arch/arm/mach-omap2/powerdomains.h
index d646c9979c38..faa8fc952d95 100644
--- a/arch/arm/mach-omap2/powerdomains.h
+++ b/arch/arm/mach-omap2/powerdomains.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * OMAP2/3 common powerdomain definitions 2 * OMAP2/3 common powerdomain definitions
3 * 3 *
4 * Copyright (C) 2007-8 Texas Instruments, Inc. 4 * Copyright (C) 2007-2008 Texas Instruments, Inc.
5 * Copyright (C) 2007-8 Nokia Corporation 5 * Copyright (C) 2007-2009 Nokia Corporation
6 * 6 *
7 * Written by Paul Walmsley 7 * Written by Paul Walmsley
8 * Debugging and integration fixes by Jouni Högander 8 * Debugging and integration fixes by Jouni Högander
@@ -25,19 +25,8 @@
25 * This file contains all of the powerdomains that have some element 25 * This file contains all of the powerdomains that have some element
26 * of software control for the OMAP24xx and OMAP34XX chips. 26 * of software control for the OMAP24xx and OMAP34XX chips.
27 * 27 *
28 * A few notes:
29 *
30 * This is not an exhaustive listing of powerdomains on the chips; only 28 * This is not an exhaustive listing of powerdomains on the chips; only
31 * powerdomains that can be controlled in software. 29 * powerdomains that can be controlled in software.
32 *
33 * A useful validation rule for struct powerdomain:
34 * Any powerdomain referenced by a wkdep_srcs or sleepdep_srcs array
35 * must have a dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really
36 * just software-controllable dependencies. Non-software-controllable
37 * dependencies do exist, but they are not encoded below (yet).
38 *
39 * 24xx does not support programmable sleep dependencies (SLEEPDEP)
40 *
41 */ 30 */
42 31
43/* 32/*
@@ -47,26 +36,17 @@
47 * 36 *
48 * On the 2420, this is a 'C55 DSP called, simply, the DSP. Its 37 * On the 2420, this is a 'C55 DSP called, simply, the DSP. Its
49 * powerdomain is called the "DSP power domain." On the 2430, the 38 * powerdomain is called the "DSP power domain." On the 2430, the
50 * on-board DSP is a 'C64 DSP, now called the IVA2 or IVA2.1. Its 39 * on-board DSP is a 'C64 DSP, now called (along with its hardware
51 * powerdomain is still called the "DSP power domain." On the 3430, 40 * accelerators) the IVA2 or IVA2.1. Its powerdomain is still called
52 * the DSP is a 'C64 DSP like the 2430, also known as the IVA2; but 41 * the "DSP power domain." On the 3430, the DSP is a 'C64 DSP like the
53 * its powerdomain is now called the "IVA2 power domain." 42 * 2430, also known as the IVA2; but its powerdomain is now called the
43 * "IVA2 power domain."
54 * 44 *
55 * The 2420 also has something called the IVA, which is a separate ARM 45 * The 2420 also has something called the IVA, which is a separate ARM
56 * core, and has nothing to do with the DSP/IVA2. 46 * core, and has nothing to do with the DSP/IVA2.
57 * 47 *
58 * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM 48 * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM
59 * address offset is different between the C55 and C64 DSPs. 49 * address offset is different between the C55 and C64 DSPs.
60 *
61 * The overly-specific dep_bit names are due to a bit name collision
62 * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
63 * value are the same for all powerdomains: 2
64 */
65
66/*
67 * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
68 * sanity check?
69 * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
70 */ 50 */
71 51
72#include <plat/powerdomain.h> 52#include <plat/powerdomain.h>
@@ -74,60 +54,11 @@
74#include "prcm-common.h" 54#include "prcm-common.h"
75#include "prm.h" 55#include "prm.h"
76#include "cm.h" 56#include "cm.h"
77
78/* OMAP2/3-common powerdomains and wakeup dependencies */
79
80#ifndef CONFIG_ARCH_OMAP4
81/*
82 * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
83 * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
84 * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
85 */
86static struct pwrdm_dep gfx_sgx_wkdeps[] = {
87 {
88 .pwrdm_name = "core_pwrdm",
89 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
90 },
91 {
92 .pwrdm_name = "iva2_pwrdm",
93 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
94 },
95 {
96 .pwrdm_name = "mpu_pwrdm",
97 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
98 CHIP_IS_OMAP3430)
99 },
100 {
101 .pwrdm_name = "wkup_pwrdm",
102 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
103 CHIP_IS_OMAP3430)
104 },
105 { NULL },
106};
107
108/*
109 * 3430: CM_SLEEPDEP_CAM: MPU
110 * 3430ES1: CM_SLEEPDEP_GFX: MPU
111 * 3430ES2: CM_SLEEPDEP_SGX: MPU
112 */
113static struct pwrdm_dep cam_gfx_sleepdeps[] = {
114 {
115 .pwrdm_name = "mpu_pwrdm",
116 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
117 },
118 { NULL },
119};
120#endif
121
122
123#include "powerdomains24xx.h" 57#include "powerdomains24xx.h"
124#include "powerdomains34xx.h" 58#include "powerdomains34xx.h"
125#include "powerdomains44xx.h" 59#include "powerdomains44xx.h"
126 60
127 61/* OMAP2/3-common powerdomains */
128/*
129 * OMAP2/3 common powerdomains
130 */
131 62
132#if defined(CONFIG_ARCH_OMAP24XX) | defined(CONFIG_ARCH_OMAP34XX) 63#if defined(CONFIG_ARCH_OMAP24XX) | defined(CONFIG_ARCH_OMAP34XX)
133 64
@@ -140,8 +71,6 @@ static struct powerdomain gfx_omap2_pwrdm = {
140 .prcm_offs = GFX_MOD, 71 .prcm_offs = GFX_MOD,
141 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | 72 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
142 CHIP_IS_OMAP3430ES1), 73 CHIP_IS_OMAP3430ES1),
143 .wkdep_srcs = gfx_sgx_wkdeps,
144 .sleepdep_srcs = cam_gfx_sleepdeps,
145 .pwrsts = PWRSTS_OFF_RET_ON, 74 .pwrsts = PWRSTS_OFF_RET_ON,
146 .pwrsts_logic_ret = PWRDM_POWER_RET, 75 .pwrsts_logic_ret = PWRDM_POWER_RET,
147 .banks = 1, 76 .banks = 1,
@@ -157,7 +86,6 @@ static struct powerdomain wkup_omap2_pwrdm = {
157 .name = "wkup_pwrdm", 86 .name = "wkup_pwrdm",
158 .prcm_offs = WKUP_MOD, 87 .prcm_offs = WKUP_MOD,
159 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430), 88 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
160 .dep_bit = OMAP_EN_WKUP_SHIFT,
161}; 89};
162 90
163#endif 91#endif
diff --git a/arch/arm/mach-omap2/powerdomains24xx.h b/arch/arm/mach-omap2/powerdomains24xx.h
index bd249a495aa9..652a01b729e9 100644
--- a/arch/arm/mach-omap2/powerdomains24xx.h
+++ b/arch/arm/mach-omap2/powerdomains24xx.h
@@ -2,7 +2,7 @@
2 * OMAP24XX powerdomain definitions 2 * OMAP24XX powerdomain definitions
3 * 3 *
4 * Copyright (C) 2007-2008 Texas Instruments, Inc. 4 * Copyright (C) 2007-2008 Texas Instruments, Inc.
5 * Copyright (C) 2007-2008 Nokia Corporation 5 * Copyright (C) 2007-2009 Nokia Corporation
6 * 6 *
7 * Written by Paul Walmsley 7 * Written by Paul Walmsley
8 * Debugging and integration fixes by Jouni Högander 8 * Debugging and integration fixes by Jouni Högander
@@ -32,90 +32,12 @@
32 32
33#ifdef CONFIG_ARCH_OMAP24XX 33#ifdef CONFIG_ARCH_OMAP24XX
34 34
35
36/* Wakeup dependency source arrays */
37
38/*
39 * 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP
40 * 2430 PM_WKDEP_MDM: same as above
41 */
42static struct pwrdm_dep dsp_mdm_24xx_wkdeps[] = {
43 {
44 .pwrdm_name = "core_pwrdm",
45 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
46 },
47 {
48 .pwrdm_name = "mpu_pwrdm",
49 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
50 },
51 {
52 .pwrdm_name = "wkup_pwrdm",
53 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
54 },
55 { NULL },
56};
57
58/*
59 * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
60 * 2430 adds MDM
61 */
62static struct pwrdm_dep mpu_24xx_wkdeps[] = {
63 {
64 .pwrdm_name = "core_pwrdm",
65 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
66 },
67 {
68 .pwrdm_name = "dsp_pwrdm",
69 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
70 },
71 {
72 .pwrdm_name = "wkup_pwrdm",
73 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
74 },
75 {
76 .pwrdm_name = "mdm_pwrdm",
77 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
78 },
79 { NULL },
80};
81
82/*
83 * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
84 * 2430 adds MDM
85 */
86static struct pwrdm_dep core_24xx_wkdeps[] = {
87 {
88 .pwrdm_name = "dsp_pwrdm",
89 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
90 },
91 {
92 .pwrdm_name = "gfx_pwrdm",
93 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
94 },
95 {
96 .pwrdm_name = "mpu_pwrdm",
97 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
98 },
99 {
100 .pwrdm_name = "wkup_pwrdm",
101 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
102 },
103 {
104 .pwrdm_name = "mdm_pwrdm",
105 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
106 },
107 { NULL },
108};
109
110
111/* Powerdomains */ 35/* Powerdomains */
112 36
113static struct powerdomain dsp_pwrdm = { 37static struct powerdomain dsp_pwrdm = {
114 .name = "dsp_pwrdm", 38 .name = "dsp_pwrdm",
115 .prcm_offs = OMAP24XX_DSP_MOD, 39 .prcm_offs = OMAP24XX_DSP_MOD,
116 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), 40 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
117 .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
118 .wkdep_srcs = dsp_mdm_24xx_wkdeps,
119 .pwrsts = PWRSTS_OFF_RET_ON, 41 .pwrsts = PWRSTS_OFF_RET_ON,
120 .pwrsts_logic_ret = PWRDM_POWER_RET, 42 .pwrsts_logic_ret = PWRDM_POWER_RET,
121 .banks = 1, 43 .banks = 1,
@@ -131,8 +53,6 @@ static struct powerdomain mpu_24xx_pwrdm = {
131 .name = "mpu_pwrdm", 53 .name = "mpu_pwrdm",
132 .prcm_offs = MPU_MOD, 54 .prcm_offs = MPU_MOD,
133 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), 55 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
134 .dep_bit = OMAP24XX_EN_MPU_SHIFT,
135 .wkdep_srcs = mpu_24xx_wkdeps,
136 .pwrsts = PWRSTS_OFF_RET_ON, 56 .pwrsts = PWRSTS_OFF_RET_ON,
137 .pwrsts_logic_ret = PWRSTS_OFF_RET, 57 .pwrsts_logic_ret = PWRSTS_OFF_RET,
138 .banks = 1, 58 .banks = 1,
@@ -148,9 +68,7 @@ static struct powerdomain core_24xx_pwrdm = {
148 .name = "core_pwrdm", 68 .name = "core_pwrdm",
149 .prcm_offs = CORE_MOD, 69 .prcm_offs = CORE_MOD,
150 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), 70 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
151 .wkdep_srcs = core_24xx_wkdeps,
152 .pwrsts = PWRSTS_OFF_RET_ON, 71 .pwrsts = PWRSTS_OFF_RET_ON,
153 .dep_bit = OMAP24XX_EN_CORE_SHIFT,
154 .banks = 3, 72 .banks = 3,
155 .pwrsts_mem_ret = { 73 .pwrsts_mem_ret = {
156 [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ 74 [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
@@ -176,13 +94,10 @@ static struct powerdomain core_24xx_pwrdm = {
176 94
177/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */ 95/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */
178 96
179/* Another case of bit name collisions between several registers: EN_MDM */
180static struct powerdomain mdm_pwrdm = { 97static struct powerdomain mdm_pwrdm = {
181 .name = "mdm_pwrdm", 98 .name = "mdm_pwrdm",
182 .prcm_offs = OMAP2430_MDM_MOD, 99 .prcm_offs = OMAP2430_MDM_MOD,
183 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), 100 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
184 .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
185 .wkdep_srcs = dsp_mdm_24xx_wkdeps,
186 .pwrsts = PWRSTS_OFF_RET_ON, 101 .pwrsts = PWRSTS_OFF_RET_ON,
187 .pwrsts_logic_ret = PWRDM_POWER_RET, 102 .pwrsts_logic_ret = PWRDM_POWER_RET,
188 .banks = 1, 103 .banks = 1,
diff --git a/arch/arm/mach-omap2/powerdomains34xx.h b/arch/arm/mach-omap2/powerdomains34xx.h
index 588f7e07d0ea..28228ef20e86 100644
--- a/arch/arm/mach-omap2/powerdomains34xx.h
+++ b/arch/arm/mach-omap2/powerdomains34xx.h
@@ -2,7 +2,7 @@
2 * OMAP34XX powerdomain definitions 2 * OMAP34XX powerdomain definitions
3 * 3 *
4 * Copyright (C) 2007-2008 Texas Instruments, Inc. 4 * Copyright (C) 2007-2008 Texas Instruments, Inc.
5 * Copyright (C) 2007-2008 Nokia Corporation 5 * Copyright (C) 2007-2009 Nokia Corporation
6 * 6 *
7 * Written by Paul Walmsley 7 * Written by Paul Walmsley
8 * Debugging and integration fixes by Jouni Högander 8 * Debugging and integration fixes by Jouni Högander
@@ -35,127 +35,6 @@
35#ifdef CONFIG_ARCH_OMAP34XX 35#ifdef CONFIG_ARCH_OMAP34XX
36 36
37/* 37/*
38 * 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP
39 * (USBHOST is ES2 only)
40 */
41static struct pwrdm_dep per_usbhost_wkdeps[] = {
42 {
43 .pwrdm_name = "core_pwrdm",
44 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
45 },
46 {
47 .pwrdm_name = "iva2_pwrdm",
48 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
49 },
50 {
51 .pwrdm_name = "mpu_pwrdm",
52 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
53 },
54 {
55 .pwrdm_name = "wkup_pwrdm",
56 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
57 },
58 { NULL },
59};
60
61/*
62 * 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER
63 */
64static struct pwrdm_dep mpu_34xx_wkdeps[] = {
65 {
66 .pwrdm_name = "core_pwrdm",
67 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
68 },
69 {
70 .pwrdm_name = "iva2_pwrdm",
71 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
72 },
73 {
74 .pwrdm_name = "dss_pwrdm",
75 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
76 },
77 {
78 .pwrdm_name = "per_pwrdm",
79 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
80 },
81 { NULL },
82};
83
84/*
85 * 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER
86 */
87static struct pwrdm_dep iva2_wkdeps[] = {
88 {
89 .pwrdm_name = "core_pwrdm",
90 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
91 },
92 {
93 .pwrdm_name = "mpu_pwrdm",
94 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
95 },
96 {
97 .pwrdm_name = "wkup_pwrdm",
98 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
99 },
100 {
101 .pwrdm_name = "dss_pwrdm",
102 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
103 },
104 {
105 .pwrdm_name = "per_pwrdm",
106 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
107 },
108 { NULL },
109};
110
111
112/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */
113static struct pwrdm_dep cam_dss_wkdeps[] = {
114 {
115 .pwrdm_name = "iva2_pwrdm",
116 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
117 },
118 {
119 .pwrdm_name = "mpu_pwrdm",
120 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
121 },
122 {
123 .pwrdm_name = "wkup_pwrdm",
124 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
125 },
126 { NULL },
127};
128
129/* 3430: PM_WKDEP_NEON: MPU */
130static struct pwrdm_dep neon_wkdeps[] = {
131 {
132 .pwrdm_name = "mpu_pwrdm",
133 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
134 },
135 { NULL },
136};
137
138
139/* Sleep dependency source arrays for 34xx-specific pwrdms - 34XX only */
140
141/*
142 * 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA
143 * 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA
144 */
145static struct pwrdm_dep dss_per_usbhost_sleepdeps[] = {
146 {
147 .pwrdm_name = "mpu_pwrdm",
148 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
149 },
150 {
151 .pwrdm_name = "iva2_pwrdm",
152 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
153 },
154 { NULL },
155};
156
157
158/*
159 * Powerdomains 38 * Powerdomains
160 */ 39 */
161 40
@@ -163,8 +42,6 @@ static struct powerdomain iva2_pwrdm = {
163 .name = "iva2_pwrdm", 42 .name = "iva2_pwrdm",
164 .prcm_offs = OMAP3430_IVA2_MOD, 43 .prcm_offs = OMAP3430_IVA2_MOD,
165 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 44 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
166 .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
167 .wkdep_srcs = iva2_wkdeps,
168 .pwrsts = PWRSTS_OFF_RET_ON, 45 .pwrsts = PWRSTS_OFF_RET_ON,
169 .pwrsts_logic_ret = PWRSTS_OFF_RET, 46 .pwrsts_logic_ret = PWRSTS_OFF_RET,
170 .banks = 4, 47 .banks = 4,
@@ -186,8 +63,6 @@ static struct powerdomain mpu_34xx_pwrdm = {
186 .name = "mpu_pwrdm", 63 .name = "mpu_pwrdm",
187 .prcm_offs = MPU_MOD, 64 .prcm_offs = MPU_MOD,
188 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 65 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
189 .dep_bit = OMAP3430_EN_MPU_SHIFT,
190 .wkdep_srcs = mpu_34xx_wkdeps,
191 .pwrsts = PWRSTS_OFF_RET_ON, 66 .pwrsts = PWRSTS_OFF_RET_ON,
192 .pwrsts_logic_ret = PWRSTS_OFF_RET, 67 .pwrsts_logic_ret = PWRSTS_OFF_RET,
193 .flags = PWRDM_HAS_MPU_QUIRK, 68 .flags = PWRDM_HAS_MPU_QUIRK,
@@ -200,7 +75,6 @@ static struct powerdomain mpu_34xx_pwrdm = {
200 }, 75 },
201}; 76};
202 77
203/* No wkdeps or sleepdeps for 34xx core apparently */
204static struct powerdomain core_34xx_pre_es3_1_pwrdm = { 78static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
205 .name = "core_pwrdm", 79 .name = "core_pwrdm",
206 .prcm_offs = CORE_MOD, 80 .prcm_offs = CORE_MOD,
@@ -208,7 +82,6 @@ static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
208 CHIP_IS_OMAP3430ES2 | 82 CHIP_IS_OMAP3430ES2 |
209 CHIP_IS_OMAP3430ES3_0), 83 CHIP_IS_OMAP3430ES3_0),
210 .pwrsts = PWRSTS_OFF_RET_ON, 84 .pwrsts = PWRSTS_OFF_RET_ON,
211 .dep_bit = OMAP3430_EN_CORE_SHIFT,
212 .banks = 2, 85 .banks = 2,
213 .pwrsts_mem_ret = { 86 .pwrsts_mem_ret = {
214 [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ 87 [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
@@ -220,13 +93,11 @@ static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
220 }, 93 },
221}; 94};
222 95
223/* No wkdeps or sleepdeps for 34xx core apparently */
224static struct powerdomain core_34xx_es3_1_pwrdm = { 96static struct powerdomain core_34xx_es3_1_pwrdm = {
225 .name = "core_pwrdm", 97 .name = "core_pwrdm",
226 .prcm_offs = CORE_MOD, 98 .prcm_offs = CORE_MOD,
227 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3_1), 99 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3_1),
228 .pwrsts = PWRSTS_OFF_RET_ON, 100 .pwrsts = PWRSTS_OFF_RET_ON,
229 .dep_bit = OMAP3430_EN_CORE_SHIFT,
230 .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */ 101 .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
231 .banks = 2, 102 .banks = 2,
232 .pwrsts_mem_ret = { 103 .pwrsts_mem_ret = {
@@ -239,14 +110,10 @@ static struct powerdomain core_34xx_es3_1_pwrdm = {
239 }, 110 },
240}; 111};
241 112
242/* Another case of bit name collisions between several registers: EN_DSS */
243static struct powerdomain dss_pwrdm = { 113static struct powerdomain dss_pwrdm = {
244 .name = "dss_pwrdm", 114 .name = "dss_pwrdm",
245 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 115 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
246 .prcm_offs = OMAP3430_DSS_MOD, 116 .prcm_offs = OMAP3430_DSS_MOD,
247 .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
248 .wkdep_srcs = cam_dss_wkdeps,
249 .sleepdep_srcs = dss_per_usbhost_sleepdeps,
250 .pwrsts = PWRSTS_OFF_RET_ON, 117 .pwrsts = PWRSTS_OFF_RET_ON,
251 .pwrsts_logic_ret = PWRDM_POWER_RET, 118 .pwrsts_logic_ret = PWRDM_POWER_RET,
252 .banks = 1, 119 .banks = 1,
@@ -267,8 +134,6 @@ static struct powerdomain sgx_pwrdm = {
267 .name = "sgx_pwrdm", 134 .name = "sgx_pwrdm",
268 .prcm_offs = OMAP3430ES2_SGX_MOD, 135 .prcm_offs = OMAP3430ES2_SGX_MOD,
269 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2), 136 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
270 .wkdep_srcs = gfx_sgx_wkdeps,
271 .sleepdep_srcs = cam_gfx_sleepdeps,
272 /* XXX This is accurate for 3430 SGX, but what about GFX? */ 137 /* XXX This is accurate for 3430 SGX, but what about GFX? */
273 .pwrsts = PWRSTS_OFF_ON, 138 .pwrsts = PWRSTS_OFF_ON,
274 .pwrsts_logic_ret = PWRDM_POWER_RET, 139 .pwrsts_logic_ret = PWRDM_POWER_RET,
@@ -285,8 +150,6 @@ static struct powerdomain cam_pwrdm = {
285 .name = "cam_pwrdm", 150 .name = "cam_pwrdm",
286 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 151 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
287 .prcm_offs = OMAP3430_CAM_MOD, 152 .prcm_offs = OMAP3430_CAM_MOD,
288 .wkdep_srcs = cam_dss_wkdeps,
289 .sleepdep_srcs = cam_gfx_sleepdeps,
290 .pwrsts = PWRSTS_OFF_RET_ON, 153 .pwrsts = PWRSTS_OFF_RET_ON,
291 .pwrsts_logic_ret = PWRDM_POWER_RET, 154 .pwrsts_logic_ret = PWRDM_POWER_RET,
292 .banks = 1, 155 .banks = 1,
@@ -302,9 +165,6 @@ static struct powerdomain per_pwrdm = {
302 .name = "per_pwrdm", 165 .name = "per_pwrdm",
303 .prcm_offs = OMAP3430_PER_MOD, 166 .prcm_offs = OMAP3430_PER_MOD,
304 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 167 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
305 .dep_bit = OMAP3430_EN_PER_SHIFT,
306 .wkdep_srcs = per_usbhost_wkdeps,
307 .sleepdep_srcs = dss_per_usbhost_sleepdeps,
308 .pwrsts = PWRSTS_OFF_RET_ON, 168 .pwrsts = PWRSTS_OFF_RET_ON,
309 .pwrsts_logic_ret = PWRSTS_OFF_RET, 169 .pwrsts_logic_ret = PWRSTS_OFF_RET,
310 .banks = 1, 170 .banks = 1,
@@ -326,7 +186,6 @@ static struct powerdomain neon_pwrdm = {
326 .name = "neon_pwrdm", 186 .name = "neon_pwrdm",
327 .prcm_offs = OMAP3430_NEON_MOD, 187 .prcm_offs = OMAP3430_NEON_MOD,
328 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 188 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
329 .wkdep_srcs = neon_wkdeps,
330 .pwrsts = PWRSTS_OFF_RET_ON, 189 .pwrsts = PWRSTS_OFF_RET_ON,
331 .pwrsts_logic_ret = PWRDM_POWER_RET, 190 .pwrsts_logic_ret = PWRDM_POWER_RET,
332}; 191};
@@ -335,8 +194,6 @@ static struct powerdomain usbhost_pwrdm = {
335 .name = "usbhost_pwrdm", 194 .name = "usbhost_pwrdm",
336 .prcm_offs = OMAP3430ES2_USBHOST_MOD, 195 .prcm_offs = OMAP3430ES2_USBHOST_MOD,
337 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2), 196 .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
338 .wkdep_srcs = per_usbhost_wkdeps,
339 .sleepdep_srcs = dss_per_usbhost_sleepdeps,
340 .pwrsts = PWRSTS_OFF_RET_ON, 197 .pwrsts = PWRSTS_OFF_RET_ON,
341 .pwrsts_logic_ret = PWRDM_POWER_RET, 198 .pwrsts_logic_ret = PWRDM_POWER_RET,
342 /* 199 /*
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 82ad8f8ad83a..abafd2298ece 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -199,6 +199,18 @@ u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
199 return v; 199 return v;
200} 200}
201 201
202/* Read a PRM register, AND it, and shift the result down to bit 0 */
203u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
204{
205 u32 v;
206
207 v = prm_read_mod_reg(domain, idx);
208 v &= mask;
209 v >>= __ffs(mask);
210
211 return v;
212}
213
202/* Read a register in a CM module */ 214/* Read a register in a CM module */
203u32 cm_read_mod_reg(s16 module, u16 idx) 215u32 cm_read_mod_reg(s16 module, u16 idx)
204{ 216{