1 /* 2 * OMAP3xxx PRM module functions 3 * 4 * Copyright (C) 2010-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/errno.h> 17 #include <linux/err.h> 18 #include <linux/io.h> 19 #include <linux/irq.h> 20 21 #include "common.h" 22 #include <plat/cpu.h> 23 24 #include "vp.h" 25 #include "powerdomain.h" 26 #include "prm3xxx.h" 27 #include "prm2xxx_3xxx.h" 28 #include "cm2xxx_3xxx.h" 29 #include "prm-regbits-34xx.h" 30 31 static const struct omap_prcm_irq omap3_prcm_irqs[] = { 32 OMAP_PRCM_IRQ("wkup", 0, 0), 33 OMAP_PRCM_IRQ("io", 9, 1), 34 }; 35 36 static struct omap_prcm_irq_setup omap3_prcm_irq_setup = { 37 .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET, 38 .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET, 39 .nr_regs = 1, 40 .irqs = omap3_prcm_irqs, 41 .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs), 42 .irq = 11 + OMAP_INTC_START, 43 .read_pending_irqs = &omap3xxx_prm_read_pending_irqs, 44 .ocp_barrier = &omap3xxx_prm_ocp_barrier, 45 .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen, 46 .restore_irqen = &omap3xxx_prm_restore_irqen, 47 }; 48 49 /* 50 * omap3_prm_reset_src_map - map from bits in the PRM_RSTST hardware 51 * register (which are specific to OMAP3xxx SoCs) to reset source ID 52 * bit shifts (which is an OMAP SoC-independent enumeration) 53 */ 54 static struct prm_reset_src_map omap3xxx_prm_reset_src_map[] = { 55 { OMAP3430_GLOBAL_COLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT }, 56 { OMAP3430_GLOBAL_SW_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT }, 57 { OMAP3430_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT }, 58 { OMAP3430_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, 59 { OMAP3430_SECURE_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, 60 { OMAP3430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT }, 61 { OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT, 62 OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT }, 63 { OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT, 64 OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT }, 65 { OMAP3430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT }, 66 { OMAP3430_ICECRUSHER_RST_SHIFT, OMAP_ICECRUSHER_RST_SRC_ID_SHIFT }, 67 { -1, -1 }, 68 }; 69 70 /* PRM VP */ 71 72 /* 73 * struct omap3_vp - OMAP3 VP register access description. 74 * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg 75 */ 76 struct omap3_vp { 77 u32 tranxdone_status; 78 }; 79 80 static struct omap3_vp omap3_vp[] = { 81 [OMAP3_VP_VDD_MPU_ID] = { 82 .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK, 83 }, 84 [OMAP3_VP_VDD_CORE_ID] = { 85 .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK, 86 }, 87 }; 88 89 #define MAX_VP_ID ARRAY_SIZE(omap3_vp); 90 91 u32 omap3_prm_vp_check_txdone(u8 vp_id) 92 { 93 struct omap3_vp *vp = &omap3_vp[vp_id]; 94 u32 irqstatus; 95 96 irqstatus = omap2_prm_read_mod_reg(OCP_MOD, 97 OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 98 return irqstatus & vp->tranxdone_status; 99 } 100 101 void omap3_prm_vp_clear_txdone(u8 vp_id) 102 { 103 struct omap3_vp *vp = &omap3_vp[vp_id]; 104 105 omap2_prm_write_mod_reg(vp->tranxdone_status, 106 OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 107 } 108 109 u32 omap3_prm_vcvp_read(u8 offset) 110 { 111 return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset); 112 } 113 114 void omap3_prm_vcvp_write(u32 val, u8 offset) 115 { 116 omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset); 117 } 118 119 u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) 120 { 121 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset); 122 } 123 124 /** 125 * omap3xxx_prm_dpll3_reset - use DPLL3 reset to reboot the OMAP SoC 126 * 127 * Set the DPLL3 reset bit, which should reboot the SoC. This is the 128 * recommended way to restart the SoC, considering Errata i520. No 129 * return value. 130 */ 131 void omap3xxx_prm_dpll3_reset(void) 132 { 133 omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD, 134 OMAP2_RM_RSTCTRL); 135 /* OCP barrier */ 136 omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL); 137 } 138 139 /** 140 * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events 141 * @events: ptr to a u32, preallocated by caller 142 * 143 * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM 144 * MPU IRQs, and store the result into the u32 pointed to by @events. 145 * No return value. 146 */ 147 void omap3xxx_prm_read_pending_irqs(unsigned long *events) 148 { 149 u32 mask, st; 150 151 /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */ 152 mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); 153 st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 154 155 events[0] = mask & st; 156 } 157 158 /** 159 * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete 160 * 161 * Force any buffered writes to the PRM IP block to complete. Needed 162 * by the PRM IRQ handler, which reads and writes directly to the IP 163 * block, to avoid race conditions after acknowledging or clearing IRQ 164 * bits. No return value. 165 */ 166 void omap3xxx_prm_ocp_barrier(void) 167 { 168 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); 169 } 170 171 /** 172 * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg 173 * @saved_mask: ptr to a u32 array to save IRQENABLE bits 174 * 175 * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask 176 * must be allocated by the caller. Intended to be used in the PRM 177 * interrupt handler suspend callback. The OCP barrier is needed to 178 * ensure the write to disable PRM interrupts reaches the PRM before 179 * returning; otherwise, spurious interrupts might occur. No return 180 * value. 181 */ 182 void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) 183 { 184 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD, 185 OMAP3_PRM_IRQENABLE_MPU_OFFSET); 186 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); 187 188 /* OCP barrier */ 189 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); 190 } 191 192 /** 193 * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args 194 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously 195 * 196 * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended 197 * to be used in the PRM interrupt handler resume callback to restore 198 * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP 199 * barrier should be needed here; any pending PRM interrupts will fire 200 * once the writes reach the PRM. No return value. 201 */ 202 void omap3xxx_prm_restore_irqen(u32 *saved_mask) 203 { 204 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD, 205 OMAP3_PRM_IRQENABLE_MPU_OFFSET); 206 } 207 208 /** 209 * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain 210 * 211 * Clear any previously-latched I/O wakeup events and ensure that the 212 * I/O wakeup gates are aligned with the current mux settings. Works 213 * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then 214 * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No 215 * return value. 216 */ 217 void omap3xxx_prm_reconfigure_io_chain(void) 218 { 219 int i = 0; 220 221 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, 222 PM_WKEN); 223 224 omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) & 225 OMAP3430_ST_IO_CHAIN_MASK, 226 MAX_IOPAD_LATCH_TIME, i); 227 if (i == MAX_IOPAD_LATCH_TIME) 228 pr_warn("PRM: I/O chain clock line assertion timed out\n"); 229 230 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, 231 PM_WKEN); 232 233 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD, 234 PM_WKST); 235 236 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST); 237 } 238 239 /** 240 * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches 241 * 242 * Activates the I/O wakeup event latches and allows events logged by 243 * those latches to signal a wakeup event to the PRCM. For I/O 244 * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux 245 * registers, and omap3xxx_prm_reconfigure_io_chain() must be called. 246 * No return value. 247 */ 248 static void __init omap3xxx_prm_enable_io_wakeup(void) 249 { 250 if (omap3_has_io_wakeup()) 251 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, 252 PM_WKEN); 253 } 254 255 /** 256 * omap3xxx_prm_read_reset_sources - return the last SoC reset source 257 * 258 * Return a u32 representing the last reset sources of the SoC. The 259 * returned reset source bits are standardized across OMAP SoCs. 260 */ 261 static u32 omap3xxx_prm_read_reset_sources(void) 262 { 263 struct prm_reset_src_map *p; 264 u32 r = 0; 265 u32 v; 266 267 v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST); 268 269 p = omap3xxx_prm_reset_src_map; 270 while (p->reg_shift >= 0 && p->std_shift >= 0) { 271 if (v & (1 << p->reg_shift)) 272 r |= 1 << p->std_shift; 273 p++; 274 } 275 276 return r; 277 } 278 279 /* Powerdomain low-level functions */ 280 281 /* Applicable only for OMAP3. Not supported on OMAP2 */ 282 static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) 283 { 284 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, 285 OMAP3430_PM_PREPWSTST, 286 OMAP3430_LASTPOWERSTATEENTERED_MASK); 287 } 288 289 static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) 290 { 291 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, 292 OMAP2_PM_PWSTST, 293 OMAP3430_LOGICSTATEST_MASK); 294 } 295 296 static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm) 297 { 298 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, 299 OMAP2_PM_PWSTCTRL, 300 OMAP3430_LOGICSTATEST_MASK); 301 } 302 303 static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) 304 { 305 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, 306 OMAP3430_PM_PREPWSTST, 307 OMAP3430_LASTLOGICSTATEENTERED_MASK); 308 } 309 310 static int omap3_get_mem_bank_lastmemst_mask(u8 bank) 311 { 312 switch (bank) { 313 case 0: 314 return OMAP3430_LASTMEM1STATEENTERED_MASK; 315 case 1: 316 return OMAP3430_LASTMEM2STATEENTERED_MASK; 317 case 2: 318 return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK; 319 case 3: 320 return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK; 321 default: 322 WARN_ON(1); /* should never happen */ 323 return -EEXIST; 324 } 325 return 0; 326 } 327 328 static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) 329 { 330 u32 m; 331 332 m = omap3_get_mem_bank_lastmemst_mask(bank); 333 334 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, 335 OMAP3430_PM_PREPWSTST, m); 336 } 337 338 static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) 339 { 340 omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); 341 return 0; 342 } 343 344 static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) 345 { 346 return omap2_prm_rmw_mod_reg_bits(0, 347 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 348 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); 349 } 350 351 static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) 352 { 353 return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 354 0, pwrdm->prcm_offs, 355 OMAP2_PM_PWSTCTRL); 356 } 357 358 struct pwrdm_ops omap3_pwrdm_operations = { 359 .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, 360 .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, 361 .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst, 362 .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst, 363 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, 364 .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst, 365 .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst, 366 .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst, 367 .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst, 368 .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst, 369 .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst, 370 .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst, 371 .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst, 372 .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst, 373 .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar, 374 .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar, 375 .pwrdm_wait_transition = omap2_pwrdm_wait_transition, 376 }; 377 378 /* 379 * 380 */ 381 382 static struct prm_ll_data omap3xxx_prm_ll_data = { 383 .read_reset_sources = &omap3xxx_prm_read_reset_sources, 384 }; 385 386 int __init omap3xxx_prm_init(void) 387 { 388 if (!cpu_is_omap34xx()) 389 return 0; 390 391 return prm_register(&omap3xxx_prm_ll_data); 392 } 393 394 static int __init omap3xxx_prm_late_init(void) 395 { 396 int ret; 397 398 if (!cpu_is_omap34xx()) 399 return 0; 400 401 omap3xxx_prm_enable_io_wakeup(); 402 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); 403 if (!ret) 404 irq_set_status_flags(omap_prcm_event_to_irq("io"), 405 IRQ_NOAUTOEN); 406 407 return ret; 408 } 409 subsys_initcall(omap3xxx_prm_late_init); 410 411 static void __exit omap3xxx_prm_exit(void) 412 { 413 if (!cpu_is_omap34xx()) 414 return; 415 416 /* Should never happen */ 417 WARN(prm_unregister(&omap3xxx_prm_ll_data), 418 "%s: prm_ll_data function pointer mismatch\n", __func__); 419 } 420 __exitcall(omap3xxx_prm_exit); 421