0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/kernel.h>
0012 #include <linux/init.h>
0013 #include <linux/bug.h>
0014
0015 #include "soc.h"
0016 #include "powerdomain.h"
0017 #include "powerdomains2xxx_3xxx_data.h"
0018 #include "prcm-common.h"
0019 #include "prm2xxx_3xxx.h"
0020 #include "prm-regbits-34xx.h"
0021 #include "cm2xxx_3xxx.h"
0022 #include "cm-regbits-34xx.h"
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 static struct powerdomain iva2_pwrdm = {
0033 .name = "iva2_pwrdm",
0034 .prcm_offs = OMAP3430_IVA2_MOD,
0035 .pwrsts = PWRSTS_OFF_RET_ON,
0036 .pwrsts_logic_ret = PWRSTS_OFF_RET,
0037 .banks = 4,
0038 .pwrsts_mem_ret = {
0039 [0] = PWRSTS_OFF_RET,
0040 [1] = PWRSTS_OFF_RET,
0041 [2] = PWRSTS_OFF_RET,
0042 [3] = PWRSTS_OFF_RET,
0043 },
0044 .pwrsts_mem_on = {
0045 [0] = PWRSTS_ON,
0046 [1] = PWRSTS_ON,
0047 [2] = PWRSTS_OFF_ON,
0048 [3] = PWRSTS_ON,
0049 },
0050 .voltdm = { .name = "mpu_iva" },
0051 };
0052
0053 static struct powerdomain mpu_3xxx_pwrdm = {
0054 .name = "mpu_pwrdm",
0055 .prcm_offs = MPU_MOD,
0056 .pwrsts = PWRSTS_OFF_RET_ON,
0057 .pwrsts_logic_ret = PWRSTS_OFF_RET,
0058 .flags = PWRDM_HAS_MPU_QUIRK,
0059 .banks = 1,
0060 .pwrsts_mem_ret = {
0061 [0] = PWRSTS_OFF_RET,
0062 },
0063 .pwrsts_mem_on = {
0064 [0] = PWRSTS_OFF_ON,
0065 },
0066 .voltdm = { .name = "mpu_iva" },
0067 };
0068
0069 static struct powerdomain mpu_am35x_pwrdm = {
0070 .name = "mpu_pwrdm",
0071 .prcm_offs = MPU_MOD,
0072 .pwrsts = PWRSTS_ON,
0073 .pwrsts_logic_ret = PWRSTS_ON,
0074 .flags = PWRDM_HAS_MPU_QUIRK,
0075 .banks = 1,
0076 .pwrsts_mem_ret = {
0077 [0] = PWRSTS_ON,
0078 },
0079 .pwrsts_mem_on = {
0080 [0] = PWRSTS_ON,
0081 },
0082 .voltdm = { .name = "mpu_iva" },
0083 };
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
0096 .name = "core_pwrdm",
0097 .prcm_offs = CORE_MOD,
0098 .pwrsts = PWRSTS_OFF_RET_ON,
0099 .pwrsts_logic_ret = PWRSTS_OFF_RET,
0100 .banks = 2,
0101 .pwrsts_mem_ret = {
0102 [0] = PWRSTS_OFF_RET,
0103 [1] = PWRSTS_OFF_RET,
0104 },
0105 .pwrsts_mem_on = {
0106 [0] = PWRSTS_OFF_RET_ON,
0107 [1] = PWRSTS_OFF_RET_ON,
0108 },
0109 .voltdm = { .name = "core" },
0110 };
0111
0112 static struct powerdomain core_3xxx_es3_1_pwrdm = {
0113 .name = "core_pwrdm",
0114 .prcm_offs = CORE_MOD,
0115 .pwrsts = PWRSTS_OFF_RET_ON,
0116 .pwrsts_logic_ret = PWRSTS_OFF_RET,
0117
0118
0119
0120
0121 .flags = PWRDM_HAS_HDWR_SAR,
0122 .banks = 2,
0123 .pwrsts_mem_ret = {
0124 [0] = PWRSTS_OFF_RET,
0125 [1] = PWRSTS_OFF_RET,
0126 },
0127 .pwrsts_mem_on = {
0128 [0] = PWRSTS_OFF_RET_ON,
0129 [1] = PWRSTS_OFF_RET_ON,
0130 },
0131 .voltdm = { .name = "core" },
0132 };
0133
0134 static struct powerdomain core_am35x_pwrdm = {
0135 .name = "core_pwrdm",
0136 .prcm_offs = CORE_MOD,
0137 .pwrsts = PWRSTS_ON,
0138 .pwrsts_logic_ret = PWRSTS_ON,
0139 .banks = 2,
0140 .pwrsts_mem_ret = {
0141 [0] = PWRSTS_ON,
0142 [1] = PWRSTS_ON,
0143 },
0144 .pwrsts_mem_on = {
0145 [0] = PWRSTS_ON,
0146 [1] = PWRSTS_ON,
0147 },
0148 .voltdm = { .name = "core" },
0149 };
0150
0151 static struct powerdomain dss_pwrdm = {
0152 .name = "dss_pwrdm",
0153 .prcm_offs = OMAP3430_DSS_MOD,
0154 .pwrsts = PWRSTS_OFF_RET_ON,
0155 .pwrsts_logic_ret = PWRSTS_RET,
0156 .banks = 1,
0157 .pwrsts_mem_ret = {
0158 [0] = PWRSTS_RET,
0159 },
0160 .pwrsts_mem_on = {
0161 [0] = PWRSTS_ON,
0162 },
0163 .voltdm = { .name = "core" },
0164 };
0165
0166 static struct powerdomain dss_am35x_pwrdm = {
0167 .name = "dss_pwrdm",
0168 .prcm_offs = OMAP3430_DSS_MOD,
0169 .pwrsts = PWRSTS_ON,
0170 .pwrsts_logic_ret = PWRSTS_ON,
0171 .banks = 1,
0172 .pwrsts_mem_ret = {
0173 [0] = PWRSTS_ON,
0174 },
0175 .pwrsts_mem_on = {
0176 [0] = PWRSTS_ON,
0177 },
0178 .voltdm = { .name = "core" },
0179 };
0180
0181
0182
0183
0184
0185
0186 static struct powerdomain sgx_pwrdm = {
0187 .name = "sgx_pwrdm",
0188 .prcm_offs = OMAP3430ES2_SGX_MOD,
0189
0190 .pwrsts = PWRSTS_OFF_ON,
0191 .pwrsts_logic_ret = PWRSTS_RET,
0192 .banks = 1,
0193 .pwrsts_mem_ret = {
0194 [0] = PWRSTS_RET,
0195 },
0196 .pwrsts_mem_on = {
0197 [0] = PWRSTS_ON,
0198 },
0199 .voltdm = { .name = "core" },
0200 };
0201
0202 static struct powerdomain sgx_am35x_pwrdm = {
0203 .name = "sgx_pwrdm",
0204 .prcm_offs = OMAP3430ES2_SGX_MOD,
0205 .pwrsts = PWRSTS_ON,
0206 .pwrsts_logic_ret = PWRSTS_ON,
0207 .banks = 1,
0208 .pwrsts_mem_ret = {
0209 [0] = PWRSTS_ON,
0210 },
0211 .pwrsts_mem_on = {
0212 [0] = PWRSTS_ON,
0213 },
0214 .voltdm = { .name = "core" },
0215 };
0216
0217 static struct powerdomain cam_pwrdm = {
0218 .name = "cam_pwrdm",
0219 .prcm_offs = OMAP3430_CAM_MOD,
0220 .pwrsts = PWRSTS_OFF_RET_ON,
0221 .pwrsts_logic_ret = PWRSTS_RET,
0222 .banks = 1,
0223 .pwrsts_mem_ret = {
0224 [0] = PWRSTS_RET,
0225 },
0226 .pwrsts_mem_on = {
0227 [0] = PWRSTS_ON,
0228 },
0229 .voltdm = { .name = "core" },
0230 };
0231
0232 static struct powerdomain per_pwrdm = {
0233 .name = "per_pwrdm",
0234 .prcm_offs = OMAP3430_PER_MOD,
0235 .pwrsts = PWRSTS_OFF_RET_ON,
0236 .pwrsts_logic_ret = PWRSTS_OFF_RET,
0237 .banks = 1,
0238 .pwrsts_mem_ret = {
0239 [0] = PWRSTS_RET,
0240 },
0241 .pwrsts_mem_on = {
0242 [0] = PWRSTS_ON,
0243 },
0244 .voltdm = { .name = "core" },
0245 };
0246
0247 static struct powerdomain per_am35x_pwrdm = {
0248 .name = "per_pwrdm",
0249 .prcm_offs = OMAP3430_PER_MOD,
0250 .pwrsts = PWRSTS_ON,
0251 .pwrsts_logic_ret = PWRSTS_ON,
0252 .banks = 1,
0253 .pwrsts_mem_ret = {
0254 [0] = PWRSTS_ON,
0255 },
0256 .pwrsts_mem_on = {
0257 [0] = PWRSTS_ON,
0258 },
0259 .voltdm = { .name = "core" },
0260 };
0261
0262 static struct powerdomain emu_pwrdm = {
0263 .name = "emu_pwrdm",
0264 .prcm_offs = OMAP3430_EMU_MOD,
0265 .voltdm = { .name = "core" },
0266 };
0267
0268 static struct powerdomain neon_pwrdm = {
0269 .name = "neon_pwrdm",
0270 .prcm_offs = OMAP3430_NEON_MOD,
0271 .pwrsts = PWRSTS_OFF_RET_ON,
0272 .pwrsts_logic_ret = PWRSTS_RET,
0273 .voltdm = { .name = "mpu_iva" },
0274 };
0275
0276 static struct powerdomain neon_am35x_pwrdm = {
0277 .name = "neon_pwrdm",
0278 .prcm_offs = OMAP3430_NEON_MOD,
0279 .pwrsts = PWRSTS_ON,
0280 .pwrsts_logic_ret = PWRSTS_ON,
0281 .voltdm = { .name = "mpu_iva" },
0282 };
0283
0284 static struct powerdomain usbhost_pwrdm = {
0285 .name = "usbhost_pwrdm",
0286 .prcm_offs = OMAP3430ES2_USBHOST_MOD,
0287 .pwrsts = PWRSTS_OFF_RET_ON,
0288 .pwrsts_logic_ret = PWRSTS_RET,
0289
0290
0291
0292
0293
0294
0295
0296 .banks = 1,
0297 .pwrsts_mem_ret = {
0298 [0] = PWRSTS_RET,
0299 },
0300 .pwrsts_mem_on = {
0301 [0] = PWRSTS_ON,
0302 },
0303 .voltdm = { .name = "core" },
0304 };
0305
0306 static struct powerdomain dpll1_pwrdm = {
0307 .name = "dpll1_pwrdm",
0308 .prcm_offs = MPU_MOD,
0309 .voltdm = { .name = "mpu_iva" },
0310 };
0311
0312 static struct powerdomain dpll2_pwrdm = {
0313 .name = "dpll2_pwrdm",
0314 .prcm_offs = OMAP3430_IVA2_MOD,
0315 .voltdm = { .name = "mpu_iva" },
0316 };
0317
0318 static struct powerdomain dpll3_pwrdm = {
0319 .name = "dpll3_pwrdm",
0320 .prcm_offs = PLL_MOD,
0321 .voltdm = { .name = "core" },
0322 };
0323
0324 static struct powerdomain dpll4_pwrdm = {
0325 .name = "dpll4_pwrdm",
0326 .prcm_offs = PLL_MOD,
0327 .voltdm = { .name = "core" },
0328 };
0329
0330 static struct powerdomain dpll5_pwrdm = {
0331 .name = "dpll5_pwrdm",
0332 .prcm_offs = PLL_MOD,
0333 .voltdm = { .name = "core" },
0334 };
0335
0336 static struct powerdomain alwon_81xx_pwrdm = {
0337 .name = "alwon_pwrdm",
0338 .prcm_offs = TI81XX_PRM_ALWON_MOD,
0339 .pwrsts = PWRSTS_OFF_ON,
0340 .voltdm = { .name = "core" },
0341 };
0342
0343 static struct powerdomain device_81xx_pwrdm = {
0344 .name = "device_pwrdm",
0345 .prcm_offs = TI81XX_PRM_DEVICE_MOD,
0346 .voltdm = { .name = "core" },
0347 };
0348
0349 static struct powerdomain gem_814x_pwrdm = {
0350 .name = "gem_pwrdm",
0351 .prcm_offs = TI814X_PRM_DSP_MOD,
0352 .pwrsts = PWRSTS_OFF_ON,
0353 .voltdm = { .name = "dsp" },
0354 };
0355
0356 static struct powerdomain ivahd_814x_pwrdm = {
0357 .name = "ivahd_pwrdm",
0358 .prcm_offs = TI814X_PRM_HDVICP_MOD,
0359 .pwrsts = PWRSTS_OFF_ON,
0360 .voltdm = { .name = "iva" },
0361 };
0362
0363 static struct powerdomain hdvpss_814x_pwrdm = {
0364 .name = "hdvpss_pwrdm",
0365 .prcm_offs = TI814X_PRM_HDVPSS_MOD,
0366 .pwrsts = PWRSTS_OFF_ON,
0367 .voltdm = { .name = "dsp" },
0368 };
0369
0370 static struct powerdomain sgx_814x_pwrdm = {
0371 .name = "sgx_pwrdm",
0372 .prcm_offs = TI814X_PRM_GFX_MOD,
0373 .pwrsts = PWRSTS_OFF_ON,
0374 .voltdm = { .name = "core" },
0375 };
0376
0377 static struct powerdomain isp_814x_pwrdm = {
0378 .name = "isp_pwrdm",
0379 .prcm_offs = TI814X_PRM_ISP_MOD,
0380 .pwrsts = PWRSTS_OFF_ON,
0381 .voltdm = { .name = "core" },
0382 };
0383
0384 static struct powerdomain active_81xx_pwrdm = {
0385 .name = "active_pwrdm",
0386 .prcm_offs = TI816X_PRM_ACTIVE_MOD,
0387 .pwrsts = PWRSTS_OFF_ON,
0388 .voltdm = { .name = "core" },
0389 };
0390
0391 static struct powerdomain default_81xx_pwrdm = {
0392 .name = "default_pwrdm",
0393 .prcm_offs = TI81XX_PRM_DEFAULT_MOD,
0394 .pwrsts = PWRSTS_OFF_ON,
0395 .voltdm = { .name = "core" },
0396 };
0397
0398 static struct powerdomain ivahd0_816x_pwrdm = {
0399 .name = "ivahd0_pwrdm",
0400 .prcm_offs = TI816X_PRM_IVAHD0_MOD,
0401 .pwrsts = PWRSTS_OFF_ON,
0402 .voltdm = { .name = "mpu_iva" },
0403 };
0404
0405 static struct powerdomain ivahd1_816x_pwrdm = {
0406 .name = "ivahd1_pwrdm",
0407 .prcm_offs = TI816X_PRM_IVAHD1_MOD,
0408 .pwrsts = PWRSTS_OFF_ON,
0409 .voltdm = { .name = "mpu_iva" },
0410 };
0411
0412 static struct powerdomain ivahd2_816x_pwrdm = {
0413 .name = "ivahd2_pwrdm",
0414 .prcm_offs = TI816X_PRM_IVAHD2_MOD,
0415 .pwrsts = PWRSTS_OFF_ON,
0416 .voltdm = { .name = "mpu_iva" },
0417 };
0418
0419 static struct powerdomain sgx_816x_pwrdm = {
0420 .name = "sgx_pwrdm",
0421 .prcm_offs = TI816X_PRM_SGX_MOD,
0422 .pwrsts = PWRSTS_OFF_ON,
0423 .voltdm = { .name = "core" },
0424 };
0425
0426
0427 static struct powerdomain *powerdomains_omap3430_common[] __initdata = {
0428 &wkup_omap2_pwrdm,
0429 &iva2_pwrdm,
0430 &mpu_3xxx_pwrdm,
0431 &neon_pwrdm,
0432 &cam_pwrdm,
0433 &dss_pwrdm,
0434 &per_pwrdm,
0435 &emu_pwrdm,
0436 &dpll1_pwrdm,
0437 &dpll2_pwrdm,
0438 &dpll3_pwrdm,
0439 &dpll4_pwrdm,
0440 NULL
0441 };
0442
0443 static struct powerdomain *powerdomains_omap3430es1[] __initdata = {
0444 &gfx_omap2_pwrdm,
0445 &core_3xxx_pre_es3_1_pwrdm,
0446 NULL
0447 };
0448
0449
0450 static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = {
0451 &core_3xxx_pre_es3_1_pwrdm,
0452 &sgx_pwrdm,
0453 &usbhost_pwrdm,
0454 &dpll5_pwrdm,
0455 NULL
0456 };
0457
0458
0459 static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
0460 &core_3xxx_es3_1_pwrdm,
0461 &sgx_pwrdm,
0462 &usbhost_pwrdm,
0463 &dpll5_pwrdm,
0464 NULL
0465 };
0466
0467 static struct powerdomain *powerdomains_am35x[] __initdata = {
0468 &wkup_omap2_pwrdm,
0469 &mpu_am35x_pwrdm,
0470 &neon_am35x_pwrdm,
0471 &core_am35x_pwrdm,
0472 &sgx_am35x_pwrdm,
0473 &dss_am35x_pwrdm,
0474 &per_am35x_pwrdm,
0475 &emu_pwrdm,
0476 &dpll1_pwrdm,
0477 &dpll3_pwrdm,
0478 &dpll4_pwrdm,
0479 &dpll5_pwrdm,
0480 NULL
0481 };
0482
0483 static struct powerdomain *powerdomains_ti814x[] __initdata = {
0484 &alwon_81xx_pwrdm,
0485 &device_81xx_pwrdm,
0486 &active_81xx_pwrdm,
0487 &default_81xx_pwrdm,
0488 &gem_814x_pwrdm,
0489 &ivahd_814x_pwrdm,
0490 &hdvpss_814x_pwrdm,
0491 &sgx_814x_pwrdm,
0492 &isp_814x_pwrdm,
0493 NULL
0494 };
0495
0496 static struct powerdomain *powerdomains_ti816x[] __initdata = {
0497 &alwon_81xx_pwrdm,
0498 &device_81xx_pwrdm,
0499 &active_81xx_pwrdm,
0500 &default_81xx_pwrdm,
0501 &ivahd0_816x_pwrdm,
0502 &ivahd1_816x_pwrdm,
0503 &ivahd2_816x_pwrdm,
0504 &sgx_816x_pwrdm,
0505 NULL
0506 };
0507
0508
0509 #define TI81XX_PM_PWSTCTRL 0x0000
0510 #define TI81XX_RM_RSTCTRL 0x0010
0511 #define TI81XX_PM_PWSTST 0x0004
0512
0513 static int ti81xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
0514 {
0515 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
0516 (pwrst << OMAP_POWERSTATE_SHIFT),
0517 pwrdm->prcm_offs, TI81XX_PM_PWSTCTRL);
0518 return 0;
0519 }
0520
0521 static int ti81xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
0522 {
0523 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0524 TI81XX_PM_PWSTCTRL,
0525 OMAP_POWERSTATE_MASK);
0526 }
0527
0528 static int ti81xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
0529 {
0530 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0531 (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
0532 TI81XX_PM_PWSTST,
0533 OMAP_POWERSTATEST_MASK);
0534 }
0535
0536 static int ti81xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
0537 {
0538 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0539 (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
0540 TI81XX_PM_PWSTST,
0541 OMAP3430_LOGICSTATEST_MASK);
0542 }
0543
0544 static int ti81xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
0545 {
0546 u32 c = 0;
0547
0548 while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs,
0549 (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
0550 TI81XX_PM_PWSTST) &
0551 OMAP_INTRANSITION_MASK) &&
0552 (c++ < PWRDM_TRANSITION_BAILOUT))
0553 udelay(1);
0554
0555 if (c > PWRDM_TRANSITION_BAILOUT) {
0556 pr_err("powerdomain: %s timeout waiting for transition\n",
0557 pwrdm->name);
0558 return -EAGAIN;
0559 }
0560
0561 pr_debug("powerdomain: completed transition in %d loops\n", c);
0562
0563 return 0;
0564 }
0565
0566
0567 static struct pwrdm_ops ti81xx_pwrdm_operations = {
0568 .pwrdm_set_next_pwrst = ti81xx_pwrdm_set_next_pwrst,
0569 .pwrdm_read_next_pwrst = ti81xx_pwrdm_read_next_pwrst,
0570 .pwrdm_read_pwrst = ti81xx_pwrdm_read_pwrst,
0571 .pwrdm_read_logic_pwrst = ti81xx_pwrdm_read_logic_pwrst,
0572 .pwrdm_wait_transition = ti81xx_pwrdm_wait_transition,
0573 };
0574
0575 void __init omap3xxx_powerdomains_init(void)
0576 {
0577 unsigned int rev;
0578
0579 if (!cpu_is_omap34xx() && !cpu_is_ti81xx())
0580 return;
0581
0582
0583 if (!cpu_is_ti81xx())
0584 pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
0585
0586 rev = omap_rev();
0587
0588 if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
0589 pwrdm_register_pwrdms(powerdomains_am35x);
0590 } else if (rev == TI8148_REV_ES1_0 || rev == TI8148_REV_ES2_0 ||
0591 rev == TI8148_REV_ES2_1) {
0592 pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
0593 pwrdm_register_pwrdms(powerdomains_ti814x);
0594 } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1
0595 || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) {
0596 pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
0597 pwrdm_register_pwrdms(powerdomains_ti816x);
0598 } else {
0599 pwrdm_register_pwrdms(powerdomains_omap3430_common);
0600
0601 switch (rev) {
0602 case OMAP3430_REV_ES1_0:
0603 pwrdm_register_pwrdms(powerdomains_omap3430es1);
0604 break;
0605 case OMAP3430_REV_ES2_0:
0606 case OMAP3430_REV_ES2_1:
0607 case OMAP3430_REV_ES3_0:
0608 case OMAP3630_REV_ES1_0:
0609 pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
0610 break;
0611 case OMAP3430_REV_ES3_1:
0612 case OMAP3430_REV_ES3_1_2:
0613 case OMAP3630_REV_ES1_1:
0614 case OMAP3630_REV_ES1_2:
0615 pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
0616 break;
0617 default:
0618 WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
0619 }
0620 }
0621
0622 pwrdm_complete_init();
0623 }