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