0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/errno.h>
0014 #include <linux/err.h>
0015 #include <linux/io.h>
0016 #include <linux/irq.h>
0017 #include <linux/of_irq.h>
0018
0019 #include "soc.h"
0020 #include "common.h"
0021 #include "vp.h"
0022 #include "powerdomain.h"
0023 #include "prm3xxx.h"
0024 #include "prm2xxx_3xxx.h"
0025 #include "cm2xxx_3xxx.h"
0026 #include "prm-regbits-34xx.h"
0027 #include "cm3xxx.h"
0028 #include "cm-regbits-34xx.h"
0029 #include "clock.h"
0030
0031 static void omap3xxx_prm_read_pending_irqs(unsigned long *events);
0032 static void omap3xxx_prm_ocp_barrier(void);
0033 static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
0034 static void omap3xxx_prm_restore_irqen(u32 *saved_mask);
0035
0036 static const struct omap_prcm_irq omap3_prcm_irqs[] = {
0037 OMAP_PRCM_IRQ("wkup", 0, 0),
0038 OMAP_PRCM_IRQ("io", 9, 1),
0039 };
0040
0041 static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
0042 .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
0043 .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
0044 .nr_regs = 1,
0045 .irqs = omap3_prcm_irqs,
0046 .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
0047 .irq = 11 + OMAP_INTC_START,
0048 .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
0049 .ocp_barrier = &omap3xxx_prm_ocp_barrier,
0050 .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
0051 .restore_irqen = &omap3xxx_prm_restore_irqen,
0052 .reconfigure_io_chain = NULL,
0053 };
0054
0055
0056
0057
0058
0059
0060 static struct prm_reset_src_map omap3xxx_prm_reset_src_map[] = {
0061 { OMAP3430_GLOBAL_COLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
0062 { OMAP3430_GLOBAL_SW_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
0063 { OMAP3430_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
0064 { OMAP3430_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
0065 { OMAP3430_SECURE_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
0066 { OMAP3430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
0067 { OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT,
0068 OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
0069 { OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT,
0070 OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
0071 { OMAP3430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
0072 { OMAP3430_ICECRUSHER_RST_SHIFT, OMAP_ICECRUSHER_RST_SRC_ID_SHIFT },
0073 { -1, -1 },
0074 };
0075
0076
0077
0078
0079
0080
0081
0082 struct omap3_vp {
0083 u32 tranxdone_status;
0084 };
0085
0086 static struct omap3_vp omap3_vp[] = {
0087 [OMAP3_VP_VDD_MPU_ID] = {
0088 .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
0089 },
0090 [OMAP3_VP_VDD_CORE_ID] = {
0091 .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
0092 },
0093 };
0094
0095 #define MAX_VP_ID ARRAY_SIZE(omap3_vp);
0096
0097 static u32 omap3_prm_vp_check_txdone(u8 vp_id)
0098 {
0099 struct omap3_vp *vp = &omap3_vp[vp_id];
0100 u32 irqstatus;
0101
0102 irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
0103 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
0104 return irqstatus & vp->tranxdone_status;
0105 }
0106
0107 static void omap3_prm_vp_clear_txdone(u8 vp_id)
0108 {
0109 struct omap3_vp *vp = &omap3_vp[vp_id];
0110
0111 omap2_prm_write_mod_reg(vp->tranxdone_status,
0112 OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
0113 }
0114
0115 u32 omap3_prm_vcvp_read(u8 offset)
0116 {
0117 return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
0118 }
0119
0120 void omap3_prm_vcvp_write(u32 val, u8 offset)
0121 {
0122 omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
0123 }
0124
0125 u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
0126 {
0127 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137 static void omap3xxx_prm_dpll3_reset(void)
0138 {
0139 omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD,
0140 OMAP2_RM_RSTCTRL);
0141
0142 omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL);
0143 }
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 static void omap3xxx_prm_read_pending_irqs(unsigned long *events)
0154 {
0155 u32 mask, st;
0156
0157
0158 mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
0159 st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
0160
0161 events[0] = mask & st;
0162 }
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172 static void omap3xxx_prm_ocp_barrier(void)
0173 {
0174 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
0175 }
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
0189 {
0190 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
0191 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
0192 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
0193
0194
0195 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
0196 }
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 static void omap3xxx_prm_restore_irqen(u32 *saved_mask)
0209 {
0210 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
0211 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
0212 }
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 static int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask)
0228 {
0229 u32 wkst, fclk, iclk, clken;
0230 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
0231 u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
0232 u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
0233 u16 grpsel_off = (regs == 3) ?
0234 OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
0235 int c = 0;
0236
0237 wkst = omap2_prm_read_mod_reg(module, wkst_off);
0238 wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
0239 wkst &= wkst_mask;
0240 if (wkst) {
0241 iclk = omap2_cm_read_mod_reg(module, iclk_off);
0242 fclk = omap2_cm_read_mod_reg(module, fclk_off);
0243 while (wkst) {
0244 clken = wkst;
0245 omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
0246
0247
0248
0249
0250 if (module == OMAP3430ES2_USBHOST_MOD)
0251 clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
0252 omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
0253 omap2_prm_write_mod_reg(wkst, module, wkst_off);
0254 wkst = omap2_prm_read_mod_reg(module, wkst_off);
0255 wkst &= wkst_mask;
0256 c++;
0257 }
0258 omap2_cm_write_mod_reg(iclk, module, iclk_off);
0259 omap2_cm_write_mod_reg(fclk, module, fclk_off);
0260 }
0261
0262 return c;
0263 }
0264
0265
0266
0267
0268
0269
0270
0271 void __init omap3_prm_reset_modem(void)
0272 {
0273 omap2_prm_write_mod_reg(
0274 OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK |
0275 OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK,
0276 CORE_MOD, OMAP2_RM_RSTCTRL);
0277 omap2_prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL);
0278 }
0279
0280
0281
0282
0283
0284
0285
0286
0287 void __init omap3_prm_init_pm(bool has_uart4, bool has_iva)
0288 {
0289 u32 en_uart4_mask;
0290 u32 grpsel_uart4_mask;
0291
0292
0293
0294
0295
0296
0297 omap2_prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
0298 1 << OMAP_AUTOEXTCLKMODE_SHIFT,
0299 OMAP3430_GR_MOD,
0300 OMAP3_PRM_CLKSRC_CTRL_OFFSET);
0301
0302
0303 omap2_prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK |
0304 OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK,
0305 WKUP_MOD, PM_WKEN);
0306
0307 omap2_prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK |
0308 OMAP3430_GRPSEL_GPT1_MASK |
0309 OMAP3430_GRPSEL_GPT12_MASK,
0310 WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
0311
0312
0313 omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
0314 OMAP3430_DSS_MOD, PM_WKEN);
0315
0316 if (has_uart4) {
0317 en_uart4_mask = OMAP3630_EN_UART4_MASK;
0318 grpsel_uart4_mask = OMAP3630_GRPSEL_UART4_MASK;
0319 } else {
0320 en_uart4_mask = 0;
0321 grpsel_uart4_mask = 0;
0322 }
0323
0324
0325 omap2_prm_write_mod_reg(en_uart4_mask |
0326 OMAP3430_EN_GPIO2_MASK |
0327 OMAP3430_EN_GPIO3_MASK |
0328 OMAP3430_EN_GPIO4_MASK |
0329 OMAP3430_EN_GPIO5_MASK |
0330 OMAP3430_EN_GPIO6_MASK |
0331 OMAP3430_EN_UART3_MASK |
0332 OMAP3430_EN_MCBSP2_MASK |
0333 OMAP3430_EN_MCBSP3_MASK |
0334 OMAP3430_EN_MCBSP4_MASK,
0335 OMAP3430_PER_MOD, PM_WKEN);
0336
0337
0338 omap2_prm_write_mod_reg(grpsel_uart4_mask |
0339 OMAP3430_GRPSEL_GPIO2_MASK |
0340 OMAP3430_GRPSEL_GPIO3_MASK |
0341 OMAP3430_GRPSEL_GPIO4_MASK |
0342 OMAP3430_GRPSEL_GPIO5_MASK |
0343 OMAP3430_GRPSEL_GPIO6_MASK |
0344 OMAP3430_GRPSEL_UART3_MASK |
0345 OMAP3430_GRPSEL_MCBSP2_MASK |
0346 OMAP3430_GRPSEL_MCBSP3_MASK |
0347 OMAP3430_GRPSEL_MCBSP4_MASK,
0348 OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
0349
0350
0351 if (has_iva) {
0352 omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
0353 omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
0354 omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
0355 omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD,
0356 OMAP3430_PM_IVAGRPSEL);
0357 }
0358
0359
0360 omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
0361 omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST);
0362 omap2_prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST);
0363 omap2_prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST);
0364 omap2_prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST);
0365 omap2_prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST);
0366 omap2_prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD,
0367 OMAP2_RM_RSTST);
0368
0369
0370 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
0371
0372
0373 omap3xxx_prm_iva_idle();
0374
0375 omap3_prm_reset_modem();
0376 }
0377
0378
0379
0380
0381
0382
0383
0384 static void omap3430_pre_es3_1_reconfigure_io_chain(void)
0385 {
0386 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
0387 PM_WKEN);
0388 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
0389 PM_WKEN);
0390 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
0391 }
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402 static void omap3_prm_reconfigure_io_chain(void)
0403 {
0404 int i = 0;
0405
0406 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
0407 PM_WKEN);
0408
0409 omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
0410 OMAP3430_ST_IO_CHAIN_MASK,
0411 MAX_IOPAD_LATCH_TIME, i);
0412 if (i == MAX_IOPAD_LATCH_TIME)
0413 pr_warn("PRM: I/O chain clock line assertion timed out\n");
0414
0415 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
0416 PM_WKEN);
0417
0418 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
0419 PM_WKST);
0420
0421 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
0422 }
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 static void omap3xxx_prm_enable_io_wakeup(void)
0434 {
0435 if (prm_features & PRM_HAS_IO_WAKEUP)
0436 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
0437 PM_WKEN);
0438 }
0439
0440
0441
0442
0443
0444
0445
0446 static u32 omap3xxx_prm_read_reset_sources(void)
0447 {
0448 struct prm_reset_src_map *p;
0449 u32 r = 0;
0450 u32 v;
0451
0452 v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
0453
0454 p = omap3xxx_prm_reset_src_map;
0455 while (p->reg_shift >= 0 && p->std_shift >= 0) {
0456 if (v & (1 << p->reg_shift))
0457 r |= 1 << p->std_shift;
0458 p++;
0459 }
0460
0461 return r;
0462 }
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472 void omap3xxx_prm_iva_idle(void)
0473 {
0474
0475 omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
0476
0477
0478 if (!(omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) &
0479 OMAP3430_CLKACTIVITY_IVA2_MASK))
0480 return;
0481
0482
0483 omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
0484 OMAP3430_RST2_IVA2_MASK |
0485 OMAP3430_RST3_IVA2_MASK,
0486 OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
0487
0488
0489 omap2_cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK,
0490 OMAP3430_IVA2_MOD, CM_FCLKEN);
0491
0492
0493 omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
0494
0495
0496 omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
0497
0498
0499 omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
0500 OMAP3430_RST2_IVA2_MASK |
0501 OMAP3430_RST3_IVA2_MASK,
0502 OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
0503 }
0504
0505
0506
0507
0508
0509
0510
0511
0512 int omap3xxx_prm_clear_global_cold_reset(void)
0513 {
0514 if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
0515 OMAP3430_GLOBAL_COLD_RST_MASK) {
0516 omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK,
0517 OMAP3430_GR_MOD,
0518 OMAP3_PRM_RSTST_OFFSET);
0519 return 1;
0520 }
0521
0522 return 0;
0523 }
0524
0525 void omap3_prm_save_scratchpad_contents(u32 *ptr)
0526 {
0527 *ptr++ = omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
0528 OMAP3_PRM_CLKSRC_CTRL_OFFSET);
0529
0530 *ptr++ = omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
0531 OMAP3_PRM_CLKSEL_OFFSET);
0532 }
0533
0534
0535
0536 static int omap3_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
0537 {
0538 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
0539 (pwrst << OMAP_POWERSTATE_SHIFT),
0540 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
0541 return 0;
0542 }
0543
0544 static int omap3_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
0545 {
0546 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0547 OMAP2_PM_PWSTCTRL,
0548 OMAP_POWERSTATE_MASK);
0549 }
0550
0551 static int omap3_pwrdm_read_pwrst(struct powerdomain *pwrdm)
0552 {
0553 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0554 OMAP2_PM_PWSTST,
0555 OMAP_POWERSTATEST_MASK);
0556 }
0557
0558
0559 static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
0560 {
0561 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0562 OMAP3430_PM_PREPWSTST,
0563 OMAP3430_LASTPOWERSTATEENTERED_MASK);
0564 }
0565
0566 static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
0567 {
0568 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0569 OMAP2_PM_PWSTST,
0570 OMAP3430_LOGICSTATEST_MASK);
0571 }
0572
0573 static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
0574 {
0575 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0576 OMAP2_PM_PWSTCTRL,
0577 OMAP3430_LOGICSTATEST_MASK);
0578 }
0579
0580 static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
0581 {
0582 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0583 OMAP3430_PM_PREPWSTST,
0584 OMAP3430_LASTLOGICSTATEENTERED_MASK);
0585 }
0586
0587 static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
0588 {
0589 switch (bank) {
0590 case 0:
0591 return OMAP3430_LASTMEM1STATEENTERED_MASK;
0592 case 1:
0593 return OMAP3430_LASTMEM2STATEENTERED_MASK;
0594 case 2:
0595 return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
0596 case 3:
0597 return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
0598 default:
0599 WARN_ON(1);
0600 return -EEXIST;
0601 }
0602 return 0;
0603 }
0604
0605 static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
0606 {
0607 u32 m;
0608
0609 m = omap3_get_mem_bank_lastmemst_mask(bank);
0610
0611 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
0612 OMAP3430_PM_PREPWSTST, m);
0613 }
0614
0615 static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
0616 {
0617 omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
0618 return 0;
0619 }
0620
0621 static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
0622 {
0623 return omap2_prm_rmw_mod_reg_bits(0,
0624 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
0625 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
0626 }
0627
0628 static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
0629 {
0630 return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
0631 0, pwrdm->prcm_offs,
0632 OMAP2_PM_PWSTCTRL);
0633 }
0634
0635 struct pwrdm_ops omap3_pwrdm_operations = {
0636 .pwrdm_set_next_pwrst = omap3_pwrdm_set_next_pwrst,
0637 .pwrdm_read_next_pwrst = omap3_pwrdm_read_next_pwrst,
0638 .pwrdm_read_pwrst = omap3_pwrdm_read_pwrst,
0639 .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
0640 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
0641 .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,
0642 .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst,
0643 .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst,
0644 .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
0645 .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
0646 .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
0647 .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
0648 .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst,
0649 .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst,
0650 .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar,
0651 .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar,
0652 .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
0653 };
0654
0655
0656
0657
0658
0659 static int omap3xxx_prm_late_init(void);
0660
0661 static struct prm_ll_data omap3xxx_prm_ll_data = {
0662 .read_reset_sources = &omap3xxx_prm_read_reset_sources,
0663 .late_init = &omap3xxx_prm_late_init,
0664 .assert_hardreset = &omap2_prm_assert_hardreset,
0665 .deassert_hardreset = &omap2_prm_deassert_hardreset,
0666 .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted,
0667 .reset_system = &omap3xxx_prm_dpll3_reset,
0668 .clear_mod_irqs = &omap3xxx_prm_clear_mod_irqs,
0669 .vp_check_txdone = &omap3_prm_vp_check_txdone,
0670 .vp_clear_txdone = &omap3_prm_vp_clear_txdone,
0671 };
0672
0673 int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data)
0674 {
0675 omap2_clk_legacy_provider_init(TI_CLKM_PRM,
0676 prm_base.va + OMAP3430_IVA2_MOD);
0677 if (omap3_has_io_wakeup())
0678 prm_features |= PRM_HAS_IO_WAKEUP;
0679
0680 return prm_register(&omap3xxx_prm_ll_data);
0681 }
0682
0683 static const struct of_device_id omap3_prm_dt_match_table[] = {
0684 { .compatible = "ti,omap3-prm" },
0685 { }
0686 };
0687
0688 static int omap3xxx_prm_late_init(void)
0689 {
0690 struct device_node *np;
0691 int irq_num;
0692
0693 if (!(prm_features & PRM_HAS_IO_WAKEUP))
0694 return 0;
0695
0696 if (omap3_has_io_chain_ctrl())
0697 omap3_prcm_irq_setup.reconfigure_io_chain =
0698 omap3_prm_reconfigure_io_chain;
0699 else
0700 omap3_prcm_irq_setup.reconfigure_io_chain =
0701 omap3430_pre_es3_1_reconfigure_io_chain;
0702
0703 np = of_find_matching_node(NULL, omap3_prm_dt_match_table);
0704 if (!np) {
0705 pr_err("PRM: no device tree node for interrupt?\n");
0706
0707 return -ENODEV;
0708 }
0709
0710 irq_num = of_irq_get(np, 0);
0711 of_node_put(np);
0712 if (irq_num == -EPROBE_DEFER)
0713 return irq_num;
0714
0715 omap3_prcm_irq_setup.irq = irq_num;
0716
0717 omap3xxx_prm_enable_io_wakeup();
0718
0719 return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
0720 }
0721
0722 static void __exit omap3xxx_prm_exit(void)
0723 {
0724 prm_unregister(&omap3xxx_prm_ll_data);
0725 }
0726 __exitcall(omap3xxx_prm_exit);