diff options
author | Tony Lindgren <tony@atomide.com> | 2014-07-15 10:00:00 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2014-07-15 10:00:00 -0400 |
commit | 81c6d80661e07d1ecd6c6ac6b7136edac5209bab (patch) | |
tree | 96ac9f06fe73f0da16c0139c047135caf5b3907d | |
parent | 6bf58859591371b247131e1cba53f18ffecdce06 (diff) | |
parent | ba12c24286296159a1271eb19f2fc5c2ef59fbde (diff) |
Merge branch 'for-v3.17/cm-prm-cleanup' of https://github.com/t-kristo/linux-pm into omap-for-v3.17/soc
-rw-r--r-- | arch/arm/mach-omap2/control.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-omap2/control.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm24xx.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 218 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm2xxx.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm2xxx.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm3xxx.c | 233 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm3xxx.h | 6 |
8 files changed, 329 insertions, 240 deletions
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 751f3549bf6f..f4796c002070 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c | |||
@@ -44,8 +44,7 @@ struct omap3_scratchpad { | |||
44 | }; | 44 | }; |
45 | 45 | ||
46 | struct omap3_scratchpad_prcm_block { | 46 | struct omap3_scratchpad_prcm_block { |
47 | u32 prm_clksrc_ctrl; | 47 | u32 prm_contents[2]; |
48 | u32 prm_clksel; | ||
49 | u32 cm_contents[11]; | 48 | u32 cm_contents[11]; |
50 | u32 prcm_block_size; | 49 | u32 prcm_block_size; |
51 | }; | 50 | }; |
@@ -282,13 +281,9 @@ void omap3_clear_scratchpad_contents(void) | |||
282 | void __iomem *v_addr; | 281 | void __iomem *v_addr; |
283 | u32 offset = 0; | 282 | u32 offset = 0; |
284 | v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM); | 283 | v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM); |
285 | if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & | 284 | if (omap3xxx_prm_clear_global_cold_reset()) { |
286 | OMAP3430_GLOBAL_COLD_RST_MASK) { | ||
287 | for ( ; offset <= max_offset; offset += 0x4) | 285 | for ( ; offset <= max_offset; offset += 0x4) |
288 | writel_relaxed(0x0, (v_addr + offset)); | 286 | writel_relaxed(0x0, (v_addr + offset)); |
289 | omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK, | ||
290 | OMAP3430_GR_MOD, | ||
291 | OMAP3_PRM_RSTST_OFFSET); | ||
292 | } | 287 | } |
293 | } | 288 | } |
294 | 289 | ||
@@ -331,13 +326,7 @@ void omap3_save_scratchpad_contents(void) | |||
331 | scratchpad_contents.sdrc_block_offset = 0x64; | 326 | scratchpad_contents.sdrc_block_offset = 0x64; |
332 | 327 | ||
333 | /* Populate the PRCM block contents */ | 328 | /* Populate the PRCM block contents */ |
334 | prcm_block_contents.prm_clksrc_ctrl = | 329 | omap3_prm_save_scratchpad_contents(prcm_block_contents.prm_contents); |
335 | omap2_prm_read_mod_reg(OMAP3430_GR_MOD, | ||
336 | OMAP3_PRM_CLKSRC_CTRL_OFFSET); | ||
337 | prcm_block_contents.prm_clksel = | ||
338 | omap2_prm_read_mod_reg(OMAP3430_CCR_MOD, | ||
339 | OMAP3_PRM_CLKSEL_OFFSET); | ||
340 | |||
341 | omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents); | 330 | omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents); |
342 | 331 | ||
343 | prcm_block_contents.prcm_block_size = 0x0; | 332 | prcm_block_contents.prcm_block_size = 0x0; |
@@ -575,9 +564,50 @@ int omap3_ctrl_save_padconf(void) | |||
575 | * Sets the bootmode for IVA2 to idle. This is needed by the PM code to | 564 | * Sets the bootmode for IVA2 to idle. This is needed by the PM code to |
576 | * force disable IVA2 so that it does not prevent any low-power states. | 565 | * force disable IVA2 so that it does not prevent any low-power states. |
577 | */ | 566 | */ |
578 | void omap3_ctrl_set_iva_bootmode_idle(void) | 567 | static void __init omap3_ctrl_set_iva_bootmode_idle(void) |
579 | { | 568 | { |
580 | omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE, | 569 | omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE, |
581 | OMAP343X_CONTROL_IVA2_BOOTMOD); | 570 | OMAP343X_CONTROL_IVA2_BOOTMOD); |
582 | } | 571 | } |
572 | |||
573 | /** | ||
574 | * omap3_ctrl_setup_d2d_padconf - setup stacked modem pads for idle | ||
575 | * | ||
576 | * Sets up the pads controlling the stacked modem in such way that the | ||
577 | * device can enter idle. | ||
578 | */ | ||
579 | static void __init omap3_ctrl_setup_d2d_padconf(void) | ||
580 | { | ||
581 | u16 mask, padconf; | ||
582 | |||
583 | /* | ||
584 | * In a stand alone OMAP3430 where there is not a stacked | ||
585 | * modem for the D2D Idle Ack and D2D MStandby must be pulled | ||
586 | * high. S CONTROL_PADCONF_SAD2D_IDLEACK and | ||
587 | * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. | ||
588 | */ | ||
589 | mask = (1 << 4) | (1 << 3); /* pull-up, enabled */ | ||
590 | padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY); | ||
591 | padconf |= mask; | ||
592 | omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY); | ||
593 | |||
594 | padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK); | ||
595 | padconf |= mask; | ||
596 | omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK); | ||
597 | } | ||
598 | |||
599 | /** | ||
600 | * omap3_ctrl_init - does static initializations for control module | ||
601 | * | ||
602 | * Initializes system control module. This sets up the sysconfig autoidle, | ||
603 | * and sets up modem and iva2 so that they can be idled properly. | ||
604 | */ | ||
605 | void __init omap3_ctrl_init(void) | ||
606 | { | ||
607 | omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG); | ||
608 | |||
609 | omap3_ctrl_set_iva_bootmode_idle(); | ||
610 | |||
611 | omap3_ctrl_setup_d2d_padconf(); | ||
612 | } | ||
583 | #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */ | 613 | #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */ |
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index 5dc2310c281d..a3c013345c45 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h | |||
@@ -455,7 +455,7 @@ extern void omap_ctrl_write_dsp_boot_addr(u32 bootaddr); | |||
455 | extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode); | 455 | extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode); |
456 | extern void omap3630_ctrl_disable_rta(void); | 456 | extern void omap3630_ctrl_disable_rta(void); |
457 | extern int omap3_ctrl_save_padconf(void); | 457 | extern int omap3_ctrl_save_padconf(void); |
458 | extern void omap3_ctrl_set_iva_bootmode_idle(void); | 458 | void omap3_ctrl_init(void); |
459 | extern void omap2_set_globals_control(void __iomem *ctrl, | 459 | extern void omap2_set_globals_control(void __iomem *ctrl, |
460 | void __iomem *ctrl_pad); | 460 | void __iomem *ctrl_pad); |
461 | #else | 461 | #else |
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index a5ea988ff340..d76694b7a591 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
@@ -75,9 +75,9 @@ static int omap2_enter_full_retention(void) | |||
75 | 75 | ||
76 | /* Clear old wake-up events */ | 76 | /* Clear old wake-up events */ |
77 | /* REVISIT: These write to reserved bits? */ | 77 | /* REVISIT: These write to reserved bits? */ |
78 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); | 78 | omap2xxx_prm_clear_mod_irqs(CORE_MOD, PM_WKST1, ~0); |
79 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); | 79 | omap2xxx_prm_clear_mod_irqs(CORE_MOD, OMAP24XX_PM_WKST2, ~0); |
80 | omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); | 80 | omap2xxx_prm_clear_mod_irqs(WKUP_MOD, PM_WKST, ~0); |
81 | 81 | ||
82 | pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET); | 82 | pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET); |
83 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); | 83 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); |
@@ -104,23 +104,18 @@ no_sleep: | |||
104 | clk_enable(osc_ck); | 104 | clk_enable(osc_ck); |
105 | 105 | ||
106 | /* clear CORE wake-up events */ | 106 | /* clear CORE wake-up events */ |
107 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); | 107 | omap2xxx_prm_clear_mod_irqs(CORE_MOD, PM_WKST1, ~0); |
108 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); | 108 | omap2xxx_prm_clear_mod_irqs(CORE_MOD, OMAP24XX_PM_WKST2, ~0); |
109 | 109 | ||
110 | /* wakeup domain events - bit 1: GPT1, bit5 GPIO */ | 110 | /* wakeup domain events - bit 1: GPT1, bit5 GPIO */ |
111 | omap2_prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST); | 111 | omap2xxx_prm_clear_mod_irqs(WKUP_MOD, PM_WKST, 0x4 | 0x1); |
112 | 112 | ||
113 | /* MPU domain wake events */ | 113 | /* MPU domain wake events */ |
114 | l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); | 114 | omap2xxx_prm_clear_mod_irqs(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET, |
115 | if (l & 0x01) | 115 | 0x1); |
116 | omap2_prm_write_mod_reg(0x01, OCP_MOD, | ||
117 | OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); | ||
118 | if (l & 0x20) | ||
119 | omap2_prm_write_mod_reg(0x20, OCP_MOD, | ||
120 | OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); | ||
121 | 116 | ||
122 | /* Mask future PRCM-to-MPU interrupts */ | 117 | omap2xxx_prm_clear_mod_irqs(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET, |
123 | omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); | 118 | 0x20); |
124 | 119 | ||
125 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); | 120 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); |
126 | pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON); | 121 | pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON); |
@@ -148,9 +143,9 @@ static void omap2_enter_mpu_retention(void) | |||
148 | * it is in retention mode. */ | 143 | * it is in retention mode. */ |
149 | if (omap2_allow_mpu_retention()) { | 144 | if (omap2_allow_mpu_retention()) { |
150 | /* REVISIT: These write to reserved bits? */ | 145 | /* REVISIT: These write to reserved bits? */ |
151 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); | 146 | omap2xxx_prm_clear_mod_irqs(CORE_MOD, PM_WKST1, ~0); |
152 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); | 147 | omap2xxx_prm_clear_mod_irqs(CORE_MOD, OMAP24XX_PM_WKST2, ~0); |
153 | omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); | 148 | omap2xxx_prm_clear_mod_irqs(WKUP_MOD, PM_WKST, ~0); |
154 | 149 | ||
155 | /* Try to enter MPU retention */ | 150 | /* Try to enter MPU retention */ |
156 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); | 151 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 507d8eeaab95..3f80929a5f7e 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -133,60 +133,13 @@ static void omap3_save_secure_ram_context(void) | |||
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | /* | ||
137 | * PRCM Interrupt Handler Helper Function | ||
138 | * | ||
139 | * The purpose of this function is to clear any wake-up events latched | ||
140 | * in the PRCM PM_WKST_x registers. It is possible that a wake-up event | ||
141 | * may occur whilst attempting to clear a PM_WKST_x register and thus | ||
142 | * set another bit in this register. A while loop is used to ensure | ||
143 | * that any peripheral wake-up events occurring while attempting to | ||
144 | * clear the PM_WKST_x are detected and cleared. | ||
145 | */ | ||
146 | static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits) | ||
147 | { | ||
148 | u32 wkst, fclk, iclk, clken; | ||
149 | u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; | ||
150 | u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1; | ||
151 | u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1; | ||
152 | u16 grpsel_off = (regs == 3) ? | ||
153 | OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL; | ||
154 | int c = 0; | ||
155 | |||
156 | wkst = omap2_prm_read_mod_reg(module, wkst_off); | ||
157 | wkst &= omap2_prm_read_mod_reg(module, grpsel_off); | ||
158 | wkst &= ~ignore_bits; | ||
159 | if (wkst) { | ||
160 | iclk = omap2_cm_read_mod_reg(module, iclk_off); | ||
161 | fclk = omap2_cm_read_mod_reg(module, fclk_off); | ||
162 | while (wkst) { | ||
163 | clken = wkst; | ||
164 | omap2_cm_set_mod_reg_bits(clken, module, iclk_off); | ||
165 | /* | ||
166 | * For USBHOST, we don't know whether HOST1 or | ||
167 | * HOST2 woke us up, so enable both f-clocks | ||
168 | */ | ||
169 | if (module == OMAP3430ES2_USBHOST_MOD) | ||
170 | clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT; | ||
171 | omap2_cm_set_mod_reg_bits(clken, module, fclk_off); | ||
172 | omap2_prm_write_mod_reg(wkst, module, wkst_off); | ||
173 | wkst = omap2_prm_read_mod_reg(module, wkst_off); | ||
174 | wkst &= ~ignore_bits; | ||
175 | c++; | ||
176 | } | ||
177 | omap2_cm_write_mod_reg(iclk, module, iclk_off); | ||
178 | omap2_cm_write_mod_reg(fclk, module, fclk_off); | ||
179 | } | ||
180 | |||
181 | return c; | ||
182 | } | ||
183 | |||
184 | static irqreturn_t _prcm_int_handle_io(int irq, void *unused) | 136 | static irqreturn_t _prcm_int_handle_io(int irq, void *unused) |
185 | { | 137 | { |
186 | int c; | 138 | int c; |
187 | 139 | ||
188 | c = prcm_clear_mod_irqs(WKUP_MOD, 1, | 140 | c = omap3xxx_prm_clear_mod_irqs(WKUP_MOD, 1, |
189 | ~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK)); | 141 | ~(OMAP3430_ST_IO_MASK | |
142 | OMAP3430_ST_IO_CHAIN_MASK)); | ||
190 | 143 | ||
191 | return c ? IRQ_HANDLED : IRQ_NONE; | 144 | return c ? IRQ_HANDLED : IRQ_NONE; |
192 | } | 145 | } |
@@ -200,13 +153,14 @@ static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused) | |||
200 | * these are handled in a separate handler to avoid acking | 153 | * these are handled in a separate handler to avoid acking |
201 | * IO events before parsing in mux code | 154 | * IO events before parsing in mux code |
202 | */ | 155 | */ |
203 | c = prcm_clear_mod_irqs(WKUP_MOD, 1, | 156 | c = omap3xxx_prm_clear_mod_irqs(WKUP_MOD, 1, |
204 | OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK); | 157 | OMAP3430_ST_IO_MASK | |
205 | c += prcm_clear_mod_irqs(CORE_MOD, 1, 0); | 158 | OMAP3430_ST_IO_CHAIN_MASK); |
206 | c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0); | 159 | c += omap3xxx_prm_clear_mod_irqs(CORE_MOD, 1, 0); |
160 | c += omap3xxx_prm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0); | ||
207 | if (omap_rev() > OMAP3430_REV_ES1_0) { | 161 | if (omap_rev() > OMAP3430_REV_ES1_0) { |
208 | c += prcm_clear_mod_irqs(CORE_MOD, 3, 0); | 162 | c += omap3xxx_prm_clear_mod_irqs(CORE_MOD, 3, 0); |
209 | c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0); | 163 | c += omap3xxx_prm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0); |
210 | } | 164 | } |
211 | 165 | ||
212 | return c ? IRQ_HANDLED : IRQ_NONE; | 166 | return c ? IRQ_HANDLED : IRQ_NONE; |
@@ -399,159 +353,11 @@ restore: | |||
399 | #define omap3_pm_suspend NULL | 353 | #define omap3_pm_suspend NULL |
400 | #endif /* CONFIG_SUSPEND */ | 354 | #endif /* CONFIG_SUSPEND */ |
401 | 355 | ||
402 | |||
403 | /** | ||
404 | * omap3_iva_idle(): ensure IVA is in idle so it can be put into | ||
405 | * retention | ||
406 | * | ||
407 | * In cases where IVA2 is activated by bootcode, it may prevent | ||
408 | * full-chip retention or off-mode because it is not idle. This | ||
409 | * function forces the IVA2 into idle state so it can go | ||
410 | * into retention/off and thus allow full-chip retention/off. | ||
411 | * | ||
412 | **/ | ||
413 | static void __init omap3_iva_idle(void) | ||
414 | { | ||
415 | /* ensure IVA2 clock is disabled */ | ||
416 | omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN); | ||
417 | |||
418 | /* if no clock activity, nothing else to do */ | ||
419 | if (!(omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) & | ||
420 | OMAP3430_CLKACTIVITY_IVA2_MASK)) | ||
421 | return; | ||
422 | |||
423 | /* Reset IVA2 */ | ||
424 | omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK | | ||
425 | OMAP3430_RST2_IVA2_MASK | | ||
426 | OMAP3430_RST3_IVA2_MASK, | ||
427 | OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); | ||
428 | |||
429 | /* Enable IVA2 clock */ | ||
430 | omap2_cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK, | ||
431 | OMAP3430_IVA2_MOD, CM_FCLKEN); | ||
432 | |||
433 | /* Set IVA2 boot mode to 'idle' */ | ||
434 | omap3_ctrl_set_iva_bootmode_idle(); | ||
435 | |||
436 | /* Un-reset IVA2 */ | ||
437 | omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); | ||
438 | |||
439 | /* Disable IVA2 clock */ | ||
440 | omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN); | ||
441 | |||
442 | /* Reset IVA2 */ | ||
443 | omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK | | ||
444 | OMAP3430_RST2_IVA2_MASK | | ||
445 | OMAP3430_RST3_IVA2_MASK, | ||
446 | OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); | ||
447 | } | ||
448 | |||
449 | static void __init omap3_d2d_idle(void) | ||
450 | { | ||
451 | u16 mask, padconf; | ||
452 | |||
453 | /* In a stand alone OMAP3430 where there is not a stacked | ||
454 | * modem for the D2D Idle Ack and D2D MStandby must be pulled | ||
455 | * high. S CONTROL_PADCONF_SAD2D_IDLEACK and | ||
456 | * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. */ | ||
457 | mask = (1 << 4) | (1 << 3); /* pull-up, enabled */ | ||
458 | padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY); | ||
459 | padconf |= mask; | ||
460 | omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY); | ||
461 | |||
462 | padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK); | ||
463 | padconf |= mask; | ||
464 | omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK); | ||
465 | |||
466 | /* reset modem */ | ||
467 | omap2_prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK | | ||
468 | OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK, | ||
469 | CORE_MOD, OMAP2_RM_RSTCTRL); | ||
470 | omap2_prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL); | ||
471 | } | ||
472 | |||
473 | static void __init prcm_setup_regs(void) | 356 | static void __init prcm_setup_regs(void) |
474 | { | 357 | { |
475 | u32 omap3630_en_uart4_mask = cpu_is_omap3630() ? | 358 | omap3_ctrl_init(); |
476 | OMAP3630_EN_UART4_MASK : 0; | ||
477 | u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ? | ||
478 | OMAP3630_GRPSEL_UART4_MASK : 0; | ||
479 | |||
480 | /* XXX This should be handled by hwmod code or SCM init code */ | ||
481 | omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG); | ||
482 | |||
483 | /* | ||
484 | * Enable control of expternal oscillator through | ||
485 | * sys_clkreq. In the long run clock framework should | ||
486 | * take care of this. | ||
487 | */ | ||
488 | omap2_prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK, | ||
489 | 1 << OMAP_AUTOEXTCLKMODE_SHIFT, | ||
490 | OMAP3430_GR_MOD, | ||
491 | OMAP3_PRM_CLKSRC_CTRL_OFFSET); | ||
492 | |||
493 | /* setup wakup source */ | ||
494 | omap2_prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK | | ||
495 | OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK, | ||
496 | WKUP_MOD, PM_WKEN); | ||
497 | /* No need to write EN_IO, that is always enabled */ | ||
498 | omap2_prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK | | ||
499 | OMAP3430_GRPSEL_GPT1_MASK | | ||
500 | OMAP3430_GRPSEL_GPT12_MASK, | ||
501 | WKUP_MOD, OMAP3430_PM_MPUGRPSEL); | ||
502 | |||
503 | /* Enable PM_WKEN to support DSS LPR */ | ||
504 | omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK, | ||
505 | OMAP3430_DSS_MOD, PM_WKEN); | ||
506 | |||
507 | /* Enable wakeups in PER */ | ||
508 | omap2_prm_write_mod_reg(omap3630_en_uart4_mask | | ||
509 | OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK | | ||
510 | OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK | | ||
511 | OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK | | ||
512 | OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK | | ||
513 | OMAP3430_EN_MCBSP4_MASK, | ||
514 | OMAP3430_PER_MOD, PM_WKEN); | ||
515 | /* and allow them to wake up MPU */ | ||
516 | omap2_prm_write_mod_reg(omap3630_grpsel_uart4_mask | | ||
517 | OMAP3430_GRPSEL_GPIO2_MASK | | ||
518 | OMAP3430_GRPSEL_GPIO3_MASK | | ||
519 | OMAP3430_GRPSEL_GPIO4_MASK | | ||
520 | OMAP3430_GRPSEL_GPIO5_MASK | | ||
521 | OMAP3430_GRPSEL_GPIO6_MASK | | ||
522 | OMAP3430_GRPSEL_UART3_MASK | | ||
523 | OMAP3430_GRPSEL_MCBSP2_MASK | | ||
524 | OMAP3430_GRPSEL_MCBSP3_MASK | | ||
525 | OMAP3430_GRPSEL_MCBSP4_MASK, | ||
526 | OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); | ||
527 | |||
528 | /* Don't attach IVA interrupts */ | ||
529 | if (omap3_has_iva()) { | ||
530 | omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); | ||
531 | omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1); | ||
532 | omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3); | ||
533 | omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, | ||
534 | OMAP3430_PM_IVAGRPSEL); | ||
535 | } | ||
536 | |||
537 | /* Clear any pending 'reset' flags */ | ||
538 | omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST); | ||
539 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST); | ||
540 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST); | ||
541 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST); | ||
542 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST); | ||
543 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST); | ||
544 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, OMAP2_RM_RSTST); | ||
545 | |||
546 | /* Clear any pending PRCM interrupts */ | ||
547 | omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
548 | |||
549 | /* | ||
550 | * We need to idle iva2_pwrdm even on am3703 with no iva2. | ||
551 | */ | ||
552 | omap3_iva_idle(); | ||
553 | 359 | ||
554 | omap3_d2d_idle(); | 360 | omap3_prm_init_pm(cpu_is_omap3630(), omap3_has_iva()); |
555 | } | 361 | } |
556 | 362 | ||
557 | void omap3_pm_off_mode_enable(int enable) | 363 | void omap3_pm_off_mode_enable(int enable) |
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c index a3a3cca2bcc4..86958050547a 100644 --- a/arch/arm/mach-omap2/prm2xxx.c +++ b/arch/arm/mach-omap2/prm2xxx.c | |||
@@ -114,6 +114,24 @@ void omap2xxx_prm_dpll_reset(void) | |||
114 | omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTCTRL); | 114 | omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTCTRL); |
115 | } | 115 | } |
116 | 116 | ||
117 | /** | ||
118 | * omap2xxx_prm_clear_mod_irqs - clear wakeup status bits for a module | ||
119 | * @module: PRM module to clear wakeups from | ||
120 | * @regs: register offset to clear | ||
121 | * @wkst_mask: wakeup status mask to clear | ||
122 | * | ||
123 | * Clears wakeup status bits for a given module, so that the device can | ||
124 | * re-enter idle. | ||
125 | */ | ||
126 | void omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask) | ||
127 | { | ||
128 | u32 wkst; | ||
129 | |||
130 | wkst = omap2_prm_read_mod_reg(module, regs); | ||
131 | wkst &= wkst_mask; | ||
132 | omap2_prm_write_mod_reg(wkst, module, regs); | ||
133 | } | ||
134 | |||
117 | int omap2xxx_clkdm_sleep(struct clockdomain *clkdm) | 135 | int omap2xxx_clkdm_sleep(struct clockdomain *clkdm) |
118 | { | 136 | { |
119 | omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, | 137 | omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, |
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h index d2cb6365716f..d73414139292 100644 --- a/arch/arm/mach-omap2/prm2xxx.h +++ b/arch/arm/mach-omap2/prm2xxx.h | |||
@@ -125,6 +125,7 @@ extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); | |||
125 | extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); | 125 | extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); |
126 | 126 | ||
127 | extern void omap2xxx_prm_dpll_reset(void); | 127 | extern void omap2xxx_prm_dpll_reset(void); |
128 | void omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask); | ||
128 | 129 | ||
129 | extern int __init omap2xxx_prm_init(void); | 130 | extern int __init omap2xxx_prm_init(void); |
130 | 131 | ||
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 4bd7a2dca8af..2458be6fc67b 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include "prm2xxx_3xxx.h" | 26 | #include "prm2xxx_3xxx.h" |
27 | #include "cm2xxx_3xxx.h" | 27 | #include "cm2xxx_3xxx.h" |
28 | #include "prm-regbits-34xx.h" | 28 | #include "prm-regbits-34xx.h" |
29 | #include "cm3xxx.h" | ||
30 | #include "cm-regbits-34xx.h" | ||
29 | 31 | ||
30 | static const struct omap_prcm_irq omap3_prcm_irqs[] = { | 32 | static const struct omap_prcm_irq omap3_prcm_irqs[] = { |
31 | OMAP_PRCM_IRQ("wkup", 0, 0), | 33 | OMAP_PRCM_IRQ("wkup", 0, 0), |
@@ -206,6 +208,167 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask) | |||
206 | } | 208 | } |
207 | 209 | ||
208 | /** | 210 | /** |
211 | * omap3xxx_prm_clear_mod_irqs - clear wake-up events from PRCM interrupt | ||
212 | * @module: PRM module to clear wakeups from | ||
213 | * @regs: register set to clear, 1 or 3 | ||
214 | * @ignore_bits: wakeup status bits to ignore | ||
215 | * | ||
216 | * The purpose of this function is to clear any wake-up events latched | ||
217 | * in the PRCM PM_WKST_x registers. It is possible that a wake-up event | ||
218 | * may occur whilst attempting to clear a PM_WKST_x register and thus | ||
219 | * set another bit in this register. A while loop is used to ensure | ||
220 | * that any peripheral wake-up events occurring while attempting to | ||
221 | * clear the PM_WKST_x are detected and cleared. | ||
222 | */ | ||
223 | int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits) | ||
224 | { | ||
225 | u32 wkst, fclk, iclk, clken; | ||
226 | u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; | ||
227 | u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1; | ||
228 | u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1; | ||
229 | u16 grpsel_off = (regs == 3) ? | ||
230 | OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL; | ||
231 | int c = 0; | ||
232 | |||
233 | wkst = omap2_prm_read_mod_reg(module, wkst_off); | ||
234 | wkst &= omap2_prm_read_mod_reg(module, grpsel_off); | ||
235 | wkst &= ~ignore_bits; | ||
236 | if (wkst) { | ||
237 | iclk = omap2_cm_read_mod_reg(module, iclk_off); | ||
238 | fclk = omap2_cm_read_mod_reg(module, fclk_off); | ||
239 | while (wkst) { | ||
240 | clken = wkst; | ||
241 | omap2_cm_set_mod_reg_bits(clken, module, iclk_off); | ||
242 | /* | ||
243 | * For USBHOST, we don't know whether HOST1 or | ||
244 | * HOST2 woke us up, so enable both f-clocks | ||
245 | */ | ||
246 | if (module == OMAP3430ES2_USBHOST_MOD) | ||
247 | clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT; | ||
248 | omap2_cm_set_mod_reg_bits(clken, module, fclk_off); | ||
249 | omap2_prm_write_mod_reg(wkst, module, wkst_off); | ||
250 | wkst = omap2_prm_read_mod_reg(module, wkst_off); | ||
251 | wkst &= ~ignore_bits; | ||
252 | c++; | ||
253 | } | ||
254 | omap2_cm_write_mod_reg(iclk, module, iclk_off); | ||
255 | omap2_cm_write_mod_reg(fclk, module, fclk_off); | ||
256 | } | ||
257 | |||
258 | return c; | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * omap3_prm_reset_modem - toggle reset signal for modem | ||
263 | * | ||
264 | * Toggles the reset signal to modem IP block. Required to allow | ||
265 | * OMAP3430 without stacked modem to idle properly. | ||
266 | */ | ||
267 | void __init omap3_prm_reset_modem(void) | ||
268 | { | ||
269 | omap2_prm_write_mod_reg( | ||
270 | OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK | | ||
271 | OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK, | ||
272 | CORE_MOD, OMAP2_RM_RSTCTRL); | ||
273 | omap2_prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL); | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * omap3_prm_init_pm - initialize PM related registers for PRM | ||
278 | * @has_uart4: SoC has UART4 | ||
279 | * @has_iva: SoC has IVA | ||
280 | * | ||
281 | * Initializes PRM registers for PM use. Called from PM init. | ||
282 | */ | ||
283 | void __init omap3_prm_init_pm(bool has_uart4, bool has_iva) | ||
284 | { | ||
285 | u32 en_uart4_mask; | ||
286 | u32 grpsel_uart4_mask; | ||
287 | |||
288 | /* | ||
289 | * Enable control of expternal oscillator through | ||
290 | * sys_clkreq. In the long run clock framework should | ||
291 | * take care of this. | ||
292 | */ | ||
293 | omap2_prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK, | ||
294 | 1 << OMAP_AUTOEXTCLKMODE_SHIFT, | ||
295 | OMAP3430_GR_MOD, | ||
296 | OMAP3_PRM_CLKSRC_CTRL_OFFSET); | ||
297 | |||
298 | /* setup wakup source */ | ||
299 | omap2_prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK | | ||
300 | OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK, | ||
301 | WKUP_MOD, PM_WKEN); | ||
302 | /* No need to write EN_IO, that is always enabled */ | ||
303 | omap2_prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK | | ||
304 | OMAP3430_GRPSEL_GPT1_MASK | | ||
305 | OMAP3430_GRPSEL_GPT12_MASK, | ||
306 | WKUP_MOD, OMAP3430_PM_MPUGRPSEL); | ||
307 | |||
308 | /* Enable PM_WKEN to support DSS LPR */ | ||
309 | omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK, | ||
310 | OMAP3430_DSS_MOD, PM_WKEN); | ||
311 | |||
312 | if (has_uart4) { | ||
313 | en_uart4_mask = OMAP3630_EN_UART4_MASK; | ||
314 | grpsel_uart4_mask = OMAP3630_GRPSEL_UART4_MASK; | ||
315 | } | ||
316 | |||
317 | /* Enable wakeups in PER */ | ||
318 | omap2_prm_write_mod_reg(en_uart4_mask | | ||
319 | OMAP3430_EN_GPIO2_MASK | | ||
320 | OMAP3430_EN_GPIO3_MASK | | ||
321 | OMAP3430_EN_GPIO4_MASK | | ||
322 | OMAP3430_EN_GPIO5_MASK | | ||
323 | OMAP3430_EN_GPIO6_MASK | | ||
324 | OMAP3430_EN_UART3_MASK | | ||
325 | OMAP3430_EN_MCBSP2_MASK | | ||
326 | OMAP3430_EN_MCBSP3_MASK | | ||
327 | OMAP3430_EN_MCBSP4_MASK, | ||
328 | OMAP3430_PER_MOD, PM_WKEN); | ||
329 | |||
330 | /* and allow them to wake up MPU */ | ||
331 | omap2_prm_write_mod_reg(grpsel_uart4_mask | | ||
332 | OMAP3430_GRPSEL_GPIO2_MASK | | ||
333 | OMAP3430_GRPSEL_GPIO3_MASK | | ||
334 | OMAP3430_GRPSEL_GPIO4_MASK | | ||
335 | OMAP3430_GRPSEL_GPIO5_MASK | | ||
336 | OMAP3430_GRPSEL_GPIO6_MASK | | ||
337 | OMAP3430_GRPSEL_UART3_MASK | | ||
338 | OMAP3430_GRPSEL_MCBSP2_MASK | | ||
339 | OMAP3430_GRPSEL_MCBSP3_MASK | | ||
340 | OMAP3430_GRPSEL_MCBSP4_MASK, | ||
341 | OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); | ||
342 | |||
343 | /* Don't attach IVA interrupts */ | ||
344 | if (has_iva) { | ||
345 | omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); | ||
346 | omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1); | ||
347 | omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3); | ||
348 | omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, | ||
349 | OMAP3430_PM_IVAGRPSEL); | ||
350 | } | ||
351 | |||
352 | /* Clear any pending 'reset' flags */ | ||
353 | omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST); | ||
354 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST); | ||
355 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST); | ||
356 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST); | ||
357 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST); | ||
358 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST); | ||
359 | omap2_prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, | ||
360 | OMAP2_RM_RSTST); | ||
361 | |||
362 | /* Clear any pending PRCM interrupts */ | ||
363 | omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
364 | |||
365 | /* We need to idle iva2_pwrdm even on am3703 with no iva2. */ | ||
366 | omap3xxx_prm_iva_idle(); | ||
367 | |||
368 | omap3_prm_reset_modem(); | ||
369 | } | ||
370 | |||
371 | /** | ||
209 | * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain | 372 | * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain |
210 | * | 373 | * |
211 | * Clear any previously-latched I/O wakeup events and ensure that the | 374 | * Clear any previously-latched I/O wakeup events and ensure that the |
@@ -276,6 +439,76 @@ static u32 omap3xxx_prm_read_reset_sources(void) | |||
276 | return r; | 439 | return r; |
277 | } | 440 | } |
278 | 441 | ||
442 | /** | ||
443 | * omap3xxx_prm_iva_idle - ensure IVA is in idle so it can be put into retention | ||
444 | * | ||
445 | * In cases where IVA2 is activated by bootcode, it may prevent | ||
446 | * full-chip retention or off-mode because it is not idle. This | ||
447 | * function forces the IVA2 into idle state so it can go | ||
448 | * into retention/off and thus allow full-chip retention/off. | ||
449 | */ | ||
450 | void omap3xxx_prm_iva_idle(void) | ||
451 | { | ||
452 | /* ensure IVA2 clock is disabled */ | ||
453 | omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN); | ||
454 | |||
455 | /* if no clock activity, nothing else to do */ | ||
456 | if (!(omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) & | ||
457 | OMAP3430_CLKACTIVITY_IVA2_MASK)) | ||
458 | return; | ||
459 | |||
460 | /* Reset IVA2 */ | ||
461 | omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK | | ||
462 | OMAP3430_RST2_IVA2_MASK | | ||
463 | OMAP3430_RST3_IVA2_MASK, | ||
464 | OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); | ||
465 | |||
466 | /* Enable IVA2 clock */ | ||
467 | omap2_cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK, | ||
468 | OMAP3430_IVA2_MOD, CM_FCLKEN); | ||
469 | |||
470 | /* Un-reset IVA2 */ | ||
471 | omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); | ||
472 | |||
473 | /* Disable IVA2 clock */ | ||
474 | omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN); | ||
475 | |||
476 | /* Reset IVA2 */ | ||
477 | omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK | | ||
478 | OMAP3430_RST2_IVA2_MASK | | ||
479 | OMAP3430_RST3_IVA2_MASK, | ||
480 | OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * omap3xxx_prm_clear_global_cold_reset - checks the global cold reset status | ||
485 | * and clears it if asserted | ||
486 | * | ||
487 | * Checks if cold-reset has occurred and clears the status bit if yes. Returns | ||
488 | * 1 if cold-reset has occurred, 0 otherwise. | ||
489 | */ | ||
490 | int omap3xxx_prm_clear_global_cold_reset(void) | ||
491 | { | ||
492 | if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & | ||
493 | OMAP3430_GLOBAL_COLD_RST_MASK) { | ||
494 | omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK, | ||
495 | OMAP3430_GR_MOD, | ||
496 | OMAP3_PRM_RSTST_OFFSET); | ||
497 | return 1; | ||
498 | } | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | void omap3_prm_save_scratchpad_contents(u32 *ptr) | ||
504 | { | ||
505 | *ptr++ = omap2_prm_read_mod_reg(OMAP3430_GR_MOD, | ||
506 | OMAP3_PRM_CLKSRC_CTRL_OFFSET); | ||
507 | |||
508 | *ptr++ = omap2_prm_read_mod_reg(OMAP3430_GR_MOD, | ||
509 | OMAP3_PRM_CLKSEL_OFFSET); | ||
510 | } | ||
511 | |||
279 | /* Powerdomain low-level functions */ | 512 | /* Powerdomain low-level functions */ |
280 | 513 | ||
281 | static int omap3_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) | 514 | static int omap3_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) |
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h index 1dacfc5b1959..bc37d42a8704 100644 --- a/arch/arm/mach-omap2/prm3xxx.h +++ b/arch/arm/mach-omap2/prm3xxx.h | |||
@@ -162,6 +162,12 @@ extern void omap3xxx_prm_dpll3_reset(void); | |||
162 | 162 | ||
163 | extern int __init omap3xxx_prm_init(void); | 163 | extern int __init omap3xxx_prm_init(void); |
164 | extern u32 omap3xxx_prm_get_reset_sources(void); | 164 | extern u32 omap3xxx_prm_get_reset_sources(void); |
165 | int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits); | ||
166 | void omap3xxx_prm_iva_idle(void); | ||
167 | void omap3_prm_reset_modem(void); | ||
168 | int omap3xxx_prm_clear_global_cold_reset(void); | ||
169 | void omap3_prm_save_scratchpad_contents(u32 *ptr); | ||
170 | void omap3_prm_init_pm(bool has_uart4, bool has_iva); | ||
165 | 171 | ||
166 | #endif /* __ASSEMBLER */ | 172 | #endif /* __ASSEMBLER */ |
167 | 173 | ||