aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/pm.h20
-rw-r--r--arch/arm/mach-omap2/pm34xx.c20
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S303
-rw-r--r--arch/arm/plat-omap/sram.c15
4 files changed, 206 insertions, 152 deletions
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 45bcfce77352..a4ec213e30c0 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -88,18 +88,28 @@ extern int pm_dbg_regset_init(int reg_set);
88#define pm_dbg_regset_init(reg_set) do {} while (0); 88#define pm_dbg_regset_init(reg_set) do {} while (0);
89#endif /* CONFIG_PM_DEBUG */ 89#endif /* CONFIG_PM_DEBUG */
90 90
91/* 24xx */
91extern void omap24xx_idle_loop_suspend(void); 92extern void omap24xx_idle_loop_suspend(void);
93extern unsigned int omap24xx_idle_loop_suspend_sz;
92 94
93extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, 95extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
94 void __iomem *sdrc_power); 96 void __iomem *sdrc_power);
97extern unsigned int omap24xx_cpu_suspend_sz;
98
99/* 3xxx */
95extern void omap34xx_cpu_suspend(u32 *addr, int save_state); 100extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
96extern int save_secure_ram_context(u32 *addr);
97extern void omap3_save_scratchpad_contents(void);
98 101
99extern unsigned int omap24xx_idle_loop_suspend_sz; 102/* omap3_do_wfi function pointer and size, for copy to SRAM */
103extern void omap3_do_wfi(void);
104extern unsigned int omap3_do_wfi_sz;
105/* ... and its pointer from SRAM after copy */
106extern void (*omap3_do_wfi_sram)(void);
107
108/* save_secure_ram_context function pointer and size, for copy to SRAM */
109extern int save_secure_ram_context(u32 *addr);
100extern unsigned int save_secure_ram_context_sz; 110extern unsigned int save_secure_ram_context_sz;
101extern unsigned int omap24xx_cpu_suspend_sz; 111
102extern unsigned int omap34xx_cpu_suspend_sz; 112extern void omap3_save_scratchpad_contents(void);
103 113
104#define PM_RTA_ERRATUM_i608 (1 << 0) 114#define PM_RTA_ERRATUM_i608 (1 << 0)
105#define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) 115#define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 3e9a13e1ac57..e1c79bae7670 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -78,9 +78,8 @@ struct power_state {
78 78
79static LIST_HEAD(pwrst_list); 79static LIST_HEAD(pwrst_list);
80 80
81static void (*_omap_sram_idle)(u32 *addr, int save_state);
82
83static int (*_omap_save_secure_sram)(u32 *addr); 81static int (*_omap_save_secure_sram)(u32 *addr);
82void (*omap3_do_wfi_sram)(void);
84 83
85static struct powerdomain *mpu_pwrdm, *neon_pwrdm; 84static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
86static struct powerdomain *core_pwrdm, *per_pwrdm; 85static struct powerdomain *core_pwrdm, *per_pwrdm;
@@ -309,7 +308,7 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
309 308
310static void omap34xx_do_sram_idle(unsigned long save_state) 309static void omap34xx_do_sram_idle(unsigned long save_state)
311{ 310{
312 _omap_sram_idle(omap3_arm_context, save_state); 311 omap34xx_cpu_suspend(omap3_arm_context, save_state);
313} 312}
314 313
315void omap_sram_idle(void) 314void omap_sram_idle(void)
@@ -328,9 +327,6 @@ void omap_sram_idle(void)
328 int core_prev_state, per_prev_state; 327 int core_prev_state, per_prev_state;
329 u32 sdrc_pwr = 0; 328 u32 sdrc_pwr = 0;
330 329
331 if (!_omap_sram_idle)
332 return;
333
334 pwrdm_clear_all_prev_pwrst(mpu_pwrdm); 330 pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
335 pwrdm_clear_all_prev_pwrst(neon_pwrdm); 331 pwrdm_clear_all_prev_pwrst(neon_pwrdm);
336 pwrdm_clear_all_prev_pwrst(core_pwrdm); 332 pwrdm_clear_all_prev_pwrst(core_pwrdm);
@@ -826,10 +822,17 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
826 return 0; 822 return 0;
827} 823}
828 824
825/*
826 * Push functions to SRAM
827 *
828 * The minimum set of functions is pushed to SRAM for execution:
829 * - omap3_do_wfi for erratum i581 WA,
830 * - save_secure_ram_context for security extensions.
831 */
829void omap_push_sram_idle(void) 832void omap_push_sram_idle(void)
830{ 833{
831 _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, 834 omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
832 omap34xx_cpu_suspend_sz); 835
833 if (omap_type() != OMAP2_DEVICE_TYPE_GP) 836 if (omap_type() != OMAP2_DEVICE_TYPE_GP)
834 _omap_save_secure_sram = omap_sram_push(save_secure_ram_context, 837 _omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
835 save_secure_ram_context_sz); 838 save_secure_ram_context_sz);
@@ -894,7 +897,6 @@ static int __init omap3_pm_init(void)
894 per_clkdm = clkdm_lookup("per_clkdm"); 897 per_clkdm = clkdm_lookup("per_clkdm");
895 core_clkdm = clkdm_lookup("core_clkdm"); 898 core_clkdm = clkdm_lookup("core_clkdm");
896 899
897 omap_push_sram_idle();
898#ifdef CONFIG_SUSPEND 900#ifdef CONFIG_SUSPEND
899 suspend_set_ops(&omap_pm_ops); 901 suspend_set_ops(&omap_pm_ops);
900#endif /* CONFIG_SUSPEND */ 902#endif /* CONFIG_SUSPEND */
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index d18f52e46c7c..17dbc5af6915 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -139,8 +139,10 @@ ENTRY(save_secure_ram_context_sz)
139 * 139 *
140 * 140 *
141 * Notes: 141 * Notes:
142 * - this code gets copied to internal SRAM at boot and after wake-up 142 * - only the minimum set of functions gets copied to internal SRAM at boot
143 * from OFF mode. The execution pointer in SRAM is _omap_sram_idle. 143 * and after wake-up from OFF mode, cf. omap_push_sram_idle. The function
144 * pointers in SDRAM or SRAM are called depending on the desired low power
145 * target state.
144 * - when the OMAP wakes up it continues at different execution points 146 * - when the OMAP wakes up it continues at different execution points
145 * depending on the low power mode (non-OFF vs OFF modes), 147 * depending on the low power mode (non-OFF vs OFF modes),
146 * cf. 'Resume path for xxx mode' comments. 148 * cf. 'Resume path for xxx mode' comments.
@@ -158,9 +160,15 @@ ENTRY(omap34xx_cpu_suspend)
158 * 3 - Both L1 and L2 lost and logic lost 160 * 3 - Both L1 and L2 lost and logic lost
159 */ 161 */
160 162
161 /* Directly jump to WFI is the context save is not required */ 163 /*
162 cmp r1, #0x0 164 * For OFF mode: save context and jump to WFI in SDRAM (omap3_do_wfi)
163 beq omap3_do_wfi 165 * For non-OFF modes: jump to the WFI code in SRAM (omap3_do_wfi_sram)
166 */
167 ldr r4, omap3_do_wfi_sram_addr
168 ldr r5, [r4]
169 cmp r1, #0x0 @ If no context save required,
170 bxeq r5 @ jump to the WFI code in SRAM
171
164 172
165 /* Otherwise fall through to the save context code */ 173 /* Otherwise fall through to the save context code */
166save_context_wfi: 174save_context_wfi:
@@ -213,7 +221,32 @@ save_context_wfi:
213 THUMB( nop ) 221 THUMB( nop )
214 .arm 222 .arm
215 223
216omap3_do_wfi: 224 b omap3_do_wfi
225
226/*
227 * Local variables
228 */
229omap3_do_wfi_sram_addr:
230 .word omap3_do_wfi_sram
231kernel_flush:
232 .word v7_flush_dcache_all
233
234/* ===================================
235 * == WFI instruction => Enter idle ==
236 * ===================================
237 */
238
239/*
240 * Do WFI instruction
241 * Includes the resume path for non-OFF modes
242 *
243 * This code gets copied to internal SRAM and is accessible
244 * from both SDRAM and SRAM:
245 * - executed from SRAM for non-off modes (omap3_do_wfi_sram),
246 * - executed from SDRAM for OFF mode (omap3_do_wfi).
247 */
248 .align 3
249ENTRY(omap3_do_wfi)
217 ldr r4, sdrc_power @ read the SDRC_POWER register 250 ldr r4, sdrc_power @ read the SDRC_POWER register
218 ldr r5, [r4] @ read the contents of SDRC_POWER 251 ldr r5, [r4] @ read the contents of SDRC_POWER
219 orr r5, r5, #0x40 @ enable self refresh on idle req 252 orr r5, r5, #0x40 @ enable self refresh on idle req
@@ -245,8 +278,86 @@ omap3_do_wfi:
245 nop 278 nop
246 nop 279 nop
247 nop 280 nop
248 bl wait_sdrc_ok
249 281
282/*
283 * This function implements the erratum ID i581 WA:
284 * SDRC state restore before accessing the SDRAM
285 *
286 * Only used at return from non-OFF mode. For OFF
287 * mode the ROM code configures the SDRC and
288 * the DPLL before calling the restore code directly
289 * from DDR.
290 */
291
292/* Make sure SDRC accesses are ok */
293wait_sdrc_ok:
294
295/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */
296 ldr r4, cm_idlest_ckgen
297wait_dpll3_lock:
298 ldr r5, [r4]
299 tst r5, #1
300 beq wait_dpll3_lock
301
302 ldr r4, cm_idlest1_core
303wait_sdrc_ready:
304 ldr r5, [r4]
305 tst r5, #0x2
306 bne wait_sdrc_ready
307 /* allow DLL powerdown upon hw idle req */
308 ldr r4, sdrc_power
309 ldr r5, [r4]
310 bic r5, r5, #0x40
311 str r5, [r4]
312
313/*
314 * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
315 * base instead.
316 * Be careful not to clobber r7 when maintaing this code.
317 */
318
319is_dll_in_lock_mode:
320 /* Is dll in lock mode? */
321 ldr r4, sdrc_dlla_ctrl
322 ldr r5, [r4]
323 tst r5, #0x4
324 bne exit_nonoff_modes @ Return if locked
325 /* wait till dll locks */
326 adr r7, kick_counter
327wait_dll_lock_timed:
328 ldr r4, wait_dll_lock_counter
329 add r4, r4, #1
330 str r4, [r7, #wait_dll_lock_counter - kick_counter]
331 ldr r4, sdrc_dlla_status
332 /* Wait 20uS for lock */
333 mov r6, #8
334wait_dll_lock:
335 subs r6, r6, #0x1
336 beq kick_dll
337 ldr r5, [r4]
338 and r5, r5, #0x4
339 cmp r5, #0x4
340 bne wait_dll_lock
341 b exit_nonoff_modes @ Return when locked
342
343 /* disable/reenable DLL if not locked */
344kick_dll:
345 ldr r4, sdrc_dlla_ctrl
346 ldr r5, [r4]
347 mov r6, r5
348 bic r6, #(1<<3) @ disable dll
349 str r6, [r4]
350 dsb
351 orr r6, r6, #(1<<3) @ enable dll
352 str r6, [r4]
353 dsb
354 ldr r4, kick_counter
355 add r4, r4, #1
356 str r4, [r7] @ kick_counter
357 b wait_dll_lock_timed
358
359exit_nonoff_modes:
360 /* Re-enable C-bit if needed */
250 mrc p15, 0, r0, c1, c0, 0 361 mrc p15, 0, r0, c1, c0, 0
251 tst r0, #(1 << 2) @ Check C bit enabled? 362 tst r0, #(1 << 2) @ Check C bit enabled?
252 orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared 363 orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared
@@ -260,6 +371,31 @@ omap3_do_wfi:
260 */ 371 */
261 ldmfd sp!, {r4 - r11, pc} @ restore regs and return 372 ldmfd sp!, {r4 - r11, pc} @ restore regs and return
262 373
374/*
375 * Local variables
376 */
377sdrc_power:
378 .word SDRC_POWER_V
379cm_idlest1_core:
380 .word CM_IDLEST1_CORE_V
381cm_idlest_ckgen:
382 .word CM_IDLEST_CKGEN_V
383sdrc_dlla_status:
384 .word SDRC_DLLA_STATUS_V
385sdrc_dlla_ctrl:
386 .word SDRC_DLLA_CTRL_V
387 /*
388 * When exporting to userspace while the counters are in SRAM,
389 * these 2 words need to be at the end to facilitate retrival!
390 */
391kick_counter:
392 .word 0
393wait_dll_lock_counter:
394 .word 0
395
396ENTRY(omap3_do_wfi_sz)
397 .word . - omap3_do_wfi
398
263 399
264/* 400/*
265 * ============================== 401 * ==============================
@@ -275,13 +411,17 @@ omap3_do_wfi:
275 * restore_es3: applies to 34xx >= ES3.0 411 * restore_es3: applies to 34xx >= ES3.0
276 * restore_3630: applies to 36xx 412 * restore_3630: applies to 36xx
277 * restore: common code for 3xxx 413 * restore: common code for 3xxx
414 *
415 * Note: when back from CORE and MPU OFF mode we are running
416 * from SDRAM, without MMU, without the caches and prediction.
417 * Also the SRAM content has been cleared.
278 */ 418 */
279ENTRY(omap3_restore_es3) 419ENTRY(omap3_restore_es3)
280 ldr r5, pm_prepwstst_core_p 420 ldr r5, pm_prepwstst_core_p
281 ldr r4, [r5] 421 ldr r4, [r5]
282 and r4, r4, #0x3 422 and r4, r4, #0x3
283 cmp r4, #0x0 @ Check if previous power state of CORE is OFF 423 cmp r4, #0x0 @ Check if previous power state of CORE is OFF
284 bne omap3_restore 424 bne omap3_restore @ Fall through to OMAP3 common code
285 adr r0, es3_sdrc_fix 425 adr r0, es3_sdrc_fix
286 ldr r1, sram_base 426 ldr r1, sram_base
287 ldr r2, es3_sdrc_fix_sz 427 ldr r2, es3_sdrc_fix_sz
@@ -293,7 +433,7 @@ copy_to_sram:
293 bne copy_to_sram 433 bne copy_to_sram
294 ldr r1, sram_base 434 ldr r1, sram_base
295 blx r1 435 blx r1
296 b omap3_restore 436 b omap3_restore @ Fall through to OMAP3 common code
297ENDPROC(omap3_restore_es3) 437ENDPROC(omap3_restore_es3)
298 438
299ENTRY(omap3_restore_3630) 439ENTRY(omap3_restore_3630)
@@ -301,7 +441,7 @@ ENTRY(omap3_restore_3630)
301 ldr r2, [r1] 441 ldr r2, [r1]
302 and r2, r2, #0x3 442 and r2, r2, #0x3
303 cmp r2, #0x0 @ Check if previous power state of CORE is OFF 443 cmp r2, #0x0 @ Check if previous power state of CORE is OFF
304 bne omap3_restore 444 bne omap3_restore @ Fall through to OMAP3 common code
305 /* Disable RTA before giving control */ 445 /* Disable RTA before giving control */
306 ldr r1, control_mem_rta 446 ldr r1, control_mem_rta
307 mov r2, #OMAP36XX_RTA_DISABLE 447 mov r2, #OMAP36XX_RTA_DISABLE
@@ -405,10 +545,31 @@ ENDPROC(omap3_restore)
405 .ltorg 545 .ltorg
406 546
407/* 547/*
548 * Local variables
549 */
550pm_prepwstst_core_p:
551 .word PM_PREPWSTST_CORE_P
552pm_pwstctrl_mpu:
553 .word PM_PWSTCTRL_MPU_P
554scratchpad_base:
555 .word SCRATCHPAD_BASE_P
556sram_base:
557 .word SRAM_BASE_P + 0x8000
558control_stat:
559 .word CONTROL_STAT
560control_mem_rta:
561 .word CONTROL_MEM_RTA_CTRL
562l2dis_3630:
563 .word 0
564
565/*
408 * Internal functions 566 * Internal functions
409 */ 567 */
410 568
411/* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */ 569/*
570 * This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0
571 * Copied to and run from SRAM in order to reconfigure the SDRC parameters.
572 */
412 .text 573 .text
413 .align 3 574 .align 3
414ENTRY(es3_sdrc_fix) 575ENTRY(es3_sdrc_fix)
@@ -438,6 +599,9 @@ ENTRY(es3_sdrc_fix)
438 str r5, [r4] @ kick off refreshes 599 str r5, [r4] @ kick off refreshes
439 bx lr 600 bx lr
440 601
602/*
603 * Local variables
604 */
441 .align 605 .align
442sdrc_syscfg: 606sdrc_syscfg:
443 .word SDRC_SYSCONFIG_P 607 .word SDRC_SYSCONFIG_P
@@ -456,120 +620,3 @@ sdrc_manual_1:
456ENDPROC(es3_sdrc_fix) 620ENDPROC(es3_sdrc_fix)
457ENTRY(es3_sdrc_fix_sz) 621ENTRY(es3_sdrc_fix_sz)
458 .word . - es3_sdrc_fix 622 .word . - es3_sdrc_fix
459
460/*
461 * This function implements the erratum ID i581 WA:
462 * SDRC state restore before accessing the SDRAM
463 *
464 * Only used at return from non-OFF mode. For OFF
465 * mode the ROM code configures the SDRC and
466 * the DPLL before calling the restore code directly
467 * from DDR.
468 */
469
470/* Make sure SDRC accesses are ok */
471wait_sdrc_ok:
472
473/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */
474 ldr r4, cm_idlest_ckgen
475wait_dpll3_lock:
476 ldr r5, [r4]
477 tst r5, #1
478 beq wait_dpll3_lock
479
480 ldr r4, cm_idlest1_core
481wait_sdrc_ready:
482 ldr r5, [r4]
483 tst r5, #0x2
484 bne wait_sdrc_ready
485 /* allow DLL powerdown upon hw idle req */
486 ldr r4, sdrc_power
487 ldr r5, [r4]
488 bic r5, r5, #0x40
489 str r5, [r4]
490
491/*
492 * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
493 * base instead.
494 * Be careful not to clobber r7 when maintaing this code.
495 */
496
497is_dll_in_lock_mode:
498 /* Is dll in lock mode? */
499 ldr r4, sdrc_dlla_ctrl
500 ldr r5, [r4]
501 tst r5, #0x4
502 bxne lr @ Return if locked
503 /* wait till dll locks */
504 adr r7, kick_counter
505wait_dll_lock_timed:
506 ldr r4, wait_dll_lock_counter
507 add r4, r4, #1
508 str r4, [r7, #wait_dll_lock_counter - kick_counter]
509 ldr r4, sdrc_dlla_status
510 /* Wait 20uS for lock */
511 mov r6, #8
512wait_dll_lock:
513 subs r6, r6, #0x1
514 beq kick_dll
515 ldr r5, [r4]
516 and r5, r5, #0x4
517 cmp r5, #0x4
518 bne wait_dll_lock
519 bx lr @ Return when locked
520
521 /* disable/reenable DLL if not locked */
522kick_dll:
523 ldr r4, sdrc_dlla_ctrl
524 ldr r5, [r4]
525 mov r6, r5
526 bic r6, #(1<<3) @ disable dll
527 str r6, [r4]
528 dsb
529 orr r6, r6, #(1<<3) @ enable dll
530 str r6, [r4]
531 dsb
532 ldr r4, kick_counter
533 add r4, r4, #1
534 str r4, [r7] @ kick_counter
535 b wait_dll_lock_timed
536
537 .align
538cm_idlest1_core:
539 .word CM_IDLEST1_CORE_V
540cm_idlest_ckgen:
541 .word CM_IDLEST_CKGEN_V
542sdrc_dlla_status:
543 .word SDRC_DLLA_STATUS_V
544sdrc_dlla_ctrl:
545 .word SDRC_DLLA_CTRL_V
546pm_prepwstst_core_p:
547 .word PM_PREPWSTST_CORE_P
548pm_pwstctrl_mpu:
549 .word PM_PWSTCTRL_MPU_P
550scratchpad_base:
551 .word SCRATCHPAD_BASE_P
552sram_base:
553 .word SRAM_BASE_P + 0x8000
554sdrc_power:
555 .word SDRC_POWER_V
556control_stat:
557 .word CONTROL_STAT
558control_mem_rta:
559 .word CONTROL_MEM_RTA_CTRL
560kernel_flush:
561 .word v7_flush_dcache_all
562l2dis_3630:
563 .word 0
564 /*
565 * When exporting to userspace while the counters are in SRAM,
566 * these 2 words need to be at the end to facilitate retrival!
567 */
568kick_counter:
569 .word 0
570wait_dll_lock_counter:
571 .word 0
572ENDPROC(omap34xx_cpu_suspend)
573
574ENTRY(omap34xx_cpu_suspend_sz)
575 .word . - omap34xx_cpu_suspend
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 6af3d0b1f8d0..363c91e44efb 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -394,20 +394,15 @@ void omap3_sram_restore_context(void)
394} 394}
395#endif /* CONFIG_PM */ 395#endif /* CONFIG_PM */
396 396
397static int __init omap34xx_sram_init(void) 397#endif /* CONFIG_ARCH_OMAP3 */
398{ 398
399 _omap3_sram_configure_core_dpll =
400 omap_sram_push(omap3_sram_configure_core_dpll,
401 omap3_sram_configure_core_dpll_sz);
402 omap_push_sram_idle();
403 return 0;
404}
405#else
406static inline int omap34xx_sram_init(void) 399static inline int omap34xx_sram_init(void)
407{ 400{
401#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
402 omap3_sram_restore_context();
403#endif
408 return 0; 404 return 0;
409} 405}
410#endif
411 406
412int __init omap_sram_init(void) 407int __init omap_sram_init(void)
413{ 408{