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
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/delay.h>
21 #include <linux/mutex.h>
22 #include <linux/list.h>
23 #include <linux/errno.h>
24 #include <linux/err.h>
26 #include <asm/atomic.h>
29 #include "cm-regbits-34xx.h"
31 #include "prm-regbits-34xx.h"
33 #include <asm/arch/cpu.h>
34 #include <asm/arch/powerdomain.h>
35 #include <asm/arch/clockdomain.h>
37 /* pwrdm_list contains all registered struct powerdomains */
38 static LIST_HEAD(pwrdm_list);
40 /* pwrdm_mutex protects pwrdm_list add and del ops */
41 static DEFINE_MUTEX(pwrdm_mutex);
43 /* Private functions */
45 static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
49 v = prm_read_mod_reg(domain, idx);
56 static struct powerdomain *_pwrdm_lookup(const char *name)
58 struct powerdomain *pwrdm, *temp_pwrdm;
62 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
63 if (!strcmp(name, temp_pwrdm->name)) {
72 /* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */
73 static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
74 struct pwrdm_dep *deps)
78 if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
79 return ERR_PTR(-EINVAL);
81 for (pd = deps; pd; pd++) {
83 if (!omap_chip_is(pd->omap_chip))
86 if (!pd->pwrdm && pd->pwrdm_name)
87 pd->pwrdm = pwrdm_lookup(pd->pwrdm_name);
89 if (pd->pwrdm == pwrdm)
95 return ERR_PTR(-ENOENT);
101 /* Public functions */
104 * pwrdm_init - set up the powerdomain layer
106 * Loop through the list of powerdomains, registering all that are
107 * available on the current CPU. If pwrdm_list is supplied and not
108 * null, all of the referenced powerdomains will be registered. No
111 void pwrdm_init(struct powerdomain **pwrdm_list)
113 struct powerdomain **p = NULL;
116 for (p = pwrdm_list; *p; p++)
121 * pwrdm_register - register a powerdomain
122 * @pwrdm: struct powerdomain * to register
124 * Adds a powerdomain to the internal powerdomain list. Returns
125 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
126 * already registered by the provided name, or 0 upon success.
128 int pwrdm_register(struct powerdomain *pwrdm)
135 if (!omap_chip_is(pwrdm->omap_chip))
138 mutex_lock(&pwrdm_mutex);
139 if (_pwrdm_lookup(pwrdm->name)) {
144 list_add(&pwrdm->node, &pwrdm_list);
146 pr_debug("powerdomain: registered %s\n", pwrdm->name);
150 mutex_unlock(&pwrdm_mutex);
156 * pwrdm_unregister - unregister a powerdomain
157 * @pwrdm: struct powerdomain * to unregister
159 * Removes a powerdomain from the internal powerdomain list. Returns
160 * -EINVAL if pwrdm argument is NULL.
162 int pwrdm_unregister(struct powerdomain *pwrdm)
167 mutex_lock(&pwrdm_mutex);
168 list_del(&pwrdm->node);
169 mutex_unlock(&pwrdm_mutex);
171 pr_debug("powerdomain: unregistered %s\n", pwrdm->name);
177 * pwrdm_lookup - look up a powerdomain by name, return a pointer
178 * @name: name of powerdomain
180 * Find a registered powerdomain by its name. Returns a pointer to the
181 * struct powerdomain if found, or NULL otherwise.
183 struct powerdomain *pwrdm_lookup(const char *name)
185 struct powerdomain *pwrdm;
190 mutex_lock(&pwrdm_mutex);
191 pwrdm = _pwrdm_lookup(name);
192 mutex_unlock(&pwrdm_mutex);
198 * pwrdm_for_each - call function on each registered clockdomain
199 * @fn: callback function *
201 * Call the supplied function for each registered powerdomain.
202 * The callback function can return anything but 0 to bail
203 * out early from the iterator. The callback function is called with
204 * the pwrdm_mutex held, so no powerdomain structure manipulation
205 * functions should be called from the callback, although hardware
206 * powerdomain control functions are fine. Returns the last return
207 * value of the callback function, which should be 0 for success or
208 * anything else to indicate failure; or -EINVAL if the function pointer
211 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
213 struct powerdomain *temp_pwrdm;
219 mutex_lock(&pwrdm_mutex);
220 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
221 ret = (*fn)(temp_pwrdm);
225 mutex_unlock(&pwrdm_mutex);
231 * pwrdm_add_clkdm - add a clockdomain to a powerdomain
232 * @pwrdm: struct powerdomain * to add the clockdomain to
233 * @clkdm: struct clockdomain * to associate with a powerdomain
235 * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'. This
236 * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
237 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
240 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
245 if (!pwrdm || !clkdm)
248 pr_debug("powerdomain: associating clockdomain %s with powerdomain "
249 "%s\n", clkdm->name, pwrdm->name);
250 mutex_lock(&pwrdm_mutex);
252 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
253 if (!pwrdm->pwrdm_clkdms[i])
256 if (pwrdm->pwrdm_clkdms[i] == clkdm) {
263 if (i == PWRDM_MAX_CLKDMS) {
264 pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
265 "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
271 pwrdm->pwrdm_clkdms[i] = clkdm;
276 mutex_unlock(&pwrdm_mutex);
282 * pwrdm_del_clkdm - remove a clockdomain to a powerdomain
283 * @pwrdm: struct powerdomain * to add the clockdomain to
284 * @clkdm: struct clockdomain * to associate with a powerdomain
286 * Dissociate the clockdomain 'clkdm' from the powerdomain
287 * 'pwrdm'. Returns -EINVAL if presented with invalid pointers;
288 * -ENOENT if the clkdm was not associated with the powerdomain, or 0
291 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
296 if (!pwrdm || !clkdm)
299 pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
300 "%s\n", clkdm->name, pwrdm->name);
302 mutex_lock(&pwrdm_mutex);
304 for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
305 if (pwrdm->pwrdm_clkdms[i] == clkdm)
308 if (i == PWRDM_MAX_CLKDMS) {
309 pr_debug("powerdomain: clkdm %s not associated with pwrdm "
310 "%s ?!\n", clkdm->name, pwrdm->name);
315 pwrdm->pwrdm_clkdms[i] = NULL;
320 mutex_unlock(&pwrdm_mutex);
326 * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
327 * @pwrdm: struct powerdomain * to iterate over
328 * @fn: callback function *
330 * Call the supplied function for each clockdomain in the powerdomain
331 * 'pwrdm'. The callback function can return anything but 0 to bail
332 * out early from the iterator. The callback function is called with
333 * the pwrdm_mutex held, so no powerdomain structure manipulation
334 * functions should be called from the callback, although hardware
335 * powerdomain control functions are fine. Returns -EINVAL if
336 * presented with invalid pointers; or passes along the last return
337 * value of the callback function, which should be 0 for success or
338 * anything else to indicate failure.
340 int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
341 int (*fn)(struct powerdomain *pwrdm,
342 struct clockdomain *clkdm))
350 mutex_lock(&pwrdm_mutex);
352 for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
353 ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
355 mutex_unlock(&pwrdm_mutex);
362 * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
363 * @pwrdm1: wake this struct powerdomain * up (dependent)
364 * @pwrdm2: when this struct powerdomain * wakes up (source)
366 * When the powerdomain represented by pwrdm2 wakes up (due to an
367 * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP,
368 * this feature is designed to reduce wakeup latency of the dependent
369 * powerdomain. Returns -EINVAL if presented with invalid powerdomain
370 * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
373 int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
375 struct powerdomain *p;
380 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
382 pr_debug("powerdomain: hardware cannot set/clear wake up of "
383 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
387 pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
388 pwrdm1->name, pwrdm2->name);
390 prm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
391 pwrdm1->prcm_offs, PM_WKDEP);
397 * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1
398 * @pwrdm1: wake this struct powerdomain * up (dependent)
399 * @pwrdm2: when this struct powerdomain * wakes up (source)
401 * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2
402 * wakes up. Returns -EINVAL if presented with invalid powerdomain
403 * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
406 int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
408 struct powerdomain *p;
413 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
415 pr_debug("powerdomain: hardware cannot set/clear wake up of "
416 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
420 pr_debug("powerdomain: hardware will no longer wake up %s after %s "
421 "wakes up\n", pwrdm1->name, pwrdm2->name);
423 prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
424 pwrdm1->prcm_offs, PM_WKDEP);
430 * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1
431 * @pwrdm1: wake this struct powerdomain * up (dependent)
432 * @pwrdm2: when this struct powerdomain * wakes up (source)
434 * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be
435 * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL
436 * if either powerdomain pointer is invalid; or -ENOENT if the hardware
439 * REVISIT: Currently this function only represents software-controllable
440 * wakeup dependencies. Wakeup dependencies fixed in hardware are not
443 int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
445 struct powerdomain *p;
450 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
452 pr_debug("powerdomain: hardware cannot set/clear wake up of "
453 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
457 return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
458 (1 << pwrdm2->dep_bit));
462 * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1
463 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
464 * @pwrdm2: when this struct powerdomain * is active (source)
466 * Prevent pwrdm1 from automatically going inactive (and then to
467 * retention or off) if pwrdm2 is still active. Returns -EINVAL if
468 * presented with invalid powerdomain pointers or called on a machine
469 * that does not support software-configurable hardware sleep dependencies,
470 * -ENOENT if the specified dependency cannot be set in hardware, or
473 int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
475 struct powerdomain *p;
480 if (!cpu_is_omap34xx())
483 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
485 pr_debug("powerdomain: hardware cannot set/clear sleep "
486 "dependency affecting %s from %s\n", pwrdm1->name,
491 pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
492 pwrdm1->name, pwrdm2->name);
494 cm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
495 pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
501 * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1
502 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
503 * @pwrdm2: when this struct powerdomain * is active (source)
505 * Allow pwrdm1 to automatically go inactive (and then to retention or
506 * off), independent of the activity state of pwrdm2. Returns -EINVAL
507 * if presented with invalid powerdomain pointers or called on a machine
508 * that does not support software-configurable hardware sleep dependencies,
509 * -ENOENT if the specified dependency cannot be cleared in hardware, or
512 int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
514 struct powerdomain *p;
519 if (!cpu_is_omap34xx())
522 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
524 pr_debug("powerdomain: hardware cannot set/clear sleep "
525 "dependency affecting %s from %s\n", pwrdm1->name,
530 pr_debug("powerdomain: will no longer prevent %s from sleeping if "
531 "%s is active\n", pwrdm1->name, pwrdm2->name);
533 cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
534 pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
540 * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1
541 * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
542 * @pwrdm2: when this struct powerdomain * is active (source)
544 * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will
545 * not be allowed to automatically go inactive if pwrdm2 is active;
546 * 0 if pwrdm1's automatic power state inactivity transition is independent
547 * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called
548 * on a machine that does not support software-configurable hardware sleep
549 * dependencies; or -ENOENT if the hardware is incapable.
551 * REVISIT: Currently this function only represents software-controllable
552 * sleep dependencies. Sleep dependencies fixed in hardware are not
555 int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
557 struct powerdomain *p;
562 if (!cpu_is_omap34xx())
565 p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
567 pr_debug("powerdomain: hardware cannot set/clear sleep "
568 "dependency affecting %s from %s\n", pwrdm1->name,
573 return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
574 (1 << pwrdm2->dep_bit));
579 * pwrdm_set_next_pwrst - set next powerdomain power state
580 * @pwrdm: struct powerdomain * to set
581 * @pwrst: one of the PWRDM_POWER_* macros
583 * Set the powerdomain pwrdm's next power state to pwrst. The powerdomain
584 * may not enter this state immediately if the preconditions for this state
585 * have not been satisfied. Returns -EINVAL if the powerdomain pointer is
586 * null or if the power state is invalid for the powerdomin, or returns 0
589 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
594 if (!(pwrdm->pwrsts & (1 << pwrst)))
597 pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
600 prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
601 (pwrst << OMAP_POWERSTATE_SHIFT),
602 pwrdm->prcm_offs, PM_PWSTCTRL);
608 * pwrdm_read_next_pwrst - get next powerdomain power state
609 * @pwrdm: struct powerdomain * to get power state
611 * Return the powerdomain pwrdm's next power state. Returns -EINVAL
612 * if the powerdomain pointer is null or returns the next power state
615 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
620 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
621 OMAP_POWERSTATE_MASK);
625 * pwrdm_read_pwrst - get current powerdomain power state
626 * @pwrdm: struct powerdomain * to get power state
628 * Return the powerdomain pwrdm's current power state. Returns -EINVAL
629 * if the powerdomain pointer is null or returns the current power state
632 int pwrdm_read_pwrst(struct powerdomain *pwrdm)
637 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
638 OMAP_POWERSTATEST_MASK);
642 * pwrdm_read_prev_pwrst - get previous powerdomain power state
643 * @pwrdm: struct powerdomain * to get previous power state
645 * Return the powerdomain pwrdm's previous power state. Returns -EINVAL
646 * if the powerdomain pointer is null or returns the previous power state
649 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
654 return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
655 OMAP3430_LASTPOWERSTATEENTERED_MASK);
659 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
660 * @pwrdm: struct powerdomain * to set
661 * @pwrst: one of the PWRDM_POWER_* macros
663 * Set the next power state that the logic portion of the powerdomain
664 * pwrdm will enter when the powerdomain enters retention. This will
665 * be either RETENTION or OFF, if supported. Returns -EINVAL if the
666 * powerdomain pointer is null or the target power state is not not
667 * supported, or returns 0 upon success.
669 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
674 if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
677 pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
681 * The register bit names below may not correspond to the
682 * actual names of the bits in each powerdomain's register,
683 * but the type of value returned is the same for each
686 prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE,
687 (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)),
688 pwrdm->prcm_offs, PM_PWSTCTRL);
694 * pwrdm_set_mem_onst - set memory power state while powerdomain ON
695 * @pwrdm: struct powerdomain * to set
696 * @bank: memory bank number to set (0-3)
697 * @pwrst: one of the PWRDM_POWER_* macros
699 * Set the next power state that memory bank x of the powerdomain
700 * pwrdm will enter when the powerdomain enters the ON state. Bank
701 * will be a number from 0 to 3, and represents different types of
702 * memory, depending on the powerdomain. Returns -EINVAL if the
703 * powerdomain pointer is null or the target power state is not not
704 * supported for this memory bank, -EEXIST if the target memory bank
705 * does not exist or is not controllable, or returns 0 upon success.
707 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
714 if (pwrdm->banks < (bank + 1))
717 if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
720 pr_debug("powerdomain: setting next memory powerstate for domain %s "
721 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
724 * The register bit names below may not correspond to the
725 * actual names of the bits in each powerdomain's register,
726 * but the type of value returned is the same for each
731 m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK;
734 m = OMAP3430_L1FLATMEMONSTATE_MASK;
737 m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK;
740 m = OMAP3430_L2FLATMEMONSTATE_MASK;
743 WARN_ON(1); /* should never happen */
747 prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
748 pwrdm->prcm_offs, PM_PWSTCTRL);
754 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
755 * @pwrdm: struct powerdomain * to set
756 * @bank: memory bank number to set (0-3)
757 * @pwrst: one of the PWRDM_POWER_* macros
759 * Set the next power state that memory bank x of the powerdomain
760 * pwrdm will enter when the powerdomain enters the RETENTION state.
761 * Bank will be a number from 0 to 3, and represents different types
762 * of memory, depending on the powerdomain. pwrst will be either
763 * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain
764 * pointer is null or the target power state is not not supported for
765 * this memory bank, -EEXIST if the target memory bank does not exist
766 * or is not controllable, or returns 0 upon success.
768 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
775 if (pwrdm->banks < (bank + 1))
778 if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
781 pr_debug("powerdomain: setting next memory powerstate for domain %s "
782 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
785 * The register bit names below may not correspond to the
786 * actual names of the bits in each powerdomain's register,
787 * but the type of value returned is the same for each
792 m = OMAP3430_SHAREDL1CACHEFLATRETSTATE;
795 m = OMAP3430_L1FLATMEMRETSTATE;
798 m = OMAP3430_SHAREDL2CACHEFLATRETSTATE;
801 m = OMAP3430_L2FLATMEMRETSTATE;
804 WARN_ON(1); /* should never happen */
808 prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
815 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
816 * @pwrdm: struct powerdomain * to get current logic retention power state
818 * Return the current power state that the logic portion of
819 * powerdomain pwrdm will enter
820 * Returns -EINVAL if the powerdomain pointer is null or returns the
821 * current logic retention power state upon success.
823 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
828 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
829 OMAP3430_LOGICSTATEST);
833 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
834 * @pwrdm: struct powerdomain * to get previous logic power state
836 * Return the powerdomain pwrdm's logic power state. Returns -EINVAL
837 * if the powerdomain pointer is null or returns the previous logic
838 * power state upon success.
840 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
846 * The register bit names below may not correspond to the
847 * actual names of the bits in each powerdomain's register,
848 * but the type of value returned is the same for each
851 return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
852 OMAP3430_LASTLOGICSTATEENTERED);
856 * pwrdm_read_mem_pwrst - get current memory bank power state
857 * @pwrdm: struct powerdomain * to get current memory bank power state
858 * @bank: memory bank number (0-3)
860 * Return the powerdomain pwrdm's current memory power state for bank
861 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
862 * the target memory bank does not exist or is not controllable, or
863 * returns the current memory power state upon success.
865 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
872 if (pwrdm->banks < (bank + 1))
876 * The register bit names below may not correspond to the
877 * actual names of the bits in each powerdomain's register,
878 * but the type of value returned is the same for each
883 m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK;
886 m = OMAP3430_L1FLATMEMSTATEST_MASK;
889 m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK;
892 m = OMAP3430_L2FLATMEMSTATEST_MASK;
895 WARN_ON(1); /* should never happen */
899 return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m);
903 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
904 * @pwrdm: struct powerdomain * to get previous memory bank power state
905 * @bank: memory bank number (0-3)
907 * Return the powerdomain pwrdm's previous memory power state for bank
908 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
909 * the target memory bank does not exist or is not controllable, or
910 * returns the previous memory power state upon success.
912 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
919 if (pwrdm->banks < (bank + 1))
923 * The register bit names below may not correspond to the
924 * actual names of the bits in each powerdomain's register,
925 * but the type of value returned is the same for each
930 m = OMAP3430_LASTMEM1STATEENTERED_MASK;
933 m = OMAP3430_LASTMEM2STATEENTERED_MASK;
936 m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
939 m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
942 WARN_ON(1); /* should never happen */
946 return prm_read_mod_bits_shift(pwrdm->prcm_offs,
947 OMAP3430_PM_PREPWSTST, m);
951 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
952 * @pwrdm: struct powerdomain * to clear
954 * Clear the powerdomain's previous power state register. Clears the
955 * entire register, including logic and memory bank previous power states.
956 * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon
959 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
965 * XXX should get the powerdomain's current state here;
966 * warn & fail if it is not ON.
969 pr_debug("powerdomain: clearing previous power state reg for %s\n",
972 prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
978 * pwrdm_wait_transition - wait for powerdomain power transition to finish
979 * @pwrdm: struct powerdomain * to wait for
981 * If the powerdomain pwrdm is in the process of a state transition,
982 * spin until it completes the power transition, or until an iteration
983 * bailout value is reached. Returns -EINVAL if the powerdomain
984 * pointer is null, -EAGAIN if the bailout value was reached, or
985 * returns 0 upon success.
987 int pwrdm_wait_transition(struct powerdomain *pwrdm)
995 * REVISIT: pwrdm_wait_transition() may be better implemented
996 * via a callback and a periodic timer check -- how long do we expect
997 * powerdomain transitions to take?
1000 /* XXX Is this udelay() value meaningful? */
1001 while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) &
1002 OMAP_INTRANSITION) &&
1003 (c++ < PWRDM_TRANSITION_BAILOUT))
1006 if (c >= PWRDM_TRANSITION_BAILOUT) {
1007 printk(KERN_ERR "powerdomain: waited too long for "
1008 "powerdomain %s to complete transition\n", pwrdm->name);
1012 pr_debug("powerdomain: completed transition in %d loops\n", c);