Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[linux-2.6] / arch / arm / mach-pxa / sleep.S
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  */
13
14 #include <linux/linkage.h>
15 #include <asm/assembler.h>
16 #include <asm/hardware.h>
17
18 #include <asm/arch/pxa-regs.h>
19 #include <asm/arch/pxa2xx-regs.h>
20
21 #define MDREFR_KDIV     0x200a4000      // all banks
22 #define CCCR_SLEEP      0x00000107      // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
23
24                 .text
25
26 pxa_cpu_save_cp:
27         @ get coprocessor registers
28         mrc     p14, 0, r3, c6, c0, 0           @ clock configuration, for turbo mode
29         mrc     p15, 0, r4, c15, c1, 0          @ CP access reg
30         mrc     p15, 0, r5, c13, c0, 0          @ PID
31         mrc     p15, 0, r6, c3, c0, 0           @ domain ID
32         mrc     p15, 0, r7, c2, c0, 0           @ translation table base addr
33         mrc     p15, 0, r8, c1, c1, 0           @ auxiliary control reg
34         mrc     p15, 0, r9, c1, c0, 0           @ control reg
35
36         bic     r3, r3, #2                      @ clear frequency change bit
37
38         @ store them plus current virtual stack ptr on stack
39         mov     r10, sp
40         stmfd   sp!, {r3 - r10}
41
42         mov     pc, lr
43
44 pxa_cpu_save_sp:
45         @ preserve phys address of stack
46         mov     r0, sp
47         str     lr, [sp, #-4]!
48         bl      sleep_phys_sp
49         ldr     r1, =sleep_save_sp
50         str     r0, [r1]
51         ldr     pc, [sp], #4
52
53 #ifdef CONFIG_PXA27x
54 /*
55  * pxa27x_cpu_suspend()
56  *
57  * Forces CPU into sleep state.
58  *
59  * r0 = value for PWRMODE M field for desired sleep state
60  */
61
62 ENTRY(pxa27x_cpu_suspend)
63
64 #ifndef CONFIG_IWMMXT
65         mra     r2, r3, acc0
66 #endif
67         stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
68
69         bl      pxa_cpu_save_cp
70
71         mov     r5, r0                          @ save sleep mode
72         bl      pxa_cpu_save_sp
73
74         @ clean data cache
75         bl      xscale_flush_kern_cache_all
76
77         @ Put the processor to sleep
78         @ (also workaround for sighting 28071)
79
80         @ prepare value for sleep mode
81         mov     r1, r5                          @ sleep mode
82
83         @ prepare pointer to physical address 0 (virtual mapping in generic.c)
84         mov     r2, #UNCACHED_PHYS_0
85
86         @ prepare SDRAM refresh settings
87         ldr     r4, =MDREFR
88         ldr     r5, [r4]
89
90         @ enable SDRAM self-refresh mode
91         orr     r5, r5, #MDREFR_SLFRSH
92
93         @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
94         ldr     r6, =MDREFR_KDIV
95         orr     r5, r5, r6
96
97         @ Intel PXA270 Specification Update notes problems sleeping
98         @ with core operating above 91 MHz
99         @ (see Errata 50, ...processor does not exit from sleep...)
100
101         ldr     r6, =CCCR
102         ldr     r8, [r6]                @ keep original value for resume
103
104         ldr     r7, =CCCR_SLEEP         @ prepare CCCR sleep value
105         mov     r0, #0x2                @ prepare value for CLKCFG
106
107         @ align execution to a cache line
108         b       pxa_cpu_do_suspend
109 #endif
110
111 #ifdef CONFIG_PXA25x
112 /*
113  * pxa25x_cpu_suspend()
114  *
115  * Forces CPU into sleep state.
116  *
117  * r0 = value for PWRMODE M field for desired sleep state
118  */
119
120 ENTRY(pxa25x_cpu_suspend)
121         stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
122
123         bl      pxa_cpu_save_cp
124
125         mov     r5, r0                          @ save sleep mode
126         bl      pxa_cpu_save_sp
127
128         @ clean data cache
129         bl      xscale_flush_kern_cache_all
130
131         @ prepare value for sleep mode
132         mov     r1, r5                          @ sleep mode
133
134         @ prepare pointer to physical address 0 (virtual mapping in generic.c)
135         mov     r2, #UNCACHED_PHYS_0
136
137         @ prepare SDRAM refresh settings
138         ldr     r4, =MDREFR
139         ldr     r5, [r4]
140
141         @ enable SDRAM self-refresh mode
142         orr     r5, r5, #MDREFR_SLFRSH
143
144         @ Intel PXA255 Specification Update notes problems
145         @ about suspending with PXBus operating above 133MHz
146         @ (see Errata 31, GPIO output signals, ... unpredictable in sleep
147         @
148         @ We keep the change-down close to the actual suspend on SDRAM
149         @ as possible to eliminate messing about with the refresh clock
150         @ as the system will restore with the original speed settings
151         @
152         @ Ben Dooks, 13-Sep-2004
153
154         ldr     r6, =CCCR
155         ldr     r8, [r6]                @ keep original value for resume
156
157         @ ensure x1 for run and turbo mode with memory clock
158         bic     r7, r8, #CCCR_M_MASK | CCCR_N_MASK
159         orr     r7, r7, #(1<<5) | (2<<7)
160
161         @ check that the memory frequency is within limits
162         and     r14, r7, #CCCR_L_MASK
163         teq     r14, #1
164         bicne   r7, r7, #CCCR_L_MASK
165         orrne   r7, r7, #1                      @@ 99.53MHz
166
167         @ get ready for the change
168
169         @ note, turbo is not preserved over sleep so there is no
170         @ point in preserving it here. we save it on the stack with the
171         @ other CP registers instead.
172         mov     r0, #0
173         mcr     p14, 0, r0, c6, c0, 0
174         orr     r0, r0, #2                      @ initiate change bit
175         b       pxa_cpu_do_suspend
176 #endif
177
178         .ltorg
179         .align  5
180 pxa_cpu_do_suspend:
181
182         @ All needed values are now in registers.
183         @ These last instructions should be in cache
184
185         @ initiate the frequency change...
186         str     r7, [r6]
187         mcr     p14, 0, r0, c6, c0, 0
188
189         @ restore the original cpu speed value for resume
190         str     r8, [r6]
191
192         @ need 6 13-MHz cycles before changing PWRMODE
193         @ just set frequency to 91-MHz... 6*91/13 = 42
194
195         mov     r0, #42
196 10:     subs    r0, r0, #1
197         bne     10b
198
199         @ Do not reorder...
200         @ Intel PXA270 Specification Update notes problems performing
201         @ external accesses after SDRAM is put in self-refresh mode
202         @ (see Errata 39 ...hangs when entering self-refresh mode)
203
204         @ force address lines low by reading at physical address 0
205         ldr     r3, [r2]
206
207         @ put SDRAM into self-refresh
208         str     r5, [r4]
209
210         @ enter sleep mode
211         mcr     p14, 0, r1, c7, c0, 0           @ PWRMODE
212
213 20:     b       20b                             @ loop waiting for sleep
214
215 /*
216  * pxa_cpu_resume()
217  *
218  * entry point from bootloader into kernel during resume
219  *
220  * Note: Yes, part of the following code is located into the .data section.
221  *       This is to allow sleep_save_sp to be accessed with a relative load
222  *       while we can't rely on any MMU translation.  We could have put
223  *       sleep_save_sp in the .text section as well, but some setups might
224  *       insist on it to be truly read-only.
225  */
226
227         .data
228         .align 5
229 ENTRY(pxa_cpu_resume)
230         mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE   @ set SVC, irqs off
231         msr     cpsr_c, r0
232
233         ldr     r0, sleep_save_sp               @ stack phys addr
234         ldr     r2, =resume_after_mmu           @ its absolute virtual address
235         ldmfd   r0, {r3 - r9, sp}               @ CP regs + virt stack ptr
236
237         mov     r1, #0
238         mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
239         mcr     p15, 0, r1, c7, c7, 0           @ invalidate I & D caches, BTB
240
241 #ifdef CONFIG_XSCALE_CACHE_ERRATA
242         bic     r9, r9, #0x0004                 @ see cpu_xscale_proc_init
243 #endif
244
245         mcr     p14, 0, r3, c6, c0, 0           @ clock configuration, turbo mode.
246         mcr     p15, 0, r4, c15, c1, 0          @ CP access reg
247         mcr     p15, 0, r5, c13, c0, 0          @ PID
248         mcr     p15, 0, r6, c3, c0, 0           @ domain ID
249         mcr     p15, 0, r7, c2, c0, 0           @ translation table base addr
250         mcr     p15, 0, r8, c1, c1, 0           @ auxiliary control reg
251         b       resume_turn_on_mmu              @ cache align execution
252
253         .align 5
254 resume_turn_on_mmu:
255         mcr     p15, 0, r9, c1, c0, 0           @ turn on MMU, caches, etc.
256
257         @ Let us ensure we jump to resume_after_mmu only when the mcr above
258         @ actually took effect.  They call it the "cpwait" operation.
259         mrc     p15, 0, r1, c2, c0, 0           @ queue a dependency on CP15
260         sub     pc, r2, r1, lsr #32             @ jump to virtual addr
261         nop
262         nop
263         nop
264
265 sleep_save_sp:
266         .word   0                               @ preserve stack phys ptr here
267
268         .text
269 resume_after_mmu:
270 #ifdef CONFIG_XSCALE_CACHE_ERRATA
271         bl      cpu_xscale_proc_init
272 #endif
273         ldmfd   sp!, {r2, r3}
274 #ifndef CONFIG_IWMMXT
275         mar     acc0, r2, r3
276 #endif
277         ldmfd   sp!, {r4 - r12, pc}             @ return to caller