2 * OMAP3 powerdomain definitions
4 * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
5 * Copyright (C) 2007-2011 Nokia Corporation
7 * Paul Walmsley, Jouni Högander
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.
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/bug.h>
19 #include "powerdomain.h"
20 #include "powerdomains2xxx_3xxx_data.h"
21 #include "prcm-common.h"
22 #include "prm2xxx_3xxx.h"
23 #include "prm-regbits-34xx.h"
24 #include "cm2xxx_3xxx.h"
25 #include "cm-regbits-34xx.h"
28 * 34XX-specific powerdomains, dependencies
35 static struct powerdomain iva2_pwrdm
= {
37 .prcm_offs
= OMAP3430_IVA2_MOD
,
38 .pwrsts
= PWRSTS_OFF_RET_ON
,
39 .pwrsts_logic_ret
= PWRSTS_OFF_RET
,
53 .voltdm
= { .name
= "mpu_iva" },
56 static struct powerdomain mpu_3xxx_pwrdm
= {
59 .pwrsts
= PWRSTS_OFF_RET_ON
,
60 .pwrsts_logic_ret
= PWRSTS_OFF_RET
,
61 .flags
= PWRDM_HAS_MPU_QUIRK
,
69 .voltdm
= { .name
= "mpu_iva" },
72 static struct powerdomain mpu_am35x_pwrdm
= {
76 .pwrsts_logic_ret
= PWRSTS_ON
,
77 .flags
= PWRDM_HAS_MPU_QUIRK
,
85 .voltdm
= { .name
= "mpu_iva" },
89 * The USBTLL Save-and-Restore mechanism is broken on
90 * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
91 * needs to be disabled on these chips.
92 * Refer: 3430 errata ID i459 and 3630 errata ID i579
94 * Note: setting the SAR flag could help for errata ID i478
95 * which applies to 3430 <= ES3.1, but since the SAR feature
96 * is broken, do not use it.
98 static struct powerdomain core_3xxx_pre_es3_1_pwrdm
= {
100 .prcm_offs
= CORE_MOD
,
101 .pwrsts
= PWRSTS_OFF_RET_ON
,
102 .pwrsts_logic_ret
= PWRSTS_OFF_RET
,
105 [0] = PWRSTS_OFF_RET
, /* MEM1RETSTATE */
106 [1] = PWRSTS_OFF_RET
, /* MEM2RETSTATE */
109 [0] = PWRSTS_OFF_RET_ON
, /* MEM1ONSTATE */
110 [1] = PWRSTS_OFF_RET_ON
, /* MEM2ONSTATE */
112 .voltdm
= { .name
= "core" },
115 static struct powerdomain core_3xxx_es3_1_pwrdm
= {
116 .name
= "core_pwrdm",
117 .prcm_offs
= CORE_MOD
,
118 .pwrsts
= PWRSTS_OFF_RET_ON
,
119 .pwrsts_logic_ret
= PWRSTS_OFF_RET
,
121 * Setting the SAR flag for errata ID i478 which applies
124 .flags
= PWRDM_HAS_HDWR_SAR
, /* for USBTLL only */
127 [0] = PWRSTS_OFF_RET
, /* MEM1RETSTATE */
128 [1] = PWRSTS_OFF_RET
, /* MEM2RETSTATE */
131 [0] = PWRSTS_OFF_RET_ON
, /* MEM1ONSTATE */
132 [1] = PWRSTS_OFF_RET_ON
, /* MEM2ONSTATE */
134 .voltdm
= { .name
= "core" },
137 static struct powerdomain core_am35x_pwrdm
= {
138 .name
= "core_pwrdm",
139 .prcm_offs
= CORE_MOD
,
141 .pwrsts_logic_ret
= PWRSTS_ON
,
144 [0] = PWRSTS_ON
, /* MEM1RETSTATE */
145 [1] = PWRSTS_ON
, /* MEM2RETSTATE */
148 [0] = PWRSTS_ON
, /* MEM1ONSTATE */
149 [1] = PWRSTS_ON
, /* MEM2ONSTATE */
151 .voltdm
= { .name
= "core" },
154 static struct powerdomain dss_pwrdm
= {
156 .prcm_offs
= OMAP3430_DSS_MOD
,
157 .pwrsts
= PWRSTS_OFF_RET_ON
,
158 .pwrsts_logic_ret
= PWRSTS_RET
,
161 [0] = PWRSTS_RET
, /* MEMRETSTATE */
164 [0] = PWRSTS_ON
, /* MEMONSTATE */
166 .voltdm
= { .name
= "core" },
169 static struct powerdomain dss_am35x_pwrdm
= {
171 .prcm_offs
= OMAP3430_DSS_MOD
,
173 .pwrsts_logic_ret
= PWRSTS_ON
,
176 [0] = PWRSTS_ON
, /* MEMRETSTATE */
179 [0] = PWRSTS_ON
, /* MEMONSTATE */
181 .voltdm
= { .name
= "core" },
185 * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
186 * possible SGX powerstate, the SGX device itself does not support
189 static struct powerdomain sgx_pwrdm
= {
191 .prcm_offs
= OMAP3430ES2_SGX_MOD
,
192 /* XXX This is accurate for 3430 SGX, but what about GFX? */
193 .pwrsts
= PWRSTS_OFF_ON
,
194 .pwrsts_logic_ret
= PWRSTS_RET
,
197 [0] = PWRSTS_RET
, /* MEMRETSTATE */
200 [0] = PWRSTS_ON
, /* MEMONSTATE */
202 .voltdm
= { .name
= "core" },
205 static struct powerdomain sgx_am35x_pwrdm
= {
207 .prcm_offs
= OMAP3430ES2_SGX_MOD
,
209 .pwrsts_logic_ret
= PWRSTS_ON
,
212 [0] = PWRSTS_ON
, /* MEMRETSTATE */
215 [0] = PWRSTS_ON
, /* MEMONSTATE */
217 .voltdm
= { .name
= "core" },
220 static struct powerdomain cam_pwrdm
= {
222 .prcm_offs
= OMAP3430_CAM_MOD
,
223 .pwrsts
= PWRSTS_OFF_RET_ON
,
224 .pwrsts_logic_ret
= PWRSTS_RET
,
227 [0] = PWRSTS_RET
, /* MEMRETSTATE */
230 [0] = PWRSTS_ON
, /* MEMONSTATE */
232 .voltdm
= { .name
= "core" },
235 static struct powerdomain per_pwrdm
= {
237 .prcm_offs
= OMAP3430_PER_MOD
,
238 .pwrsts
= PWRSTS_OFF_RET_ON
,
239 .pwrsts_logic_ret
= PWRSTS_OFF_RET
,
242 [0] = PWRSTS_RET
, /* MEMRETSTATE */
245 [0] = PWRSTS_ON
, /* MEMONSTATE */
247 .voltdm
= { .name
= "core" },
250 static struct powerdomain per_am35x_pwrdm
= {
252 .prcm_offs
= OMAP3430_PER_MOD
,
254 .pwrsts_logic_ret
= PWRSTS_ON
,
257 [0] = PWRSTS_ON
, /* MEMRETSTATE */
260 [0] = PWRSTS_ON
, /* MEMONSTATE */
262 .voltdm
= { .name
= "core" },
265 static struct powerdomain emu_pwrdm
= {
267 .prcm_offs
= OMAP3430_EMU_MOD
,
268 .voltdm
= { .name
= "core" },
271 static struct powerdomain neon_pwrdm
= {
272 .name
= "neon_pwrdm",
273 .prcm_offs
= OMAP3430_NEON_MOD
,
274 .pwrsts
= PWRSTS_OFF_RET_ON
,
275 .pwrsts_logic_ret
= PWRSTS_RET
,
276 .voltdm
= { .name
= "mpu_iva" },
279 static struct powerdomain neon_am35x_pwrdm
= {
280 .name
= "neon_pwrdm",
281 .prcm_offs
= OMAP3430_NEON_MOD
,
283 .pwrsts_logic_ret
= PWRSTS_ON
,
284 .voltdm
= { .name
= "mpu_iva" },
287 static struct powerdomain usbhost_pwrdm
= {
288 .name
= "usbhost_pwrdm",
289 .prcm_offs
= OMAP3430ES2_USBHOST_MOD
,
290 .pwrsts
= PWRSTS_OFF_RET_ON
,
291 .pwrsts_logic_ret
= PWRSTS_RET
,
293 * REVISIT: Enabling usb host save and restore mechanism seems to
294 * leave the usb host domain permanently in ACTIVE mode after
295 * changing the usb host power domain state from OFF to active once.
298 /*.flags = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
301 [0] = PWRSTS_RET
, /* MEMRETSTATE */
304 [0] = PWRSTS_ON
, /* MEMONSTATE */
306 .voltdm
= { .name
= "core" },
309 static struct powerdomain dpll1_pwrdm
= {
310 .name
= "dpll1_pwrdm",
311 .prcm_offs
= MPU_MOD
,
312 .voltdm
= { .name
= "mpu_iva" },
315 static struct powerdomain dpll2_pwrdm
= {
316 .name
= "dpll2_pwrdm",
317 .prcm_offs
= OMAP3430_IVA2_MOD
,
318 .voltdm
= { .name
= "mpu_iva" },
321 static struct powerdomain dpll3_pwrdm
= {
322 .name
= "dpll3_pwrdm",
323 .prcm_offs
= PLL_MOD
,
324 .voltdm
= { .name
= "core" },
327 static struct powerdomain dpll4_pwrdm
= {
328 .name
= "dpll4_pwrdm",
329 .prcm_offs
= PLL_MOD
,
330 .voltdm
= { .name
= "core" },
333 static struct powerdomain dpll5_pwrdm
= {
334 .name
= "dpll5_pwrdm",
335 .prcm_offs
= PLL_MOD
,
336 .voltdm
= { .name
= "core" },
339 static struct powerdomain alwon_81xx_pwrdm
= {
340 .name
= "alwon_pwrdm",
341 .prcm_offs
= TI81XX_PRM_ALWON_MOD
,
342 .pwrsts
= PWRSTS_OFF_ON
,
343 .voltdm
= { .name
= "core" },
346 static struct powerdomain device_81xx_pwrdm
= {
347 .name
= "device_pwrdm",
348 .prcm_offs
= TI81XX_PRM_DEVICE_MOD
,
349 .voltdm
= { .name
= "core" },
352 static struct powerdomain gem_814x_pwrdm
= {
354 .prcm_offs
= TI814X_PRM_DSP_MOD
,
355 .pwrsts
= PWRSTS_OFF_ON
,
356 .voltdm
= { .name
= "dsp" },
359 static struct powerdomain ivahd_814x_pwrdm
= {
360 .name
= "ivahd_pwrdm",
361 .prcm_offs
= TI814X_PRM_HDVICP_MOD
,
362 .pwrsts
= PWRSTS_OFF_ON
,
363 .voltdm
= { .name
= "iva" },
366 static struct powerdomain hdvpss_814x_pwrdm
= {
367 .name
= "hdvpss_pwrdm",
368 .prcm_offs
= TI814X_PRM_HDVPSS_MOD
,
369 .pwrsts
= PWRSTS_OFF_ON
,
370 .voltdm
= { .name
= "dsp" },
373 static struct powerdomain sgx_814x_pwrdm
= {
375 .prcm_offs
= TI814X_PRM_GFX_MOD
,
376 .pwrsts
= PWRSTS_OFF_ON
,
377 .voltdm
= { .name
= "core" },
380 static struct powerdomain isp_814x_pwrdm
= {
382 .prcm_offs
= TI814X_PRM_ISP_MOD
,
383 .pwrsts
= PWRSTS_OFF_ON
,
384 .voltdm
= { .name
= "core" },
387 static struct powerdomain active_816x_pwrdm
= {
388 .name
= "active_pwrdm",
389 .prcm_offs
= TI816X_PRM_ACTIVE_MOD
,
390 .pwrsts
= PWRSTS_OFF_ON
,
391 .voltdm
= { .name
= "core" },
394 static struct powerdomain default_816x_pwrdm
= {
395 .name
= "default_pwrdm",
396 .prcm_offs
= TI81XX_PRM_DEFAULT_MOD
,
397 .pwrsts
= PWRSTS_OFF_ON
,
398 .voltdm
= { .name
= "core" },
401 static struct powerdomain ivahd0_816x_pwrdm
= {
402 .name
= "ivahd0_pwrdm",
403 .prcm_offs
= TI816X_PRM_IVAHD0_MOD
,
404 .pwrsts
= PWRSTS_OFF_ON
,
405 .voltdm
= { .name
= "mpu_iva" },
408 static struct powerdomain ivahd1_816x_pwrdm
= {
409 .name
= "ivahd1_pwrdm",
410 .prcm_offs
= TI816X_PRM_IVAHD1_MOD
,
411 .pwrsts
= PWRSTS_OFF_ON
,
412 .voltdm
= { .name
= "mpu_iva" },
415 static struct powerdomain ivahd2_816x_pwrdm
= {
416 .name
= "ivahd2_pwrdm",
417 .prcm_offs
= TI816X_PRM_IVAHD2_MOD
,
418 .pwrsts
= PWRSTS_OFF_ON
,
419 .voltdm
= { .name
= "mpu_iva" },
422 static struct powerdomain sgx_816x_pwrdm
= {
424 .prcm_offs
= TI816X_PRM_SGX_MOD
,
425 .pwrsts
= PWRSTS_OFF_ON
,
426 .voltdm
= { .name
= "core" },
429 /* As powerdomains are added or removed above, this list must also be changed */
430 static struct powerdomain
*powerdomains_omap3430_common
[] __initdata
= {
446 static struct powerdomain
*powerdomains_omap3430es1
[] __initdata
= {
448 &core_3xxx_pre_es3_1_pwrdm
,
452 /* also includes 3630ES1.0 */
453 static struct powerdomain
*powerdomains_omap3430es2_es3_0
[] __initdata
= {
454 &core_3xxx_pre_es3_1_pwrdm
,
461 /* also includes 3630ES1.1+ */
462 static struct powerdomain
*powerdomains_omap3430es3_1plus
[] __initdata
= {
463 &core_3xxx_es3_1_pwrdm
,
470 static struct powerdomain
*powerdomains_am35x
[] __initdata
= {
486 static struct powerdomain
*powerdomains_ti814x
[] __initdata
= {
497 static struct powerdomain
*powerdomains_ti816x
[] __initdata
= {
509 /* TI81XX specific ops */
510 #define TI81XX_PM_PWSTCTRL 0x0000
511 #define TI81XX_RM_RSTCTRL 0x0010
512 #define TI81XX_PM_PWSTST 0x0004
514 static int ti81xx_pwrdm_set_next_pwrst(struct powerdomain
*pwrdm
, u8 pwrst
)
516 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK
,
517 (pwrst
<< OMAP_POWERSTATE_SHIFT
),
518 pwrdm
->prcm_offs
, TI81XX_PM_PWSTCTRL
);
522 static int ti81xx_pwrdm_read_next_pwrst(struct powerdomain
*pwrdm
)
524 return omap2_prm_read_mod_bits_shift(pwrdm
->prcm_offs
,
526 OMAP_POWERSTATE_MASK
);
529 static int ti81xx_pwrdm_read_pwrst(struct powerdomain
*pwrdm
)
531 return omap2_prm_read_mod_bits_shift(pwrdm
->prcm_offs
,
532 (pwrdm
->prcm_offs
== TI814X_PRM_GFX_MOD
) ? TI81XX_RM_RSTCTRL
:
534 OMAP_POWERSTATEST_MASK
);
537 static int ti81xx_pwrdm_read_logic_pwrst(struct powerdomain
*pwrdm
)
539 return omap2_prm_read_mod_bits_shift(pwrdm
->prcm_offs
,
540 (pwrdm
->prcm_offs
== TI814X_PRM_GFX_MOD
) ? TI81XX_RM_RSTCTRL
:
542 OMAP3430_LOGICSTATEST_MASK
);
545 static int ti81xx_pwrdm_wait_transition(struct powerdomain
*pwrdm
)
549 while ((omap2_prm_read_mod_reg(pwrdm
->prcm_offs
,
550 (pwrdm
->prcm_offs
== TI814X_PRM_GFX_MOD
) ? TI81XX_RM_RSTCTRL
:
552 OMAP_INTRANSITION_MASK
) &&
553 (c
++ < PWRDM_TRANSITION_BAILOUT
))
556 if (c
> PWRDM_TRANSITION_BAILOUT
) {
557 pr_err("powerdomain: %s timeout waiting for transition\n",
562 pr_debug("powerdomain: completed transition in %d loops\n", c
);
567 /* For dm814x we need to fix up fix GFX pwstst and rstctrl reg offsets */
568 static struct pwrdm_ops ti81xx_pwrdm_operations
= {
569 .pwrdm_set_next_pwrst
= ti81xx_pwrdm_set_next_pwrst
,
570 .pwrdm_read_next_pwrst
= ti81xx_pwrdm_read_next_pwrst
,
571 .pwrdm_read_pwrst
= ti81xx_pwrdm_read_pwrst
,
572 .pwrdm_read_logic_pwrst
= ti81xx_pwrdm_read_logic_pwrst
,
573 .pwrdm_wait_transition
= ti81xx_pwrdm_wait_transition
,
576 void __init
omap3xxx_powerdomains_init(void)
580 if (!cpu_is_omap34xx() && !cpu_is_ti81xx())
583 /* Only 81xx needs custom pwrdm_operations */
584 if (!cpu_is_ti81xx())
585 pwrdm_register_platform_funcs(&omap3_pwrdm_operations
);
589 if (rev
== AM35XX_REV_ES1_0
|| rev
== AM35XX_REV_ES1_1
) {
590 pwrdm_register_pwrdms(powerdomains_am35x
);
591 } else if (rev
== TI8148_REV_ES1_0
|| rev
== TI8148_REV_ES2_0
||
592 rev
== TI8148_REV_ES2_1
) {
593 pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations
);
594 pwrdm_register_pwrdms(powerdomains_ti814x
);
595 } else if (rev
== TI8168_REV_ES1_0
|| rev
== TI8168_REV_ES1_1
596 || rev
== TI8168_REV_ES2_0
|| rev
== TI8168_REV_ES2_1
) {
597 pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations
);
598 pwrdm_register_pwrdms(powerdomains_ti816x
);
600 pwrdm_register_pwrdms(powerdomains_omap3430_common
);
603 case OMAP3430_REV_ES1_0
:
604 pwrdm_register_pwrdms(powerdomains_omap3430es1
);
606 case OMAP3430_REV_ES2_0
:
607 case OMAP3430_REV_ES2_1
:
608 case OMAP3430_REV_ES3_0
:
609 case OMAP3630_REV_ES1_0
:
610 pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0
);
612 case OMAP3430_REV_ES3_1
:
613 case OMAP3430_REV_ES3_1_2
:
614 case OMAP3630_REV_ES1_1
:
615 case OMAP3630_REV_ES1_2
:
616 pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus
);
619 WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
623 pwrdm_complete_init();