summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/sleep.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa/sleep.S')
-rw-r--r--arch/arm/mach-pxa/sleep.S56
1 files changed, 50 insertions, 6 deletions
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index 16cad2c2497c..5786ccad938c 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -18,6 +18,11 @@
#include <asm/arch/pxa-regs.h>
+#ifdef CONFIG_PXA27x // workaround for Errata 50
+#define MDREFR_KDIV 0x200a4000 // all banks
+#define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
+#endif
+
.text
/*
@@ -28,7 +33,9 @@
ENTRY(pxa_cpu_suspend)
+#ifndef CONFIG_IWMMXT
mra r2, r3, acc0
+#endif
stmfd sp!, {r2 - r12, lr} @ save registers on stack
@ get coprocessor registers
@@ -61,14 +68,23 @@ ENTRY(pxa_cpu_suspend)
@ prepare value for sleep mode
mov r1, #3 @ sleep mode
- @ prepare to put SDRAM into self-refresh manually
+ @ prepare pointer to physical address 0 (virtual mapping in generic.c)
+ mov r2, #UNCACHED_PHYS_0
+
+ @ prepare SDRAM refresh settings
ldr r4, =MDREFR
ldr r5, [r4]
+
+ @ enable SDRAM self-refresh mode
orr r5, r5, #MDREFR_SLFRSH
- @ prepare pointer to physical address 0 (virtual mapping in generic.c)
- mov r2, #UNCACHED_PHYS_0
+#ifdef CONFIG_PXA27x
+ @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
+ ldr r6, =MDREFR_KDIV
+ orr r5, r5, r6
+#endif
+#ifdef CONFIG_PXA25x
@ Intel PXA255 Specification Update notes problems
@ about suspending with PXBus operating above 133MHz
@ (see Errata 31, GPIO output signals, ... unpredictable in sleep
@@ -100,6 +116,18 @@ ENTRY(pxa_cpu_suspend)
mov r0, #0
mcr p14, 0, r0, c6, c0, 0
orr r0, r0, #2 @ initiate change bit
+#endif
+#ifdef CONFIG_PXA27x
+ @ Intel PXA270 Specification Update notes problems sleeping
+ @ with core operating above 91 MHz
+ @ (see Errata 50, ...processor does not exit from sleep...)
+
+ ldr r6, =CCCR
+ ldr r8, [r6] @ keep original value for resume
+
+ ldr r7, =CCCR_SLEEP @ prepare CCCR sleep value
+ mov r0, #0x2 @ prepare value for CLKCFG
+#endif
@ align execution to a cache line
b 1f
@@ -111,6 +139,7 @@ ENTRY(pxa_cpu_suspend)
@ All needed values are now in registers.
@ These last instructions should be in cache
+#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
@ initiate the frequency change...
str r7, [r6]
mcr p14, 0, r0, c6, c0, 0
@@ -118,14 +147,27 @@ ENTRY(pxa_cpu_suspend)
@ restore the original cpu speed value for resume
str r8, [r6]
- @ put SDRAM into self-refresh
- str r5, [r4]
+ @ need 6 13-MHz cycles before changing PWRMODE
+ @ just set frequency to 91-MHz... 6*91/13 = 42
+
+ mov r0, #42
+10: subs r0, r0, #1
+ bne 10b
+#endif
+
+ @ Do not reorder...
+ @ Intel PXA270 Specification Update notes problems performing
+ @ external accesses after SDRAM is put in self-refresh mode
+ @ (see Errata 39 ...hangs when entering self-refresh mode)
@ force address lines low by reading at physical address 0
ldr r3, [r2]
+ @ put SDRAM into self-refresh
+ str r5, [r4]
+
@ enter sleep mode
- mcr p14, 0, r1, c7, c0, 0
+ mcr p14, 0, r1, c7, c0, 0 @ PWRMODE
20: b 20b @ loop waiting for sleep
@@ -188,7 +230,9 @@ resume_after_mmu:
bl cpu_xscale_proc_init
#endif
ldmfd sp!, {r2, r3}
+#ifndef CONFIG_IWMMXT
mar acc0, r2, r3
+#endif
ldmfd sp!, {r4 - r12, pc} @ return to caller