1 /* 2 * OMAP4 PRM module functions 3 * 4 * Copyright (C) 2011-2012 Texas Instruments, Inc. 5 * Copyright (C) 2010 Nokia Corporation 6 * Benoît Cousson 7 * Paul Walmsley 8 * Rajendra Nayak <rnayak@ti.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15 #include <linux/kernel.h> 16 #include <linux/delay.h> 17 #include <linux/errno.h> 18 #include <linux/err.h> 19 #include <linux/io.h> 20 21 22 #include "soc.h" 23 #include "iomap.h" 24 #include "common.h" 25 #include "vp.h" 26 #include "prm44xx.h" 27 #include "prm-regbits-44xx.h" 28 #include "prcm44xx.h" 29 #include "prminst44xx.h" 30 #include "powerdomain.h" 31 32 /* Static data */ 33 34 static const struct omap_prcm_irq omap4_prcm_irqs[] = { 35 OMAP_PRCM_IRQ("wkup", 0, 0), 36 OMAP_PRCM_IRQ("io", 9, 1), 37 }; 38 39 static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { 40 .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, 41 .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET, 42 .nr_regs = 2, 43 .irqs = omap4_prcm_irqs, 44 .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs), 45 .irq = 11 + OMAP44XX_IRQ_GIC_START, 46 .read_pending_irqs = &omap44xx_prm_read_pending_irqs, 47 .ocp_barrier = &omap44xx_prm_ocp_barrier, 48 .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen, 49 .restore_irqen = &omap44xx_prm_restore_irqen, 50 .reconfigure_io_chain = &omap44xx_prm_reconfigure_io_chain, 51 }; 52 53 /* 54 * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST 55 * hardware register (which are specific to OMAP44xx SoCs) to reset 56 * source ID bit shifts (which is an OMAP SoC-independent 57 * enumeration) 58 */ 59 static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { 60 { OMAP4430_GLOBAL_WARM_SW_RST_SHIFT, 61 OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT }, 62 { OMAP4430_GLOBAL_COLD_RST_SHIFT, 63 OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT }, 64 { OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT, 65 OMAP_SECU_VIOL_RST_SRC_ID_SHIFT }, 66 { OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, 67 { OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT }, 68 { OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT }, 69 { OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT, 70 OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT }, 71 { OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT, 72 OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT }, 73 { OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT, 74 OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT }, 75 { OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT }, 76 { OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT }, 77 { -1, -1 }, 78 }; 79 80 /* PRM low-level functions */ 81 82 /* Read a register in a CM/PRM instance in the PRM module */ 83 u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) 84 { 85 return readl_relaxed(prm_base + inst + reg); 86 } 87 88 /* Write into a register in a CM/PRM instance in the PRM module */ 89 void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) 90 { 91 writel_relaxed(val, prm_base + inst + reg); 92 } 93 94 /* Read-modify-write a register in a PRM module. Caller must lock */ 95 u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) 96 { 97 u32 v; 98 99 v = omap4_prm_read_inst_reg(inst, reg); 100 v &= ~mask; 101 v |= bits; 102 omap4_prm_write_inst_reg(v, inst, reg); 103 104 return v; 105 } 106 107 /* PRM VP */ 108 109 /* 110 * struct omap4_vp - OMAP4 VP register access description. 111 * @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP 112 * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg 113 */ 114 struct omap4_vp { 115 u32 irqstatus_mpu; 116 u32 tranxdone_status; 117 }; 118 119 static struct omap4_vp omap4_vp[] = { 120 [OMAP4_VP_VDD_MPU_ID] = { 121 .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET, 122 .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK, 123 }, 124 [OMAP4_VP_VDD_IVA_ID] = { 125 .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, 126 .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK, 127 }, 128 [OMAP4_VP_VDD_CORE_ID] = { 129 .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, 130 .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK, 131 }, 132 }; 133 134 u32 omap4_prm_vp_check_txdone(u8 vp_id) 135 { 136 struct omap4_vp *vp = &omap4_vp[vp_id]; 137 u32 irqstatus; 138 139 irqstatus = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, 140 OMAP4430_PRM_OCP_SOCKET_INST, 141 vp->irqstatus_mpu); 142 return irqstatus & vp->tranxdone_status; 143 } 144 145 void omap4_prm_vp_clear_txdone(u8 vp_id) 146 { 147 struct omap4_vp *vp = &omap4_vp[vp_id]; 148 149 omap4_prminst_write_inst_reg(vp->tranxdone_status, 150 OMAP4430_PRM_PARTITION, 151 OMAP4430_PRM_OCP_SOCKET_INST, 152 vp->irqstatus_mpu); 153 }; 154 155 u32 omap4_prm_vcvp_read(u8 offset) 156 { 157 return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, 158 OMAP4430_PRM_DEVICE_INST, offset); 159 } 160 161 void omap4_prm_vcvp_write(u32 val, u8 offset) 162 { 163 omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, 164 OMAP4430_PRM_DEVICE_INST, offset); 165 } 166 167 u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) 168 { 169 return omap4_prminst_rmw_inst_reg_bits(mask, bits, 170 OMAP4430_PRM_PARTITION, 171 OMAP4430_PRM_DEVICE_INST, 172 offset); 173 } 174 175 static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) 176 { 177 u32 mask, st; 178 179 /* XXX read mask from RAM? */ 180 mask = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, 181 irqen_offs); 182 st = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, irqst_offs); 183 184 return mask & st; 185 } 186 187 /** 188 * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events 189 * @events: ptr to two consecutive u32s, preallocated by caller 190 * 191 * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM 192 * MPU IRQs, and store the result into the two u32s pointed to by @events. 193 * No return value. 194 */ 195 void omap44xx_prm_read_pending_irqs(unsigned long *events) 196 { 197 events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, 198 OMAP4_PRM_IRQSTATUS_MPU_OFFSET); 199 200 events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET, 201 OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); 202 } 203 204 /** 205 * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete 206 * 207 * Force any buffered writes to the PRM IP block to complete. Needed 208 * by the PRM IRQ handler, which reads and writes directly to the IP 209 * block, to avoid race conditions after acknowledging or clearing IRQ 210 * bits. No return value. 211 */ 212 void omap44xx_prm_ocp_barrier(void) 213 { 214 omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, 215 OMAP4_REVISION_PRM_OFFSET); 216 } 217 218 /** 219 * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs 220 * @saved_mask: ptr to a u32 array to save IRQENABLE bits 221 * 222 * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to 223 * @saved_mask. @saved_mask must be allocated by the caller. 224 * Intended to be used in the PRM interrupt handler suspend callback. 225 * The OCP barrier is needed to ensure the write to disable PRM 226 * interrupts reaches the PRM before returning; otherwise, spurious 227 * interrupts might occur. No return value. 228 */ 229 void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) 230 { 231 saved_mask[0] = 232 omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, 233 OMAP4_PRM_IRQSTATUS_MPU_OFFSET); 234 saved_mask[1] = 235 omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, 236 OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); 237 238 omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, 239 OMAP4_PRM_IRQENABLE_MPU_OFFSET); 240 omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, 241 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); 242 243 /* OCP barrier */ 244 omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, 245 OMAP4_REVISION_PRM_OFFSET); 246 } 247 248 /** 249 * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args 250 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously 251 * 252 * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from 253 * @saved_mask. Intended to be used in the PRM interrupt handler resume 254 * callback to restore values saved by omap44xx_prm_save_and_clear_irqen(). 255 * No OCP barrier should be needed here; any pending PRM interrupts will fire 256 * once the writes reach the PRM. No return value. 257 */ 258 void omap44xx_prm_restore_irqen(u32 *saved_mask) 259 { 260 omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, 261 OMAP4_PRM_IRQENABLE_MPU_OFFSET); 262 omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_OCP_SOCKET_INST, 263 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); 264 } 265 266 /** 267 * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain 268 * 269 * Clear any previously-latched I/O wakeup events and ensure that the 270 * I/O wakeup gates are aligned with the current mux settings. Works 271 * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then 272 * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted. 273 * No return value. XXX Are the final two steps necessary? 274 */ 275 void omap44xx_prm_reconfigure_io_chain(void) 276 { 277 int i = 0; 278 279 /* Trigger WUCLKIN enable */ 280 omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 281 OMAP4430_WUCLK_CTRL_MASK, 282 OMAP4430_PRM_DEVICE_INST, 283 OMAP4_PRM_IO_PMCTRL_OFFSET); 284 omap_test_timeout( 285 (((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, 286 OMAP4_PRM_IO_PMCTRL_OFFSET) & 287 OMAP4430_WUCLK_STATUS_MASK) >> 288 OMAP4430_WUCLK_STATUS_SHIFT) == 1), 289 MAX_IOPAD_LATCH_TIME, i); 290 if (i == MAX_IOPAD_LATCH_TIME) 291 pr_warn("PRM: I/O chain clock line assertion timed out\n"); 292 293 /* Trigger WUCLKIN disable */ 294 omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0, 295 OMAP4430_PRM_DEVICE_INST, 296 OMAP4_PRM_IO_PMCTRL_OFFSET); 297 omap_test_timeout( 298 (((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, 299 OMAP4_PRM_IO_PMCTRL_OFFSET) & 300 OMAP4430_WUCLK_STATUS_MASK) >> 301 OMAP4430_WUCLK_STATUS_SHIFT) == 0), 302 MAX_IOPAD_LATCH_TIME, i); 303 if (i == MAX_IOPAD_LATCH_TIME) 304 pr_warn("PRM: I/O chain clock line deassertion timed out\n"); 305 306 return; 307 } 308 309 /** 310 * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches 311 * 312 * Activates the I/O wakeup event latches and allows events logged by 313 * those latches to signal a wakeup event to the PRCM. For I/O wakeups 314 * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and 315 * omap44xx_prm_reconfigure_io_chain() must be called. No return value. 316 */ 317 static void __init omap44xx_prm_enable_io_wakeup(void) 318 { 319 omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, 320 OMAP4430_GLOBAL_WUEN_MASK, 321 OMAP4430_PRM_DEVICE_INST, 322 OMAP4_PRM_IO_PMCTRL_OFFSET); 323 } 324 325 /** 326 * omap44xx_prm_read_reset_sources - return the last SoC reset source 327 * 328 * Return a u32 representing the last reset sources of the SoC. The 329 * returned reset source bits are standardized across OMAP SoCs. 330 */ 331 static u32 omap44xx_prm_read_reset_sources(void) 332 { 333 struct prm_reset_src_map *p; 334 u32 r = 0; 335 u32 v; 336 337 v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, 338 OMAP4_RM_RSTST); 339 340 p = omap44xx_prm_reset_src_map; 341 while (p->reg_shift >= 0 && p->std_shift >= 0) { 342 if (v & (1 << p->reg_shift)) 343 r |= 1 << p->std_shift; 344 p++; 345 } 346 347 return r; 348 } 349 350 /** 351 * omap44xx_prm_was_any_context_lost_old - was module hardware context lost? 352 * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION) 353 * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST) 354 * @idx: CONTEXT register offset 355 * 356 * Return 1 if any bits were set in the *_CONTEXT_* register 357 * identified by (@part, @inst, @idx), which means that some context 358 * was lost for that module; otherwise, return 0. 359 */ 360 static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx) 361 { 362 return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0; 363 } 364 365 /** 366 * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags 367 * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION) 368 * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST) 369 * @idx: CONTEXT register offset 370 * 371 * Clear hardware context loss bits for the module identified by 372 * (@part, @inst, @idx). No return value. XXX Writes to reserved bits; 373 * is there a way to avoid this? 374 */ 375 static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst, 376 u16 idx) 377 { 378 omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx); 379 } 380 381 /* Powerdomain low-level functions */ 382 383 static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) 384 { 385 omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK, 386 (pwrst << OMAP_POWERSTATE_SHIFT), 387 pwrdm->prcm_partition, 388 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); 389 return 0; 390 } 391 392 static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) 393 { 394 u32 v; 395 396 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, 397 OMAP4_PM_PWSTCTRL); 398 v &= OMAP_POWERSTATE_MASK; 399 v >>= OMAP_POWERSTATE_SHIFT; 400 401 return v; 402 } 403 404 static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm) 405 { 406 u32 v; 407 408 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, 409 OMAP4_PM_PWSTST); 410 v &= OMAP_POWERSTATEST_MASK; 411 v >>= OMAP_POWERSTATEST_SHIFT; 412 413 return v; 414 } 415 416 static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) 417 { 418 u32 v; 419 420 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, 421 OMAP4_PM_PWSTST); 422 v &= OMAP4430_LASTPOWERSTATEENTERED_MASK; 423 v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT; 424 425 return v; 426 } 427 428 static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) 429 { 430 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK, 431 (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT), 432 pwrdm->prcm_partition, 433 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); 434 return 0; 435 } 436 437 static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) 438 { 439 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK, 440 OMAP4430_LASTPOWERSTATEENTERED_MASK, 441 pwrdm->prcm_partition, 442 pwrdm->prcm_offs, OMAP4_PM_PWSTST); 443 return 0; 444 } 445 446 static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) 447 { 448 u32 v; 449 450 v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK); 451 omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v, 452 pwrdm->prcm_partition, pwrdm->prcm_offs, 453 OMAP4_PM_PWSTCTRL); 454 455 return 0; 456 } 457 458 static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, 459 u8 pwrst) 460 { 461 u32 m; 462 463 m = omap2_pwrdm_get_mem_bank_onstate_mask(bank); 464 465 omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)), 466 pwrdm->prcm_partition, pwrdm->prcm_offs, 467 OMAP4_PM_PWSTCTRL); 468 469 return 0; 470 } 471 472 static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, 473 u8 pwrst) 474 { 475 u32 m; 476 477 m = omap2_pwrdm_get_mem_bank_retst_mask(bank); 478 479 omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)), 480 pwrdm->prcm_partition, pwrdm->prcm_offs, 481 OMAP4_PM_PWSTCTRL); 482 483 return 0; 484 } 485 486 static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) 487 { 488 u32 v; 489 490 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, 491 OMAP4_PM_PWSTST); 492 v &= OMAP4430_LOGICSTATEST_MASK; 493 v >>= OMAP4430_LOGICSTATEST_SHIFT; 494 495 return v; 496 } 497 498 static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) 499 { 500 u32 v; 501 502 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, 503 OMAP4_PM_PWSTCTRL); 504 v &= OMAP4430_LOGICRETSTATE_MASK; 505 v >>= OMAP4430_LOGICRETSTATE_SHIFT; 506 507 return v; 508 } 509 510 /** 511 * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate 512 * @pwrdm: struct powerdomain * to read the state for 513 * 514 * Reads the previous logic powerstate for a powerdomain. This 515 * function must determine the previous logic powerstate by first 516 * checking the previous powerstate for the domain. If that was OFF, 517 * then logic has been lost. If previous state was RETENTION, the 518 * function reads the setting for the next retention logic state to 519 * see the actual value. In every other case, the logic is 520 * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET 521 * depending whether the logic was retained or not. 522 */ 523 static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) 524 { 525 int state; 526 527 state = omap4_pwrdm_read_prev_pwrst(pwrdm); 528 529 if (state == PWRDM_POWER_OFF) 530 return PWRDM_POWER_OFF; 531 532 if (state != PWRDM_POWER_RET) 533 return PWRDM_POWER_RET; 534 535 return omap4_pwrdm_read_logic_retst(pwrdm); 536 } 537 538 static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 539 { 540 u32 m, v; 541 542 m = omap2_pwrdm_get_mem_bank_stst_mask(bank); 543 544 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, 545 OMAP4_PM_PWSTST); 546 v &= m; 547 v >>= __ffs(m); 548 549 return v; 550 } 551 552 static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) 553 { 554 u32 m, v; 555 556 m = omap2_pwrdm_get_mem_bank_retst_mask(bank); 557 558 v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, 559 OMAP4_PM_PWSTCTRL); 560 v &= m; 561 v >>= __ffs(m); 562 563 return v; 564 } 565 566 /** 567 * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate 568 * @pwrdm: struct powerdomain * to read mem powerstate for 569 * @bank: memory bank index 570 * 571 * Reads the previous memory powerstate for a powerdomain. This 572 * function must determine the previous memory powerstate by first 573 * checking the previous powerstate for the domain. If that was OFF, 574 * then logic has been lost. If previous state was RETENTION, the 575 * function reads the setting for the next memory retention state to 576 * see the actual value. In every other case, the logic is 577 * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET 578 * depending whether logic was retained or not. 579 */ 580 static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 581 { 582 int state; 583 584 state = omap4_pwrdm_read_prev_pwrst(pwrdm); 585 586 if (state == PWRDM_POWER_OFF) 587 return PWRDM_POWER_OFF; 588 589 if (state != PWRDM_POWER_RET) 590 return PWRDM_POWER_RET; 591 592 return omap4_pwrdm_read_mem_retst(pwrdm, bank); 593 } 594 595 static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) 596 { 597 u32 c = 0; 598 599 /* 600 * REVISIT: pwrdm_wait_transition() may be better implemented 601 * via a callback and a periodic timer check -- how long do we expect 602 * powerdomain transitions to take? 603 */ 604 605 /* XXX Is this udelay() value meaningful? */ 606 while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition, 607 pwrdm->prcm_offs, 608 OMAP4_PM_PWSTST) & 609 OMAP_INTRANSITION_MASK) && 610 (c++ < PWRDM_TRANSITION_BAILOUT)) 611 udelay(1); 612 613 if (c > PWRDM_TRANSITION_BAILOUT) { 614 pr_err("powerdomain: %s: waited too long to complete transition\n", 615 pwrdm->name); 616 return -EAGAIN; 617 } 618 619 pr_debug("powerdomain: completed transition in %d loops\n", c); 620 621 return 0; 622 } 623 624 static int omap4_check_vcvp(void) 625 { 626 /* No VC/VP on dra7xx devices */ 627 if (soc_is_dra7xx()) 628 return 0; 629 630 return 1; 631 } 632 633 struct pwrdm_ops omap4_pwrdm_operations = { 634 .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, 635 .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst, 636 .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst, 637 .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst, 638 .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange, 639 .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, 640 .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, 641 .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, 642 .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst, 643 .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, 644 .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, 645 .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, 646 .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst, 647 .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, 648 .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, 649 .pwrdm_wait_transition = omap4_pwrdm_wait_transition, 650 .pwrdm_has_voltdm = omap4_check_vcvp, 651 }; 652 653 static int omap44xx_prm_late_init(void); 654 655 /* 656 * XXX document 657 */ 658 static struct prm_ll_data omap44xx_prm_ll_data = { 659 .read_reset_sources = &omap44xx_prm_read_reset_sources, 660 .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, 661 .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, 662 .late_init = &omap44xx_prm_late_init, 663 }; 664 665 int __init omap44xx_prm_init(void) 666 { 667 if (cpu_is_omap44xx()) 668 prm_features |= PRM_HAS_IO_WAKEUP; 669 670 return prm_register(&omap44xx_prm_ll_data); 671 } 672 673 static int omap44xx_prm_late_init(void) 674 { 675 if (!(prm_features & PRM_HAS_IO_WAKEUP)) 676 return 0; 677 678 omap44xx_prm_enable_io_wakeup(); 679 680 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); 681 } 682 683 static void __exit omap44xx_prm_exit(void) 684 { 685 prm_unregister(&omap44xx_prm_ll_data); 686 } 687 __exitcall(omap44xx_prm_exit); 688