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