Linux 2.6.31.8
[linux/fpc-iii.git] / arch / arm / mach-pxa / sleep.S
blob2ed95f369cfc9a8ebb357b713f866e20842f3d86
1 /*
2  * Low-level PXA250/210 sleep/wakeUp support
3  *
4  * Initial SA1110 code:
5  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
6  *
7  * Adapted for PXA by Nicolas Pitre:
8  * Copyright (c) 2002 Monta Vista Software, Inc.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License.
12  */
14 #include <linux/linkage.h>
15 #include <asm/assembler.h>
16 #include <mach/hardware.h>
18 #include <mach/pxa2xx-regs.h>
20 #define MDREFR_KDIV     0x200a4000      // all banks
21 #define CCCR_SLEEP      0x00000107      // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
23                 .text
25 pxa_cpu_save_cp:
26         @ get coprocessor registers
27         mrc     p14, 0, r3, c6, c0, 0           @ clock configuration, for turbo mode
28         mrc     p15, 0, r4, c15, c1, 0          @ CP access reg
29         mrc     p15, 0, r5, c13, c0, 0          @ PID
30         mrc     p15, 0, r6, c3, c0, 0           @ domain ID
31         mrc     p15, 0, r7, c2, c0, 0           @ translation table base addr
32         mrc     p15, 0, r8, c1, c1, 0           @ auxiliary control reg
33         mrc     p15, 0, r9, c1, c0, 0           @ control reg
35         bic     r3, r3, #2                      @ clear frequency change bit
37         @ store them plus current virtual stack ptr on stack
38         mov     r10, sp
39         stmfd   sp!, {r3 - r10}
41         mov     pc, lr
43 pxa_cpu_save_sp:
44         @ preserve phys address of stack
45         mov     r0, sp
46         str     lr, [sp, #-4]!
47         bl      sleep_phys_sp
48         ldr     r1, =sleep_save_sp
49         str     r0, [r1]
50         ldr     pc, [sp], #4
52 #ifdef CONFIG_PXA3xx
54  * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4)
55  *
56  * NOTE:  unfortunately, pxa_cpu_save_cp can not be reused here since
57  * the auxiliary control register address is different between pxa3xx
58  * and pxa{25x,27x}
59  */
61 ENTRY(pxa3xx_cpu_suspend)
63 #ifndef CONFIG_IWMMXT
64         mra     r2, r3, acc0
65 #endif
66         stmfd   sp!, {r2 - r12, lr}     @ save registers on stack
68         mrc     p14, 0, r3, c6, c0, 0           @ clock configuration, for turbo mode
69         mrc     p15, 0, r4, c15, c1, 0          @ CP access reg
70         mrc     p15, 0, r5, c13, c0, 0          @ PID
71         mrc     p15, 0, r6, c3, c0, 0           @ domain ID
72         mrc     p15, 0, r7, c2, c0, 0           @ translation table base addr
73         mrc     p15, 0, r8, c1, c0, 1           @ auxiliary control reg
74         mrc     p15, 0, r9, c1, c0, 0           @ control reg
76         bic     r3, r3, #2                      @ clear frequency change bit
78         @ store them plus current virtual stack ptr on stack
79         mov     r10, sp
80         stmfd   sp!, {r3 - r10}
82         @ store physical address of stack pointer
83         mov     r0, sp
84         bl      sleep_phys_sp
85         ldr     r1, =sleep_save_sp
86         str     r0, [r1]
88         @ clean data cache
89         bl      xsc3_flush_kern_cache_all
91         mov     r0, #0x06               @ S2D3C4 mode
92         mcr     p14, 0, r0, c7, c0, 0   @ enter sleep
94 20:     b       20b                     @ waiting for sleep
96         .data
97         .align 5
99  * pxa3xx_cpu_resume
100  */
102 ENTRY(pxa3xx_cpu_resume)
104         mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE   @ set SVC, irqs off
105         msr     cpsr_c, r0
107         ldr     r0, sleep_save_sp               @ stack phys addr
108         ldmfd   r0, {r3 - r9, sp}               @ CP regs + virt stack ptr
110         mov     r1, #0
111         mcr     p15, 0, r1, c7, c7, 0           @ invalidate I & D caches, BTB
112         mcr     p15, 0, r1, c7, c10, 4          @ drain write (&fill) buffer
113         mcr     p15, 0, r1, c7, c5, 4           @ flush prefetch buffer
114         mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
116         mcr     p14, 0, r3, c6, c0, 0           @ clock configuration, turbo mode.
117         mcr     p15, 0, r4, c15, c1, 0          @ CP access reg
118         mcr     p15, 0, r5, c13, c0, 0          @ PID
119         mcr     p15, 0, r6, c3, c0, 0           @ domain ID
120         mcr     p15, 0, r7, c2, c0, 0           @ translation table base addr
121         mcr     p15, 0, r8, c1, c0, 1           @ auxiliary control reg
123         @ temporarily map resume_turn_on_mmu into the page table,
124         @ otherwise prefetch abort occurs after MMU is turned on
125         mov     r1, r7
126         bic     r1, r1, #0x00ff
127         bic     r1, r1, #0x3f00
128         ldr     r2, =0x542e
130         adr     r3, resume_turn_on_mmu
131         mov     r3, r3, lsr #20
132         orr     r4, r2, r3, lsl #20
133         ldr     r5, [r1, r3, lsl #2]
134         str     r4, [r1, r3, lsl #2]
136         @ Mapping page table address in the page table
137         mov     r6, r1, lsr #20
138         orr     r7, r2, r6, lsl #20
139         ldr     r8, [r1, r6, lsl #2]
140         str     r7, [r1, r6, lsl #2]
142         ldr     r2, =pxa3xx_resume_after_mmu    @ absolute virtual address
143         b       resume_turn_on_mmu              @ cache align execution
145         .text
146 pxa3xx_resume_after_mmu:
147         /* restore the temporary mapping */
148         str     r5, [r1, r3, lsl #2]
149         str     r8, [r1, r6, lsl #2]
150         b       resume_after_mmu
152 #endif /* CONFIG_PXA3xx */
154 #ifdef CONFIG_PXA27x
156  * pxa27x_cpu_suspend()
158  * Forces CPU into sleep state.
160  * r0 = value for PWRMODE M field for desired sleep state
161  */
163 ENTRY(pxa27x_cpu_suspend)
165 #ifndef CONFIG_IWMMXT
166         mra     r2, r3, acc0
167 #endif
168         stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
170         bl      pxa_cpu_save_cp
172         mov     r5, r0                          @ save sleep mode
173         bl      pxa_cpu_save_sp
175         @ clean data cache
176         bl      xscale_flush_kern_cache_all
178         @ Put the processor to sleep
179         @ (also workaround for sighting 28071)
181         @ prepare value for sleep mode
182         mov     r1, r5                          @ sleep mode
184         @ prepare pointer to physical address 0 (virtual mapping in generic.c)
185         mov     r2, #UNCACHED_PHYS_0
187         @ prepare SDRAM refresh settings
188         ldr     r4, =MDREFR
189         ldr     r5, [r4]
191         @ enable SDRAM self-refresh mode
192         orr     r5, r5, #MDREFR_SLFRSH
194         @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
195         ldr     r6, =MDREFR_KDIV
196         orr     r5, r5, r6
198         @ Intel PXA270 Specification Update notes problems sleeping
199         @ with core operating above 91 MHz
200         @ (see Errata 50, ...processor does not exit from sleep...)
202         ldr     r6, =CCCR
203         ldr     r8, [r6]                @ keep original value for resume
205         ldr     r7, =CCCR_SLEEP         @ prepare CCCR sleep value
206         mov     r0, #0x2                @ prepare value for CLKCFG
208         @ align execution to a cache line
209         b       pxa_cpu_do_suspend
210 #endif
212 #ifdef CONFIG_PXA25x
214  * pxa25x_cpu_suspend()
216  * Forces CPU into sleep state.
218  * r0 = value for PWRMODE M field for desired sleep state
219  */
221 ENTRY(pxa25x_cpu_suspend)
222         stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
224         bl      pxa_cpu_save_cp
226         mov     r5, r0                          @ save sleep mode
227         bl      pxa_cpu_save_sp
229         @ clean data cache
230         bl      xscale_flush_kern_cache_all
232         @ prepare value for sleep mode
233         mov     r1, r5                          @ sleep mode
235         @ prepare pointer to physical address 0 (virtual mapping in generic.c)
236         mov     r2, #UNCACHED_PHYS_0
238         @ prepare SDRAM refresh settings
239         ldr     r4, =MDREFR
240         ldr     r5, [r4]
242         @ enable SDRAM self-refresh mode
243         orr     r5, r5, #MDREFR_SLFRSH
245         @ Intel PXA255 Specification Update notes problems
246         @ about suspending with PXBus operating above 133MHz
247         @ (see Errata 31, GPIO output signals, ... unpredictable in sleep
248         @
249         @ We keep the change-down close to the actual suspend on SDRAM
250         @ as possible to eliminate messing about with the refresh clock
251         @ as the system will restore with the original speed settings
252         @
253         @ Ben Dooks, 13-Sep-2004
255         ldr     r6, =CCCR
256         ldr     r8, [r6]                @ keep original value for resume
258         @ ensure x1 for run and turbo mode with memory clock
259         bic     r7, r8, #CCCR_M_MASK | CCCR_N_MASK
260         orr     r7, r7, #(1<<5) | (2<<7)
262         @ check that the memory frequency is within limits
263         and     r14, r7, #CCCR_L_MASK
264         teq     r14, #1
265         bicne   r7, r7, #CCCR_L_MASK
266         orrne   r7, r7, #1                      @@ 99.53MHz
268         @ get ready for the change
270         @ note, turbo is not preserved over sleep so there is no
271         @ point in preserving it here. we save it on the stack with the
272         @ other CP registers instead.
273         mov     r0, #0
274         mcr     p14, 0, r0, c6, c0, 0
275         orr     r0, r0, #2                      @ initiate change bit
276         b       pxa_cpu_do_suspend
277 #endif
279         .ltorg
280         .align  5
281 pxa_cpu_do_suspend:
283         @ All needed values are now in registers.
284         @ These last instructions should be in cache
286         @ initiate the frequency change...
287         str     r7, [r6]
288         mcr     p14, 0, r0, c6, c0, 0
290         @ restore the original cpu speed value for resume
291         str     r8, [r6]
293         @ need 6 13-MHz cycles before changing PWRMODE
294         @ just set frequency to 91-MHz... 6*91/13 = 42
296         mov     r0, #42
297 10:     subs    r0, r0, #1
298         bne     10b
300         @ Do not reorder...
301         @ Intel PXA270 Specification Update notes problems performing
302         @ external accesses after SDRAM is put in self-refresh mode
303         @ (see Errata 39 ...hangs when entering self-refresh mode)
305         @ force address lines low by reading at physical address 0
306         ldr     r3, [r2]
308         @ put SDRAM into self-refresh
309         str     r5, [r4]
311         @ enter sleep mode
312         mcr     p14, 0, r1, c7, c0, 0           @ PWRMODE
314 20:     b       20b                             @ loop waiting for sleep
317  * pxa_cpu_resume()
319  * entry point from bootloader into kernel during resume
321  * Note: Yes, part of the following code is located into the .data section.
322  *       This is to allow sleep_save_sp to be accessed with a relative load
323  *       while we can't rely on any MMU translation.  We could have put
324  *       sleep_save_sp in the .text section as well, but some setups might
325  *       insist on it to be truly read-only.
326  */
328         .data
329         .align 5
330 ENTRY(pxa_cpu_resume)
331         mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE   @ set SVC, irqs off
332         msr     cpsr_c, r0
334         ldr     r0, sleep_save_sp               @ stack phys addr
335         ldr     r2, =resume_after_mmu           @ its absolute virtual address
336         ldmfd   r0, {r3 - r9, sp}               @ CP regs + virt stack ptr
338         mov     r1, #0
339         mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
340         mcr     p15, 0, r1, c7, c7, 0           @ invalidate I & D caches, BTB
342 #ifdef CONFIG_XSCALE_CACHE_ERRATA
343         bic     r9, r9, #0x0004                 @ see cpu_xscale_proc_init
344 #endif
346         mcr     p14, 0, r3, c6, c0, 0           @ clock configuration, turbo mode.
347         mcr     p15, 0, r4, c15, c1, 0          @ CP access reg
348         mcr     p15, 0, r5, c13, c0, 0          @ PID
349         mcr     p15, 0, r6, c3, c0, 0           @ domain ID
350         mcr     p15, 0, r7, c2, c0, 0           @ translation table base addr
351         mcr     p15, 0, r8, c1, c1, 0           @ auxiliary control reg
352         b       resume_turn_on_mmu              @ cache align execution
354         .align 5
355 resume_turn_on_mmu:
356         mcr     p15, 0, r9, c1, c0, 0           @ turn on MMU, caches, etc.
358         @ Let us ensure we jump to resume_after_mmu only when the mcr above
359         @ actually took effect.  They call it the "cpwait" operation.
360         mrc     p15, 0, r1, c2, c0, 0           @ queue a dependency on CP15
361         sub     pc, r2, r1, lsr #32             @ jump to virtual addr
362         nop
363         nop
364         nop
366 sleep_save_sp:
367         .word   0                               @ preserve stack phys ptr here
369         .text
370 resume_after_mmu:
371 #ifdef CONFIG_XSCALE_CACHE_ERRATA
372         bl      cpu_xscale_proc_init
373 #endif
374         ldmfd   sp!, {r2, r3}
375 #ifndef CONFIG_IWMMXT
376         mar     acc0, r2, r3
377 #endif
378         ldmfd   sp!, {r4 - r12, pc}             @ return to caller