diff options
Diffstat (limited to 'arch/arm/mach-omap2/prm33xx.c')
-rw-r--r-- | arch/arm/mach-omap2/prm33xx.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index 624ade5c3c33..53ec9cbaa3d3 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "../plat-omap/common.h" | 22 | #include "../plat-omap/common.h" |
23 | 23 | ||
24 | #include "common.h" | 24 | #include "common.h" |
25 | #include "powerdomain.h" | ||
25 | #include "prm33xx.h" | 26 | #include "prm33xx.h" |
26 | #include "prm-regbits-33xx.h" | 27 | #include "prm-regbits-33xx.h" |
27 | 28 | ||
@@ -133,3 +134,204 @@ int am33xx_prm_deassert_hardreset(u8 shift, s16 inst, | |||
133 | 134 | ||
134 | return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; | 135 | return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; |
135 | } | 136 | } |
137 | |||
138 | static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) | ||
139 | { | ||
140 | am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK, | ||
141 | (pwrst << OMAP_POWERSTATE_SHIFT), | ||
142 | pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) | ||
147 | { | ||
148 | u32 v; | ||
149 | |||
150 | v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); | ||
151 | v &= OMAP_POWERSTATE_MASK; | ||
152 | v >>= OMAP_POWERSTATE_SHIFT; | ||
153 | |||
154 | return v; | ||
155 | } | ||
156 | |||
157 | static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm) | ||
158 | { | ||
159 | u32 v; | ||
160 | |||
161 | v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); | ||
162 | v &= OMAP_POWERSTATEST_MASK; | ||
163 | v >>= OMAP_POWERSTATEST_SHIFT; | ||
164 | |||
165 | return v; | ||
166 | } | ||
167 | |||
168 | static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) | ||
169 | { | ||
170 | u32 v; | ||
171 | |||
172 | v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); | ||
173 | v &= AM33XX_LASTPOWERSTATEENTERED_MASK; | ||
174 | v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT; | ||
175 | |||
176 | return v; | ||
177 | } | ||
178 | |||
179 | static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) | ||
180 | { | ||
181 | am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK, | ||
182 | (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT), | ||
183 | pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) | ||
188 | { | ||
189 | am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK, | ||
190 | AM33XX_LASTPOWERSTATEENTERED_MASK, | ||
191 | pwrdm->prcm_offs, pwrdm->pwrstst_offs); | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) | ||
196 | { | ||
197 | u32 m; | ||
198 | |||
199 | m = pwrdm->logicretstate_mask; | ||
200 | if (!m) | ||
201 | return -EINVAL; | ||
202 | |||
203 | am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), | ||
204 | pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) | ||
210 | { | ||
211 | u32 v; | ||
212 | |||
213 | v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); | ||
214 | v &= AM33XX_LOGICSTATEST_MASK; | ||
215 | v >>= AM33XX_LOGICSTATEST_SHIFT; | ||
216 | |||
217 | return v; | ||
218 | } | ||
219 | |||
220 | static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm) | ||
221 | { | ||
222 | u32 v, m; | ||
223 | |||
224 | m = pwrdm->logicretstate_mask; | ||
225 | if (!m) | ||
226 | return -EINVAL; | ||
227 | |||
228 | v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); | ||
229 | v &= m; | ||
230 | v >>= __ffs(m); | ||
231 | |||
232 | return v; | ||
233 | } | ||
234 | |||
235 | static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, | ||
236 | u8 pwrst) | ||
237 | { | ||
238 | u32 m; | ||
239 | |||
240 | m = pwrdm->mem_on_mask[bank]; | ||
241 | if (!m) | ||
242 | return -EINVAL; | ||
243 | |||
244 | am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), | ||
245 | pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, | ||
251 | u8 pwrst) | ||
252 | { | ||
253 | u32 m; | ||
254 | |||
255 | m = pwrdm->mem_ret_mask[bank]; | ||
256 | if (!m) | ||
257 | return -EINVAL; | ||
258 | |||
259 | am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), | ||
260 | pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | ||
266 | { | ||
267 | u32 m, v; | ||
268 | |||
269 | m = pwrdm->mem_pwrst_mask[bank]; | ||
270 | if (!m) | ||
271 | return -EINVAL; | ||
272 | |||
273 | v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); | ||
274 | v &= m; | ||
275 | v >>= __ffs(m); | ||
276 | |||
277 | return v; | ||
278 | } | ||
279 | |||
280 | static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) | ||
281 | { | ||
282 | u32 m, v; | ||
283 | |||
284 | m = pwrdm->mem_retst_mask[bank]; | ||
285 | if (!m) | ||
286 | return -EINVAL; | ||
287 | |||
288 | v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); | ||
289 | v &= m; | ||
290 | v >>= __ffs(m); | ||
291 | |||
292 | return v; | ||
293 | } | ||
294 | |||
295 | static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm) | ||
296 | { | ||
297 | u32 c = 0; | ||
298 | |||
299 | /* | ||
300 | * REVISIT: pwrdm_wait_transition() may be better implemented | ||
301 | * via a callback and a periodic timer check -- how long do we expect | ||
302 | * powerdomain transitions to take? | ||
303 | */ | ||
304 | |||
305 | /* XXX Is this udelay() value meaningful? */ | ||
306 | while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs) | ||
307 | & OMAP_INTRANSITION_MASK) && | ||
308 | (c++ < PWRDM_TRANSITION_BAILOUT)) | ||
309 | udelay(1); | ||
310 | |||
311 | if (c > PWRDM_TRANSITION_BAILOUT) { | ||
312 | pr_err("powerdomain: %s: waited too long to complete transition\n", | ||
313 | pwrdm->name); | ||
314 | return -EAGAIN; | ||
315 | } | ||
316 | |||
317 | pr_debug("powerdomain: completed transition in %d loops\n", c); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | struct pwrdm_ops am33xx_pwrdm_operations = { | ||
323 | .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, | ||
324 | .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, | ||
325 | .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst, | ||
326 | .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst, | ||
327 | .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst, | ||
328 | .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst, | ||
329 | .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst, | ||
330 | .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst, | ||
331 | .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange, | ||
332 | .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst, | ||
333 | .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst, | ||
334 | .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst, | ||
335 | .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst, | ||
336 | .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, | ||
337 | }; | ||