1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * OMAP3 powerdomain definitions |
4 | * |
5 | * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc. |
6 | * Copyright (C) 2007-2011 Nokia Corporation |
7 | * |
8 | * Paul Walmsley, Jouni Högander |
9 | */ |
10 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> |
13 | #include <linux/bug.h> |
14 | |
15 | #include "soc.h" |
16 | #include "powerdomain.h" |
17 | #include "powerdomains2xxx_3xxx_data.h" |
18 | #include "prcm-common.h" |
19 | #include "prm2xxx_3xxx.h" |
20 | #include "prm-regbits-34xx.h" |
21 | #include "cm2xxx_3xxx.h" |
22 | #include "cm-regbits-34xx.h" |
23 | |
24 | /* |
25 | * 34XX-specific powerdomains, dependencies |
26 | */ |
27 | |
28 | /* |
29 | * Powerdomains |
30 | */ |
31 | |
32 | static struct powerdomain iva2_pwrdm = { |
33 | .name = "iva2_pwrdm" , |
34 | .prcm_offs = OMAP3430_IVA2_MOD, |
35 | .pwrsts = PWRSTS_OFF_RET_ON, |
36 | .pwrsts_logic_ret = PWRSTS_OFF_RET, |
37 | .banks = 4, |
38 | .pwrsts_mem_ret = { |
39 | [0] = PWRSTS_OFF_RET, |
40 | [1] = PWRSTS_OFF_RET, |
41 | [2] = PWRSTS_OFF_RET, |
42 | [3] = PWRSTS_OFF_RET, |
43 | }, |
44 | .pwrsts_mem_on = { |
45 | [0] = PWRSTS_ON, |
46 | [1] = PWRSTS_ON, |
47 | [2] = PWRSTS_OFF_ON, |
48 | [3] = PWRSTS_ON, |
49 | }, |
50 | .voltdm = { .name = "mpu_iva" }, |
51 | }; |
52 | |
53 | static struct powerdomain mpu_3xxx_pwrdm = { |
54 | .name = "mpu_pwrdm" , |
55 | .prcm_offs = MPU_MOD, |
56 | .pwrsts = PWRSTS_OFF_RET_ON, |
57 | .pwrsts_logic_ret = PWRSTS_OFF_RET, |
58 | .flags = PWRDM_HAS_MPU_QUIRK, |
59 | .banks = 1, |
60 | .pwrsts_mem_ret = { |
61 | [0] = PWRSTS_OFF_RET, |
62 | }, |
63 | .pwrsts_mem_on = { |
64 | [0] = PWRSTS_OFF_ON, |
65 | }, |
66 | .voltdm = { .name = "mpu_iva" }, |
67 | }; |
68 | |
69 | static struct powerdomain mpu_am35x_pwrdm = { |
70 | .name = "mpu_pwrdm" , |
71 | .prcm_offs = MPU_MOD, |
72 | .pwrsts = PWRSTS_ON, |
73 | .pwrsts_logic_ret = PWRSTS_ON, |
74 | .flags = PWRDM_HAS_MPU_QUIRK, |
75 | .banks = 1, |
76 | .pwrsts_mem_ret = { |
77 | [0] = PWRSTS_ON, |
78 | }, |
79 | .pwrsts_mem_on = { |
80 | [0] = PWRSTS_ON, |
81 | }, |
82 | .voltdm = { .name = "mpu_iva" }, |
83 | }; |
84 | |
85 | /* |
86 | * The USBTLL Save-and-Restore mechanism is broken on |
87 | * 3430s up to ES3.0 and 3630ES1.0. Hence this feature |
88 | * needs to be disabled on these chips. |
89 | * Refer: 3430 errata ID i459 and 3630 errata ID i579 |
90 | * |
91 | * Note: setting the SAR flag could help for errata ID i478 |
92 | * which applies to 3430 <= ES3.1, but since the SAR feature |
93 | * is broken, do not use it. |
94 | */ |
95 | static struct powerdomain core_3xxx_pre_es3_1_pwrdm = { |
96 | .name = "core_pwrdm" , |
97 | .prcm_offs = CORE_MOD, |
98 | .pwrsts = PWRSTS_OFF_RET_ON, |
99 | .pwrsts_logic_ret = PWRSTS_OFF_RET, |
100 | .banks = 2, |
101 | .pwrsts_mem_ret = { |
102 | [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ |
103 | [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ |
104 | }, |
105 | .pwrsts_mem_on = { |
106 | [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ |
107 | [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ |
108 | }, |
109 | .voltdm = { .name = "core" }, |
110 | }; |
111 | |
112 | static struct powerdomain core_3xxx_es3_1_pwrdm = { |
113 | .name = "core_pwrdm" , |
114 | .prcm_offs = CORE_MOD, |
115 | .pwrsts = PWRSTS_OFF_RET_ON, |
116 | .pwrsts_logic_ret = PWRSTS_OFF_RET, |
117 | /* |
118 | * Setting the SAR flag for errata ID i478 which applies |
119 | * to 3430 <= ES3.1 |
120 | */ |
121 | .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */ |
122 | .banks = 2, |
123 | .pwrsts_mem_ret = { |
124 | [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ |
125 | [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ |
126 | }, |
127 | .pwrsts_mem_on = { |
128 | [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ |
129 | [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ |
130 | }, |
131 | .voltdm = { .name = "core" }, |
132 | }; |
133 | |
134 | static struct powerdomain core_am35x_pwrdm = { |
135 | .name = "core_pwrdm" , |
136 | .prcm_offs = CORE_MOD, |
137 | .pwrsts = PWRSTS_ON, |
138 | .pwrsts_logic_ret = PWRSTS_ON, |
139 | .banks = 2, |
140 | .pwrsts_mem_ret = { |
141 | [0] = PWRSTS_ON, /* MEM1RETSTATE */ |
142 | [1] = PWRSTS_ON, /* MEM2RETSTATE */ |
143 | }, |
144 | .pwrsts_mem_on = { |
145 | [0] = PWRSTS_ON, /* MEM1ONSTATE */ |
146 | [1] = PWRSTS_ON, /* MEM2ONSTATE */ |
147 | }, |
148 | .voltdm = { .name = "core" }, |
149 | }; |
150 | |
151 | static struct powerdomain dss_pwrdm = { |
152 | .name = "dss_pwrdm" , |
153 | .prcm_offs = OMAP3430_DSS_MOD, |
154 | .pwrsts = PWRSTS_OFF_RET_ON, |
155 | .pwrsts_logic_ret = PWRSTS_RET, |
156 | .banks = 1, |
157 | .pwrsts_mem_ret = { |
158 | [0] = PWRSTS_RET, /* MEMRETSTATE */ |
159 | }, |
160 | .pwrsts_mem_on = { |
161 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
162 | }, |
163 | .voltdm = { .name = "core" }, |
164 | }; |
165 | |
166 | static struct powerdomain dss_am35x_pwrdm = { |
167 | .name = "dss_pwrdm" , |
168 | .prcm_offs = OMAP3430_DSS_MOD, |
169 | .pwrsts = PWRSTS_ON, |
170 | .pwrsts_logic_ret = PWRSTS_ON, |
171 | .banks = 1, |
172 | .pwrsts_mem_ret = { |
173 | [0] = PWRSTS_ON, /* MEMRETSTATE */ |
174 | }, |
175 | .pwrsts_mem_on = { |
176 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
177 | }, |
178 | .voltdm = { .name = "core" }, |
179 | }; |
180 | |
181 | /* |
182 | * Although the 34XX TRM Rev K Table 4-371 notes that retention is a |
183 | * possible SGX powerstate, the SGX device itself does not support |
184 | * retention. |
185 | */ |
186 | static struct powerdomain sgx_pwrdm = { |
187 | .name = "sgx_pwrdm" , |
188 | .prcm_offs = OMAP3430ES2_SGX_MOD, |
189 | /* XXX This is accurate for 3430 SGX, but what about GFX? */ |
190 | .pwrsts = PWRSTS_OFF_ON, |
191 | .pwrsts_logic_ret = PWRSTS_RET, |
192 | .banks = 1, |
193 | .pwrsts_mem_ret = { |
194 | [0] = PWRSTS_RET, /* MEMRETSTATE */ |
195 | }, |
196 | .pwrsts_mem_on = { |
197 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
198 | }, |
199 | .voltdm = { .name = "core" }, |
200 | }; |
201 | |
202 | static struct powerdomain sgx_am35x_pwrdm = { |
203 | .name = "sgx_pwrdm" , |
204 | .prcm_offs = OMAP3430ES2_SGX_MOD, |
205 | .pwrsts = PWRSTS_ON, |
206 | .pwrsts_logic_ret = PWRSTS_ON, |
207 | .banks = 1, |
208 | .pwrsts_mem_ret = { |
209 | [0] = PWRSTS_ON, /* MEMRETSTATE */ |
210 | }, |
211 | .pwrsts_mem_on = { |
212 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
213 | }, |
214 | .voltdm = { .name = "core" }, |
215 | }; |
216 | |
217 | static struct powerdomain cam_pwrdm = { |
218 | .name = "cam_pwrdm" , |
219 | .prcm_offs = OMAP3430_CAM_MOD, |
220 | .pwrsts = PWRSTS_OFF_RET_ON, |
221 | .pwrsts_logic_ret = PWRSTS_RET, |
222 | .banks = 1, |
223 | .pwrsts_mem_ret = { |
224 | [0] = PWRSTS_RET, /* MEMRETSTATE */ |
225 | }, |
226 | .pwrsts_mem_on = { |
227 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
228 | }, |
229 | .voltdm = { .name = "core" }, |
230 | }; |
231 | |
232 | static struct powerdomain per_pwrdm = { |
233 | .name = "per_pwrdm" , |
234 | .prcm_offs = OMAP3430_PER_MOD, |
235 | .pwrsts = PWRSTS_OFF_RET_ON, |
236 | .pwrsts_logic_ret = PWRSTS_OFF_RET, |
237 | .banks = 1, |
238 | .pwrsts_mem_ret = { |
239 | [0] = PWRSTS_RET, /* MEMRETSTATE */ |
240 | }, |
241 | .pwrsts_mem_on = { |
242 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
243 | }, |
244 | .voltdm = { .name = "core" }, |
245 | }; |
246 | |
247 | static struct powerdomain per_am35x_pwrdm = { |
248 | .name = "per_pwrdm" , |
249 | .prcm_offs = OMAP3430_PER_MOD, |
250 | .pwrsts = PWRSTS_ON, |
251 | .pwrsts_logic_ret = PWRSTS_ON, |
252 | .banks = 1, |
253 | .pwrsts_mem_ret = { |
254 | [0] = PWRSTS_ON, /* MEMRETSTATE */ |
255 | }, |
256 | .pwrsts_mem_on = { |
257 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
258 | }, |
259 | .voltdm = { .name = "core" }, |
260 | }; |
261 | |
262 | static struct powerdomain emu_pwrdm = { |
263 | .name = "emu_pwrdm" , |
264 | .prcm_offs = OMAP3430_EMU_MOD, |
265 | .voltdm = { .name = "core" }, |
266 | }; |
267 | |
268 | static struct powerdomain neon_pwrdm = { |
269 | .name = "neon_pwrdm" , |
270 | .prcm_offs = OMAP3430_NEON_MOD, |
271 | .pwrsts = PWRSTS_OFF_RET_ON, |
272 | .pwrsts_logic_ret = PWRSTS_RET, |
273 | .voltdm = { .name = "mpu_iva" }, |
274 | }; |
275 | |
276 | static struct powerdomain neon_am35x_pwrdm = { |
277 | .name = "neon_pwrdm" , |
278 | .prcm_offs = OMAP3430_NEON_MOD, |
279 | .pwrsts = PWRSTS_ON, |
280 | .pwrsts_logic_ret = PWRSTS_ON, |
281 | .voltdm = { .name = "mpu_iva" }, |
282 | }; |
283 | |
284 | static struct powerdomain usbhost_pwrdm = { |
285 | .name = "usbhost_pwrdm" , |
286 | .prcm_offs = OMAP3430ES2_USBHOST_MOD, |
287 | .pwrsts = PWRSTS_OFF_RET_ON, |
288 | .pwrsts_logic_ret = PWRSTS_RET, |
289 | /* |
290 | * REVISIT: Enabling usb host save and restore mechanism seems to |
291 | * leave the usb host domain permanently in ACTIVE mode after |
292 | * changing the usb host power domain state from OFF to active once. |
293 | * Disabling for now. |
294 | */ |
295 | /*.flags = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */ |
296 | .banks = 1, |
297 | .pwrsts_mem_ret = { |
298 | [0] = PWRSTS_RET, /* MEMRETSTATE */ |
299 | }, |
300 | .pwrsts_mem_on = { |
301 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
302 | }, |
303 | .voltdm = { .name = "core" }, |
304 | }; |
305 | |
306 | static struct powerdomain dpll1_pwrdm = { |
307 | .name = "dpll1_pwrdm" , |
308 | .prcm_offs = MPU_MOD, |
309 | .voltdm = { .name = "mpu_iva" }, |
310 | }; |
311 | |
312 | static struct powerdomain dpll2_pwrdm = { |
313 | .name = "dpll2_pwrdm" , |
314 | .prcm_offs = OMAP3430_IVA2_MOD, |
315 | .voltdm = { .name = "mpu_iva" }, |
316 | }; |
317 | |
318 | static struct powerdomain dpll3_pwrdm = { |
319 | .name = "dpll3_pwrdm" , |
320 | .prcm_offs = PLL_MOD, |
321 | .voltdm = { .name = "core" }, |
322 | }; |
323 | |
324 | static struct powerdomain dpll4_pwrdm = { |
325 | .name = "dpll4_pwrdm" , |
326 | .prcm_offs = PLL_MOD, |
327 | .voltdm = { .name = "core" }, |
328 | }; |
329 | |
330 | static struct powerdomain dpll5_pwrdm = { |
331 | .name = "dpll5_pwrdm" , |
332 | .prcm_offs = PLL_MOD, |
333 | .voltdm = { .name = "core" }, |
334 | }; |
335 | |
336 | static struct powerdomain alwon_81xx_pwrdm = { |
337 | .name = "alwon_pwrdm" , |
338 | .prcm_offs = TI81XX_PRM_ALWON_MOD, |
339 | .pwrsts = PWRSTS_OFF_ON, |
340 | .voltdm = { .name = "core" }, |
341 | }; |
342 | |
343 | static struct powerdomain device_81xx_pwrdm = { |
344 | .name = "device_pwrdm" , |
345 | .prcm_offs = TI81XX_PRM_DEVICE_MOD, |
346 | .voltdm = { .name = "core" }, |
347 | }; |
348 | |
349 | static struct powerdomain gem_814x_pwrdm = { |
350 | .name = "gem_pwrdm" , |
351 | .prcm_offs = TI814X_PRM_DSP_MOD, |
352 | .pwrsts = PWRSTS_OFF_ON, |
353 | .voltdm = { .name = "dsp" }, |
354 | }; |
355 | |
356 | static struct powerdomain ivahd_814x_pwrdm = { |
357 | .name = "ivahd_pwrdm" , |
358 | .prcm_offs = TI814X_PRM_HDVICP_MOD, |
359 | .pwrsts = PWRSTS_OFF_ON, |
360 | .voltdm = { .name = "iva" }, |
361 | }; |
362 | |
363 | static struct powerdomain hdvpss_814x_pwrdm = { |
364 | .name = "hdvpss_pwrdm" , |
365 | .prcm_offs = TI814X_PRM_HDVPSS_MOD, |
366 | .pwrsts = PWRSTS_OFF_ON, |
367 | .voltdm = { .name = "dsp" }, |
368 | }; |
369 | |
370 | static struct powerdomain sgx_814x_pwrdm = { |
371 | .name = "sgx_pwrdm" , |
372 | .prcm_offs = TI814X_PRM_GFX_MOD, |
373 | .pwrsts = PWRSTS_OFF_ON, |
374 | .voltdm = { .name = "core" }, |
375 | }; |
376 | |
377 | static struct powerdomain isp_814x_pwrdm = { |
378 | .name = "isp_pwrdm" , |
379 | .prcm_offs = TI814X_PRM_ISP_MOD, |
380 | .pwrsts = PWRSTS_OFF_ON, |
381 | .voltdm = { .name = "core" }, |
382 | }; |
383 | |
384 | static struct powerdomain active_81xx_pwrdm = { |
385 | .name = "active_pwrdm" , |
386 | .prcm_offs = TI816X_PRM_ACTIVE_MOD, |
387 | .pwrsts = PWRSTS_OFF_ON, |
388 | .voltdm = { .name = "core" }, |
389 | }; |
390 | |
391 | static struct powerdomain default_81xx_pwrdm = { |
392 | .name = "default_pwrdm" , |
393 | .prcm_offs = TI81XX_PRM_DEFAULT_MOD, |
394 | .pwrsts = PWRSTS_OFF_ON, |
395 | .voltdm = { .name = "core" }, |
396 | }; |
397 | |
398 | static struct powerdomain ivahd0_816x_pwrdm = { |
399 | .name = "ivahd0_pwrdm" , |
400 | .prcm_offs = TI816X_PRM_IVAHD0_MOD, |
401 | .pwrsts = PWRSTS_OFF_ON, |
402 | .voltdm = { .name = "mpu_iva" }, |
403 | }; |
404 | |
405 | static struct powerdomain ivahd1_816x_pwrdm = { |
406 | .name = "ivahd1_pwrdm" , |
407 | .prcm_offs = TI816X_PRM_IVAHD1_MOD, |
408 | .pwrsts = PWRSTS_OFF_ON, |
409 | .voltdm = { .name = "mpu_iva" }, |
410 | }; |
411 | |
412 | static struct powerdomain ivahd2_816x_pwrdm = { |
413 | .name = "ivahd2_pwrdm" , |
414 | .prcm_offs = TI816X_PRM_IVAHD2_MOD, |
415 | .pwrsts = PWRSTS_OFF_ON, |
416 | .voltdm = { .name = "mpu_iva" }, |
417 | }; |
418 | |
419 | static struct powerdomain sgx_816x_pwrdm = { |
420 | .name = "sgx_pwrdm" , |
421 | .prcm_offs = TI816X_PRM_SGX_MOD, |
422 | .pwrsts = PWRSTS_OFF_ON, |
423 | .voltdm = { .name = "core" }, |
424 | }; |
425 | |
426 | /* As powerdomains are added or removed above, this list must also be changed */ |
427 | static struct powerdomain *powerdomains_omap3430_common[] __initdata = { |
428 | &wkup_omap2_pwrdm, |
429 | &iva2_pwrdm, |
430 | &mpu_3xxx_pwrdm, |
431 | &neon_pwrdm, |
432 | &cam_pwrdm, |
433 | &dss_pwrdm, |
434 | &per_pwrdm, |
435 | &emu_pwrdm, |
436 | &dpll1_pwrdm, |
437 | &dpll2_pwrdm, |
438 | &dpll3_pwrdm, |
439 | &dpll4_pwrdm, |
440 | NULL |
441 | }; |
442 | |
443 | static struct powerdomain *powerdomains_omap3430es1[] __initdata = { |
444 | &gfx_omap2_pwrdm, |
445 | &core_3xxx_pre_es3_1_pwrdm, |
446 | NULL |
447 | }; |
448 | |
449 | /* also includes 3630ES1.0 */ |
450 | static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = { |
451 | &core_3xxx_pre_es3_1_pwrdm, |
452 | &sgx_pwrdm, |
453 | &usbhost_pwrdm, |
454 | &dpll5_pwrdm, |
455 | NULL |
456 | }; |
457 | |
458 | /* also includes 3630ES1.1+ */ |
459 | static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = { |
460 | &core_3xxx_es3_1_pwrdm, |
461 | &sgx_pwrdm, |
462 | &usbhost_pwrdm, |
463 | &dpll5_pwrdm, |
464 | NULL |
465 | }; |
466 | |
467 | static struct powerdomain *powerdomains_am35x[] __initdata = { |
468 | &wkup_omap2_pwrdm, |
469 | &mpu_am35x_pwrdm, |
470 | &neon_am35x_pwrdm, |
471 | &core_am35x_pwrdm, |
472 | &sgx_am35x_pwrdm, |
473 | &dss_am35x_pwrdm, |
474 | &per_am35x_pwrdm, |
475 | &emu_pwrdm, |
476 | &dpll1_pwrdm, |
477 | &dpll3_pwrdm, |
478 | &dpll4_pwrdm, |
479 | &dpll5_pwrdm, |
480 | NULL |
481 | }; |
482 | |
483 | static struct powerdomain *powerdomains_ti814x[] __initdata = { |
484 | &alwon_81xx_pwrdm, |
485 | &device_81xx_pwrdm, |
486 | &active_81xx_pwrdm, |
487 | &default_81xx_pwrdm, |
488 | &gem_814x_pwrdm, |
489 | &ivahd_814x_pwrdm, |
490 | &hdvpss_814x_pwrdm, |
491 | &sgx_814x_pwrdm, |
492 | &isp_814x_pwrdm, |
493 | NULL |
494 | }; |
495 | |
496 | static struct powerdomain *powerdomains_ti816x[] __initdata = { |
497 | &alwon_81xx_pwrdm, |
498 | &device_81xx_pwrdm, |
499 | &active_81xx_pwrdm, |
500 | &default_81xx_pwrdm, |
501 | &ivahd0_816x_pwrdm, |
502 | &ivahd1_816x_pwrdm, |
503 | &ivahd2_816x_pwrdm, |
504 | &sgx_816x_pwrdm, |
505 | NULL |
506 | }; |
507 | |
508 | /* TI81XX specific ops */ |
509 | #define TI81XX_PM_PWSTCTRL 0x0000 |
510 | #define TI81XX_RM_RSTCTRL 0x0010 |
511 | #define TI81XX_PM_PWSTST 0x0004 |
512 | |
513 | static int ti81xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) |
514 | { |
515 | omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, |
516 | bits: (pwrst << OMAP_POWERSTATE_SHIFT), |
517 | module: pwrdm->prcm_offs, TI81XX_PM_PWSTCTRL); |
518 | return 0; |
519 | } |
520 | |
521 | static int ti81xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) |
522 | { |
523 | return omap2_prm_read_mod_bits_shift(domain: pwrdm->prcm_offs, |
524 | TI81XX_PM_PWSTCTRL, |
525 | OMAP_POWERSTATE_MASK); |
526 | } |
527 | |
528 | static int ti81xx_pwrdm_read_pwrst(struct powerdomain *pwrdm) |
529 | { |
530 | return omap2_prm_read_mod_bits_shift(domain: pwrdm->prcm_offs, |
531 | idx: (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL : |
532 | TI81XX_PM_PWSTST, |
533 | OMAP_POWERSTATEST_MASK); |
534 | } |
535 | |
536 | static int ti81xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) |
537 | { |
538 | return omap2_prm_read_mod_bits_shift(domain: pwrdm->prcm_offs, |
539 | idx: (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL : |
540 | TI81XX_PM_PWSTST, |
541 | OMAP3430_LOGICSTATEST_MASK); |
542 | } |
543 | |
544 | static int ti81xx_pwrdm_wait_transition(struct powerdomain *pwrdm) |
545 | { |
546 | u32 c = 0; |
547 | |
548 | while ((omap2_prm_read_mod_reg(module: pwrdm->prcm_offs, |
549 | idx: (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL : |
550 | TI81XX_PM_PWSTST) & |
551 | OMAP_INTRANSITION_MASK) && |
552 | (c++ < PWRDM_TRANSITION_BAILOUT)) |
553 | udelay(1); |
554 | |
555 | if (c > PWRDM_TRANSITION_BAILOUT) { |
556 | pr_err("powerdomain: %s timeout waiting for transition\n" , |
557 | pwrdm->name); |
558 | return -EAGAIN; |
559 | } |
560 | |
561 | pr_debug("powerdomain: completed transition in %d loops\n" , c); |
562 | |
563 | return 0; |
564 | } |
565 | |
566 | /* For dm814x we need to fix up fix GFX pwstst and rstctrl reg offsets */ |
567 | static struct pwrdm_ops ti81xx_pwrdm_operations = { |
568 | .pwrdm_set_next_pwrst = ti81xx_pwrdm_set_next_pwrst, |
569 | .pwrdm_read_next_pwrst = ti81xx_pwrdm_read_next_pwrst, |
570 | .pwrdm_read_pwrst = ti81xx_pwrdm_read_pwrst, |
571 | .pwrdm_read_logic_pwrst = ti81xx_pwrdm_read_logic_pwrst, |
572 | .pwrdm_wait_transition = ti81xx_pwrdm_wait_transition, |
573 | }; |
574 | |
575 | void __init omap3xxx_powerdomains_init(void) |
576 | { |
577 | unsigned int rev; |
578 | |
579 | if (!cpu_is_omap34xx() && !cpu_is_ti81xx()) |
580 | return; |
581 | |
582 | /* Only 81xx needs custom pwrdm_operations */ |
583 | if (!cpu_is_ti81xx()) |
584 | pwrdm_register_platform_funcs(custom_funcs: &omap3_pwrdm_operations); |
585 | |
586 | rev = omap_rev(); |
587 | |
588 | if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { |
589 | pwrdm_register_pwrdms(pwrdm_list: powerdomains_am35x); |
590 | } else if (rev == TI8148_REV_ES1_0 || rev == TI8148_REV_ES2_0 || |
591 | rev == TI8148_REV_ES2_1) { |
592 | pwrdm_register_platform_funcs(custom_funcs: &ti81xx_pwrdm_operations); |
593 | pwrdm_register_pwrdms(pwrdm_list: powerdomains_ti814x); |
594 | } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1 |
595 | || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) { |
596 | pwrdm_register_platform_funcs(custom_funcs: &ti81xx_pwrdm_operations); |
597 | pwrdm_register_pwrdms(pwrdm_list: powerdomains_ti816x); |
598 | } else { |
599 | pwrdm_register_pwrdms(pwrdm_list: powerdomains_omap3430_common); |
600 | |
601 | switch (rev) { |
602 | case OMAP3430_REV_ES1_0: |
603 | pwrdm_register_pwrdms(pwrdm_list: powerdomains_omap3430es1); |
604 | break; |
605 | case OMAP3430_REV_ES2_0: |
606 | case OMAP3430_REV_ES2_1: |
607 | case OMAP3430_REV_ES3_0: |
608 | case OMAP3630_REV_ES1_0: |
609 | pwrdm_register_pwrdms(pwrdm_list: powerdomains_omap3430es2_es3_0); |
610 | break; |
611 | case OMAP3430_REV_ES3_1: |
612 | case OMAP3430_REV_ES3_1_2: |
613 | case OMAP3630_REV_ES1_1: |
614 | case OMAP3630_REV_ES1_2: |
615 | pwrdm_register_pwrdms(pwrdm_list: powerdomains_omap3430es3_1plus); |
616 | break; |
617 | default: |
618 | WARN(1, "OMAP3 powerdomain init: unknown chip type\n" ); |
619 | } |
620 | } |
621 | |
622 | pwrdm_complete_init(); |
623 | } |
624 | |