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