added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / arch / arm / mach-omap2 / powerdomain.c
blob73e2971b17573250e7ba4caaf7f7691b51c66266
1 /*
2 * OMAP powerdomain control
4 * Copyright (C) 2007-2008 Texas Instruments, Inc.
5 * Copyright (C) 2007-2008 Nokia Corporation
7 * Written by Paul Walmsley
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
13 #ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN
14 # define DEBUG
15 #endif
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>
27 #include <asm/atomic.h>
29 #include "cm.h"
30 #include "cm-regbits-34xx.h"
31 #include "prm.h"
32 #include "prm-regbits-34xx.h"
34 #include <mach/cpu.h>
35 #include <mach/powerdomain.h>
36 #include <mach/clockdomain.h>
38 /* pwrdm_list contains all registered struct powerdomains */
39 static LIST_HEAD(pwrdm_list);
42 * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to
43 * protect pwrdm_clkdms[] during clkdm add/del ops
45 static DEFINE_RWLOCK(pwrdm_rwlock);
48 /* Private functions */
50 static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
52 u32 v;
54 v = prm_read_mod_reg(domain, idx);
55 v &= mask;
56 v >>= __ffs(mask);
58 return v;
61 static struct powerdomain *_pwrdm_lookup(const char *name)
63 struct powerdomain *pwrdm, *temp_pwrdm;
65 pwrdm = NULL;
67 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
68 if (!strcmp(name, temp_pwrdm->name)) {
69 pwrdm = temp_pwrdm;
70 break;
74 return pwrdm;
77 /* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */
78 static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
79 struct pwrdm_dep *deps)
81 struct pwrdm_dep *pd;
83 if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
84 return ERR_PTR(-EINVAL);
86 for (pd = deps; pd; pd++) {
88 if (!omap_chip_is(pd->omap_chip))
89 continue;
91 if (!pd->pwrdm && pd->pwrdm_name)
92 pd->pwrdm = pwrdm_lookup(pd->pwrdm_name);
94 if (pd->pwrdm == pwrdm)
95 break;
99 if (!pd)
100 return ERR_PTR(-ENOENT);
102 return pd->pwrdm;
106 /* Public functions */
109 * pwrdm_init - set up the powerdomain layer
111 * Loop through the list of powerdomains, registering all that are
112 * available on the current CPU. If pwrdm_list is supplied and not
113 * null, all of the referenced powerdomains will be registered. No
114 * return value.
116 void pwrdm_init(struct powerdomain **pwrdm_list)
118 struct powerdomain **p = NULL;
120 if (pwrdm_list)
121 for (p = pwrdm_list; *p; p++)
122 pwrdm_register(*p);
126 * pwrdm_register - register a powerdomain
127 * @pwrdm: struct powerdomain * to register
129 * Adds a powerdomain to the internal powerdomain list. Returns
130 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
131 * already registered by the provided name, or 0 upon success.
133 int pwrdm_register(struct powerdomain *pwrdm)
135 unsigned long flags;
136 int ret = -EINVAL;
138 if (!pwrdm)
139 return -EINVAL;
141 if (!omap_chip_is(pwrdm->omap_chip))
142 return -EINVAL;
144 write_lock_irqsave(&pwrdm_rwlock, flags);
145 if (_pwrdm_lookup(pwrdm->name)) {
146 ret = -EEXIST;
147 goto pr_unlock;
150 list_add(&pwrdm->node, &pwrdm_list);
152 pr_debug("powerdomain: registered %s\n", pwrdm->name);
153 ret = 0;
155 pr_unlock:
156 write_unlock_irqrestore(&pwrdm_rwlock, flags);
158 return ret;
162 * pwrdm_unregister - unregister a powerdomain
163 * @pwrdm: struct powerdomain * to unregister
165 * Removes a powerdomain from the internal powerdomain list. Returns
166 * -EINVAL if pwrdm argument is NULL.
168 int pwrdm_unregister(struct powerdomain *pwrdm)
170 unsigned long flags;
172 if (!pwrdm)
173 return -EINVAL;
175 write_lock_irqsave(&pwrdm_rwlock, flags);
176 list_del(&pwrdm->node);
177 write_unlock_irqrestore(&pwrdm_rwlock, flags);
179 pr_debug("powerdomain: unregistered %s\n", pwrdm->name);
181 return 0;
185 * pwrdm_lookup - look up a powerdomain by name, return a pointer
186 * @name: name of powerdomain
188 * Find a registered powerdomain by its name. Returns a pointer to the
189 * struct powerdomain if found, or NULL otherwise.
191 struct powerdomain *pwrdm_lookup(const char *name)
193 struct powerdomain *pwrdm;
194 unsigned long flags;
196 if (!name)
197 return NULL;
199 read_lock_irqsave(&pwrdm_rwlock, flags);
200 pwrdm = _pwrdm_lookup(name);
201 read_unlock_irqrestore(&pwrdm_rwlock, flags);
203 return pwrdm;
207 * pwrdm_for_each - call function on each registered clockdomain
208 * @fn: callback function *
210 * Call the supplied function for each registered powerdomain. The
211 * callback function can return anything but 0 to bail out early from
212 * the iterator. The callback function is called with the pwrdm_rwlock
213 * held for reading, so no powerdomain structure manipulation
214 * functions should be called from the callback, although hardware
215 * powerdomain control functions are fine. Returns the last return
216 * value of the callback function, which should be 0 for success or
217 * anything else to indicate failure; or -EINVAL if the function
218 * pointer is null.
220 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
222 struct powerdomain *temp_pwrdm;
223 unsigned long flags;
224 int ret = 0;
226 if (!fn)
227 return -EINVAL;
229 read_lock_irqsave(&pwrdm_rwlock, flags);
230 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
231 ret = (*fn)(temp_pwrdm);
232 if (ret)
233 break;
235 read_unlock_irqrestore(&pwrdm_rwlock, flags);
237 return ret;
241 * pwrdm_add_clkdm - add a clockdomain to a powerdomain
242 * @pwrdm: struct powerdomain * to add the clockdomain to
243 * @clkdm: struct clockdomain * to associate with a powerdomain
245 * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'. This
246 * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
247 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
248 * or 0 upon success.
250 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
252 unsigned long flags;
253 int i;
254 int ret = -EINVAL;
256 if (!pwrdm || !clkdm)
257 return -EINVAL;
259 pr_debug("powerdomain: associating clockdomain %s with powerdomain "
260 "%s\n", clkdm->name, pwrdm->name);
262 write_lock_irqsave(&pwrdm_rwlock, flags);
264 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
265 if (!pwrdm->pwrdm_clkdms[i])
266 break;
267 #ifdef DEBUG
268 if (pwrdm->pwrdm_clkdms[i] == clkdm) {
269 ret = -EINVAL;
270 goto pac_exit;
272 #endif
275 if (i == PWRDM_MAX_CLKDMS) {
276 pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
277 "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
278 WARN_ON(1);
279 ret = -ENOMEM;
280 goto pac_exit;
283 pwrdm->pwrdm_clkdms[i] = clkdm;
285 ret = 0;
287 pac_exit:
288 write_unlock_irqrestore(&pwrdm_rwlock, flags);
290 return ret;
294 * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
295 * @pwrdm: struct powerdomain * to add the clockdomain to
296 * @clkdm: struct clockdomain * to associate with a powerdomain
298 * Dissociate the clockdomain 'clkdm' from the powerdomain
299 * 'pwrdm'. Returns -EINVAL if presented with invalid pointers;
300 * -ENOENT if the clkdm was not associated with the powerdomain, or 0
301 * upon success.
303 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
305 unsigned long flags;
306 int ret = -EINVAL;
307 int i;
309 if (!pwrdm || !clkdm)
310 return -EINVAL;
312 pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
313 "%s\n", clkdm->name, pwrdm->name);
315 write_lock_irqsave(&pwrdm_rwlock, flags);
317 for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
318 if (pwrdm->pwrdm_clkdms[i] == clkdm)
319 break;
321 if (i == PWRDM_MAX_CLKDMS) {
322 pr_debug("powerdomain: clkdm %s not associated with pwrdm "
323 "%s ?!\n", clkdm->name, pwrdm->name);
324 ret = -ENOENT;
325 goto pdc_exit;
328 pwrdm->pwrdm_clkdms[i] = NULL;
330 ret = 0;
332 pdc_exit:
333 write_unlock_irqrestore(&pwrdm_rwlock, flags);
335 return ret;
339 * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
340 * @pwrdm: struct powerdomain * to iterate over
341 * @fn: callback function *
343 * Call the supplied function for each clockdomain in the powerdomain
344 * 'pwrdm'. The callback function can return anything but 0 to bail
345 * out early from the iterator. The callback function is called with
346 * the pwrdm_rwlock held for reading, so no powerdomain structure
347 * manipulation functions should be called from the callback, although
348 * hardware powerdomain control functions are fine. Returns -EINVAL
349 * if presented with invalid pointers; or passes along the last return
350 * value of the callback function, which should be 0 for success or
351 * anything else to indicate failure.
353 int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
354 int (*fn)(struct powerdomain *pwrdm,
355 struct clockdomain *clkdm))
357 unsigned long flags;
358 int ret = 0;
359 int i;
361 if (!fn)
362 return -EINVAL;
364 read_lock_irqsave(&pwrdm_rwlock, flags);
366 for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
367 ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
369 read_unlock_irqrestore(&pwrdm_rwlock, flags);
371 return ret;
376 * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
377 * @pwrdm1: wake this struct powerdomain * up (dependent)
378 * @pwrdm2: when this struct powerdomain * wakes up (source)
380 * When the powerdomain represented by pwrdm2 wakes up (due to an
381 * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP,
382 * this feature is designed to reduce wakeup latency of the dependent
383 * powerdomain. Returns -EINVAL if presented with invalid powerdomain
384 * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
385 * 0 upon success.
387 int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
389 struct powerdomain *p;
391 if (!pwrdm1)
392 return -EINVAL;
394 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
395 if (IS_ERR(p)) {
396 pr_debug("powerdomain: hardware cannot set/clear wake up of "
397 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
398 return IS_ERR(p);
401 pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
402 pwrdm1->name, pwrdm2->name);
404 prm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
405 pwrdm1->prcm_offs, PM_WKDEP);
407 return 0;
411 * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1
412 * @pwrdm1: wake this struct powerdomain * up (dependent)
413 * @pwrdm2: when this struct powerdomain * wakes up (source)
415 * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2
416 * wakes up. Returns -EINVAL if presented with invalid powerdomain
417 * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
418 * 0 upon success.
420 int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
422 struct powerdomain *p;
424 if (!pwrdm1)
425 return -EINVAL;
427 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
428 if (IS_ERR(p)) {
429 pr_debug("powerdomain: hardware cannot set/clear wake up of "
430 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
431 return IS_ERR(p);
434 pr_debug("powerdomain: hardware will no longer wake up %s after %s "
435 "wakes up\n", pwrdm1->name, pwrdm2->name);
437 prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
438 pwrdm1->prcm_offs, PM_WKDEP);
440 return 0;
444 * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1
445 * @pwrdm1: wake this struct powerdomain * up (dependent)
446 * @pwrdm2: when this struct powerdomain * wakes up (source)
448 * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be
449 * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL
450 * if either powerdomain pointer is invalid; or -ENOENT if the hardware
451 * is incapable.
453 * REVISIT: Currently this function only represents software-controllable
454 * wakeup dependencies. Wakeup dependencies fixed in hardware are not
455 * yet handled here.
457 int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
459 struct powerdomain *p;
461 if (!pwrdm1)
462 return -EINVAL;
464 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
465 if (IS_ERR(p)) {
466 pr_debug("powerdomain: hardware cannot set/clear wake up of "
467 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
468 return IS_ERR(p);
471 return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
472 (1 << pwrdm2->dep_bit));
476 * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1
477 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
478 * @pwrdm2: when this struct powerdomain * is active (source)
480 * Prevent pwrdm1 from automatically going inactive (and then to
481 * retention or off) if pwrdm2 is still active. Returns -EINVAL if
482 * presented with invalid powerdomain pointers or called on a machine
483 * that does not support software-configurable hardware sleep dependencies,
484 * -ENOENT if the specified dependency cannot be set in hardware, or
485 * 0 upon success.
487 int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
489 struct powerdomain *p;
491 if (!pwrdm1)
492 return -EINVAL;
494 if (!cpu_is_omap34xx())
495 return -EINVAL;
497 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
498 if (IS_ERR(p)) {
499 pr_debug("powerdomain: hardware cannot set/clear sleep "
500 "dependency affecting %s from %s\n", pwrdm1->name,
501 pwrdm2->name);
502 return IS_ERR(p);
505 pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
506 pwrdm1->name, pwrdm2->name);
508 cm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
509 pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
511 return 0;
515 * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1
516 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
517 * @pwrdm2: when this struct powerdomain * is active (source)
519 * Allow pwrdm1 to automatically go inactive (and then to retention or
520 * off), independent of the activity state of pwrdm2. Returns -EINVAL
521 * if presented with invalid powerdomain pointers or called on a machine
522 * that does not support software-configurable hardware sleep dependencies,
523 * -ENOENT if the specified dependency cannot be cleared in hardware, or
524 * 0 upon success.
526 int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
528 struct powerdomain *p;
530 if (!pwrdm1)
531 return -EINVAL;
533 if (!cpu_is_omap34xx())
534 return -EINVAL;
536 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
537 if (IS_ERR(p)) {
538 pr_debug("powerdomain: hardware cannot set/clear sleep "
539 "dependency affecting %s from %s\n", pwrdm1->name,
540 pwrdm2->name);
541 return IS_ERR(p);
544 pr_debug("powerdomain: will no longer prevent %s from sleeping if "
545 "%s is active\n", pwrdm1->name, pwrdm2->name);
547 cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
548 pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
550 return 0;
554 * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1
555 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
556 * @pwrdm2: when this struct powerdomain * is active (source)
558 * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will
559 * not be allowed to automatically go inactive if pwrdm2 is active;
560 * 0 if pwrdm1's automatic power state inactivity transition is independent
561 * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called
562 * on a machine that does not support software-configurable hardware sleep
563 * dependencies; or -ENOENT if the hardware is incapable.
565 * REVISIT: Currently this function only represents software-controllable
566 * sleep dependencies. Sleep dependencies fixed in hardware are not
567 * yet handled here.
569 int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
571 struct powerdomain *p;
573 if (!pwrdm1)
574 return -EINVAL;
576 if (!cpu_is_omap34xx())
577 return -EINVAL;
579 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
580 if (IS_ERR(p)) {
581 pr_debug("powerdomain: hardware cannot set/clear sleep "
582 "dependency affecting %s from %s\n", pwrdm1->name,
583 pwrdm2->name);
584 return IS_ERR(p);
587 return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
588 (1 << pwrdm2->dep_bit));
592 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
593 * @pwrdm: struct powerdomain *
595 * Return the number of controllable memory banks in powerdomain pwrdm,
596 * starting with 1. Returns -EINVAL if the powerdomain pointer is null.
598 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
600 if (!pwrdm)
601 return -EINVAL;
603 return pwrdm->banks;
607 * pwrdm_set_next_pwrst - set next powerdomain power state
608 * @pwrdm: struct powerdomain * to set
609 * @pwrst: one of the PWRDM_POWER_* macros
611 * Set the powerdomain pwrdm's next power state to pwrst. The powerdomain
612 * may not enter this state immediately if the preconditions for this state
613 * have not been satisfied. Returns -EINVAL if the powerdomain pointer is
614 * null or if the power state is invalid for the powerdomin, or returns 0
615 * upon success.
617 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
619 if (!pwrdm)
620 return -EINVAL;
622 if (!(pwrdm->pwrsts & (1 << pwrst)))
623 return -EINVAL;
625 pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
626 pwrdm->name, pwrst);
628 prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
629 (pwrst << OMAP_POWERSTATE_SHIFT),
630 pwrdm->prcm_offs, PM_PWSTCTRL);
632 return 0;
636 * pwrdm_read_next_pwrst - get next powerdomain power state
637 * @pwrdm: struct powerdomain * to get power state
639 * Return the powerdomain pwrdm's next power state. Returns -EINVAL
640 * if the powerdomain pointer is null or returns the next power state
641 * upon success.
643 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
645 if (!pwrdm)
646 return -EINVAL;
648 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
649 OMAP_POWERSTATE_MASK);
653 * pwrdm_read_pwrst - get current powerdomain power state
654 * @pwrdm: struct powerdomain * to get power state
656 * Return the powerdomain pwrdm's current power state. Returns -EINVAL
657 * if the powerdomain pointer is null or returns the current power state
658 * upon success.
660 int pwrdm_read_pwrst(struct powerdomain *pwrdm)
662 if (!pwrdm)
663 return -EINVAL;
665 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
666 OMAP_POWERSTATEST_MASK);
670 * pwrdm_read_prev_pwrst - get previous powerdomain power state
671 * @pwrdm: struct powerdomain * to get previous power state
673 * Return the powerdomain pwrdm's previous power state. Returns -EINVAL
674 * if the powerdomain pointer is null or returns the previous power state
675 * upon success.
677 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
679 if (!pwrdm)
680 return -EINVAL;
682 return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
683 OMAP3430_LASTPOWERSTATEENTERED_MASK);
687 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
688 * @pwrdm: struct powerdomain * to set
689 * @pwrst: one of the PWRDM_POWER_* macros
691 * Set the next power state that the logic portion of the powerdomain
692 * pwrdm will enter when the powerdomain enters retention. This will
693 * be either RETENTION or OFF, if supported. Returns -EINVAL if the
694 * powerdomain pointer is null or the target power state is not not
695 * supported, or returns 0 upon success.
697 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
699 if (!pwrdm)
700 return -EINVAL;
702 if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
703 return -EINVAL;
705 pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
706 pwrdm->name, pwrst);
709 * The register bit names below may not correspond to the
710 * actual names of the bits in each powerdomain's register,
711 * but the type of value returned is the same for each
712 * powerdomain.
714 prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE,
715 (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)),
716 pwrdm->prcm_offs, PM_PWSTCTRL);
718 return 0;
722 * pwrdm_set_mem_onst - set memory power state while powerdomain ON
723 * @pwrdm: struct powerdomain * to set
724 * @bank: memory bank number to set (0-3)
725 * @pwrst: one of the PWRDM_POWER_* macros
727 * Set the next power state that memory bank x of the powerdomain
728 * pwrdm will enter when the powerdomain enters the ON state. Bank
729 * will be a number from 0 to 3, and represents different types of
730 * memory, depending on the powerdomain. Returns -EINVAL if the
731 * powerdomain pointer is null or the target power state is not not
732 * supported for this memory bank, -EEXIST if the target memory bank
733 * does not exist or is not controllable, or returns 0 upon success.
735 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
737 u32 m;
739 if (!pwrdm)
740 return -EINVAL;
742 if (pwrdm->banks < (bank + 1))
743 return -EEXIST;
745 if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
746 return -EINVAL;
748 pr_debug("powerdomain: setting next memory powerstate for domain %s "
749 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
752 * The register bit names below may not correspond to the
753 * actual names of the bits in each powerdomain's register,
754 * but the type of value returned is the same for each
755 * powerdomain.
757 switch (bank) {
758 case 0:
759 m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK;
760 break;
761 case 1:
762 m = OMAP3430_L1FLATMEMONSTATE_MASK;
763 break;
764 case 2:
765 m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK;
766 break;
767 case 3:
768 m = OMAP3430_L2FLATMEMONSTATE_MASK;
769 break;
770 default:
771 WARN_ON(1); /* should never happen */
772 return -EEXIST;
775 prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
776 pwrdm->prcm_offs, PM_PWSTCTRL);
778 return 0;
782 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
783 * @pwrdm: struct powerdomain * to set
784 * @bank: memory bank number to set (0-3)
785 * @pwrst: one of the PWRDM_POWER_* macros
787 * Set the next power state that memory bank x of the powerdomain
788 * pwrdm will enter when the powerdomain enters the RETENTION state.
789 * Bank will be a number from 0 to 3, and represents different types
790 * of memory, depending on the powerdomain. pwrst will be either
791 * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain
792 * pointer is null or the target power state is not not supported for
793 * this memory bank, -EEXIST if the target memory bank does not exist
794 * or is not controllable, or returns 0 upon success.
796 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
798 u32 m;
800 if (!pwrdm)
801 return -EINVAL;
803 if (pwrdm->banks < (bank + 1))
804 return -EEXIST;
806 if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
807 return -EINVAL;
809 pr_debug("powerdomain: setting next memory powerstate for domain %s "
810 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
813 * The register bit names below may not correspond to the
814 * actual names of the bits in each powerdomain's register,
815 * but the type of value returned is the same for each
816 * powerdomain.
818 switch (bank) {
819 case 0:
820 m = OMAP3430_SHAREDL1CACHEFLATRETSTATE;
821 break;
822 case 1:
823 m = OMAP3430_L1FLATMEMRETSTATE;
824 break;
825 case 2:
826 m = OMAP3430_SHAREDL2CACHEFLATRETSTATE;
827 break;
828 case 3:
829 m = OMAP3430_L2FLATMEMRETSTATE;
830 break;
831 default:
832 WARN_ON(1); /* should never happen */
833 return -EEXIST;
836 prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
837 PM_PWSTCTRL);
839 return 0;
843 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
844 * @pwrdm: struct powerdomain * to get current logic retention power state
846 * Return the current power state that the logic portion of
847 * powerdomain pwrdm will enter
848 * Returns -EINVAL if the powerdomain pointer is null or returns the
849 * current logic retention power state upon success.
851 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
853 if (!pwrdm)
854 return -EINVAL;
856 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
857 OMAP3430_LOGICSTATEST);
861 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
862 * @pwrdm: struct powerdomain * to get previous logic power state
864 * Return the powerdomain pwrdm's logic power state. Returns -EINVAL
865 * if the powerdomain pointer is null or returns the previous logic
866 * power state upon success.
868 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
870 if (!pwrdm)
871 return -EINVAL;
874 * The register bit names below may not correspond to the
875 * actual names of the bits in each powerdomain's register,
876 * but the type of value returned is the same for each
877 * powerdomain.
879 return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
880 OMAP3430_LASTLOGICSTATEENTERED);
884 * pwrdm_read_mem_pwrst - get current memory bank power state
885 * @pwrdm: struct powerdomain * to get current memory bank power state
886 * @bank: memory bank number (0-3)
888 * Return the powerdomain pwrdm's current memory power state for bank
889 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
890 * the target memory bank does not exist or is not controllable, or
891 * returns the current memory power state upon success.
893 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
895 u32 m;
897 if (!pwrdm)
898 return -EINVAL;
900 if (pwrdm->banks < (bank + 1))
901 return -EEXIST;
904 * The register bit names below may not correspond to the
905 * actual names of the bits in each powerdomain's register,
906 * but the type of value returned is the same for each
907 * powerdomain.
909 switch (bank) {
910 case 0:
911 m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK;
912 break;
913 case 1:
914 m = OMAP3430_L1FLATMEMSTATEST_MASK;
915 break;
916 case 2:
917 m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK;
918 break;
919 case 3:
920 m = OMAP3430_L2FLATMEMSTATEST_MASK;
921 break;
922 default:
923 WARN_ON(1); /* should never happen */
924 return -EEXIST;
927 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m);
931 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
932 * @pwrdm: struct powerdomain * to get previous memory bank power state
933 * @bank: memory bank number (0-3)
935 * Return the powerdomain pwrdm's previous memory power state for bank
936 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
937 * the target memory bank does not exist or is not controllable, or
938 * returns the previous memory power state upon success.
940 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
942 u32 m;
944 if (!pwrdm)
945 return -EINVAL;
947 if (pwrdm->banks < (bank + 1))
948 return -EEXIST;
951 * The register bit names below may not correspond to the
952 * actual names of the bits in each powerdomain's register,
953 * but the type of value returned is the same for each
954 * powerdomain.
956 switch (bank) {
957 case 0:
958 m = OMAP3430_LASTMEM1STATEENTERED_MASK;
959 break;
960 case 1:
961 m = OMAP3430_LASTMEM2STATEENTERED_MASK;
962 break;
963 case 2:
964 m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
965 break;
966 case 3:
967 m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
968 break;
969 default:
970 WARN_ON(1); /* should never happen */
971 return -EEXIST;
974 return prm_read_mod_bits_shift(pwrdm->prcm_offs,
975 OMAP3430_PM_PREPWSTST, m);
979 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
980 * @pwrdm: struct powerdomain * to clear
982 * Clear the powerdomain's previous power state register. Clears the
983 * entire register, including logic and memory bank previous power states.
984 * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon
985 * success.
987 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
989 if (!pwrdm)
990 return -EINVAL;
993 * XXX should get the powerdomain's current state here;
994 * warn & fail if it is not ON.
997 pr_debug("powerdomain: clearing previous power state reg for %s\n",
998 pwrdm->name);
1000 prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
1002 return 0;
1006 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
1007 * @pwrdm: struct powerdomain *
1009 * Enable automatic context save-and-restore upon power state change
1010 * for some devices in a powerdomain. Warning: this only affects a
1011 * subset of devices in a powerdomain; check the TRM closely. Returns
1012 * -EINVAL if the powerdomain pointer is null or if the powerdomain
1013 * does not support automatic save-and-restore, or returns 0 upon
1014 * success.
1016 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
1018 if (!pwrdm)
1019 return -EINVAL;
1021 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
1022 return -EINVAL;
1024 pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
1025 pwrdm->name);
1027 prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
1028 pwrdm->prcm_offs, PM_PWSTCTRL);
1030 return 0;
1034 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
1035 * @pwrdm: struct powerdomain *
1037 * Disable automatic context save-and-restore upon power state change
1038 * for some devices in a powerdomain. Warning: this only affects a
1039 * subset of devices in a powerdomain; check the TRM closely. Returns
1040 * -EINVAL if the powerdomain pointer is null or if the powerdomain
1041 * does not support automatic save-and-restore, or returns 0 upon
1042 * success.
1044 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
1046 if (!pwrdm)
1047 return -EINVAL;
1049 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
1050 return -EINVAL;
1052 pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
1053 pwrdm->name);
1055 prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0,
1056 pwrdm->prcm_offs, PM_PWSTCTRL);
1058 return 0;
1062 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
1063 * @pwrdm: struct powerdomain *
1065 * Returns 1 if powerdomain 'pwrdm' supports hardware save-and-restore
1066 * for some devices, or 0 if it does not.
1068 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
1070 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
1074 * pwrdm_wait_transition - wait for powerdomain power transition to finish
1075 * @pwrdm: struct powerdomain * to wait for
1077 * If the powerdomain pwrdm is in the process of a state transition,
1078 * spin until it completes the power transition, or until an iteration
1079 * bailout value is reached. Returns -EINVAL if the powerdomain
1080 * pointer is null, -EAGAIN if the bailout value was reached, or
1081 * returns 0 upon success.
1083 int pwrdm_wait_transition(struct powerdomain *pwrdm)
1085 u32 c = 0;
1087 if (!pwrdm)
1088 return -EINVAL;
1091 * REVISIT: pwrdm_wait_transition() may be better implemented
1092 * via a callback and a periodic timer check -- how long do we expect
1093 * powerdomain transitions to take?
1096 /* XXX Is this udelay() value meaningful? */
1097 while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) &
1098 OMAP_INTRANSITION) &&
1099 (c++ < PWRDM_TRANSITION_BAILOUT))
1100 udelay(1);
1102 if (c >= PWRDM_TRANSITION_BAILOUT) {
1103 printk(KERN_ERR "powerdomain: waited too long for "
1104 "powerdomain %s to complete transition\n", pwrdm->name);
1105 return -EAGAIN;
1108 pr_debug("powerdomain: completed transition in %d loops\n", c);
1110 return 0;