aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/prm2xxx_3xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/prm2xxx_3xxx.c')
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c112
1 files changed, 111 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 0d6cc543987d..bdddf5ca67c4 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -17,7 +17,7 @@
17#include <linux/io.h> 17#include <linux/io.h>
18 18
19#include "common.h" 19#include "common.h"
20 20#include "powerdomain.h"
21#include "prm2xxx_3xxx.h" 21#include "prm2xxx_3xxx.h"
22#include "prm-regbits-24xx.h" 22#include "prm-regbits-24xx.h"
23 23
@@ -98,3 +98,113 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
98 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; 98 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
99} 99}
100 100
101
102/* Powerdomain low-level functions */
103
104/* Common functions across OMAP2 and OMAP3 */
105int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
106{
107 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
108 (pwrst << OMAP_POWERSTATE_SHIFT),
109 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
110 return 0;
111}
112
113int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
114{
115 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
116 OMAP2_PM_PWSTCTRL,
117 OMAP_POWERSTATE_MASK);
118}
119
120int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
121{
122 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
123 OMAP2_PM_PWSTST,
124 OMAP_POWERSTATEST_MASK);
125}
126
127int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
128 u8 pwrst)
129{
130 u32 m;
131
132 m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
133
134 omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
135 OMAP2_PM_PWSTCTRL);
136
137 return 0;
138}
139
140int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
141 u8 pwrst)
142{
143 u32 m;
144
145 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
146
147 omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
148 OMAP2_PM_PWSTCTRL);
149
150 return 0;
151}
152
153int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
154{
155 u32 m;
156
157 m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
158
159 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
160 m);
161}
162
163int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
164{
165 u32 m;
166
167 m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
168
169 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
170 OMAP2_PM_PWSTCTRL, m);
171}
172
173int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
174{
175 u32 v;
176
177 v = pwrst << __ffs(OMAP_LOGICRETSTATE_MASK);
178 omap2_prm_rmw_mod_reg_bits(OMAP_LOGICRETSTATE_MASK, v, pwrdm->prcm_offs,
179 OMAP2_PM_PWSTCTRL);
180
181 return 0;
182}
183
184int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
185{
186 u32 c = 0;
187
188 /*
189 * REVISIT: pwrdm_wait_transition() may be better implemented
190 * via a callback and a periodic timer check -- how long do we expect
191 * powerdomain transitions to take?
192 */
193
194 /* XXX Is this udelay() value meaningful? */
195 while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
196 OMAP_INTRANSITION_MASK) &&
197 (c++ < PWRDM_TRANSITION_BAILOUT))
198 udelay(1);
199
200 if (c > PWRDM_TRANSITION_BAILOUT) {
201 pr_err("powerdomain: %s: waited too long to complete transition\n",
202 pwrdm->name);
203 return -EAGAIN;
204 }
205
206 pr_debug("powerdomain: completed transition in %d loops\n", c);
207
208 return 0;
209}
210