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