ARM: pm: convert cpu_suspend() to a normal function
[pandora-kernel.git] / 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 <mach/hardware.h>
17 #include <mach/smemc.h>
18 #include <mach/pxa2xx-regs.h>
19
20 #define MDREFR_KDIV     0x200a4000      // all banks
21 #define CCCR_SLEEP      0x00000107      // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
22
23                 .text
24
25 #ifdef CONFIG_PXA3xx
26 /*
27  * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4)
28  *
29  * r0 = v:p offset
30  */
31 ENTRY(pxa3xx_cpu_suspend)
32
33 #ifndef CONFIG_IWMMXT
34         mra     r2, r3, acc0
35 #endif
36         stmfd   sp!, {r2 - r12, lr}     @ save registers on stack
37         mov     r1, r0
38         adr     r3, BSYM(pxa3xx_finish_suspend)
39         bl      cpu_suspend
40         b       pxa_cpu_resume
41
42 pxa3xx_finish_suspend:
43         mov     r0, #0x06               @ S2D3C4 mode
44         mcr     p14, 0, r0, c7, c0, 0   @ enter sleep
45
46 20:     b       20b                     @ waiting for sleep
47 #endif /* CONFIG_PXA3xx */
48
49 #ifdef CONFIG_PXA27x
50 /*
51  * pxa27x_cpu_suspend()
52  *
53  * Forces CPU into sleep state.
54  *
55  * r0 = value for PWRMODE M field for desired sleep state
56  * r1 = v:p offset
57  */
58 ENTRY(pxa27x_cpu_suspend)
59
60 #ifndef CONFIG_IWMMXT
61         mra     r2, r3, acc0
62 #endif
63         stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
64         mov     r2, r0                          @ save sleep mode
65         adr     r3, BSYM(pxa27x_finish_suspend)
66         bl      cpu_suspend
67         b       pxa_cpu_resume
68
69 pxa27x_finish_suspend:
70         @ Put the processor to sleep
71         @ (also workaround for sighting 28071)
72
73         @ prepare value for sleep mode
74         mov     r1, r0                          @ sleep mode
75
76         @ prepare pointer to physical address 0 (virtual mapping in generic.c)
77         mov     r2, #UNCACHED_PHYS_0
78
79         @ prepare SDRAM refresh settings
80         ldr     r4, =MDREFR
81         ldr     r5, [r4]
82
83         @ enable SDRAM self-refresh mode
84         orr     r5, r5, #MDREFR_SLFRSH
85
86         @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
87         ldr     r6, =MDREFR_KDIV
88         orr     r5, r5, r6
89
90         @ Intel PXA270 Specification Update notes problems sleeping
91         @ with core operating above 91 MHz
92         @ (see Errata 50, ...processor does not exit from sleep...)
93
94         ldr     r6, =CCCR
95         ldr     r8, [r6]                @ keep original value for resume
96
97         ldr     r7, =CCCR_SLEEP         @ prepare CCCR sleep value
98         mov     r0, #0x2                @ prepare value for CLKCFG
99
100         @ align execution to a cache line
101         b       pxa_cpu_do_suspend
102 #endif
103
104 #ifdef CONFIG_PXA25x
105 /*
106  * pxa25x_cpu_suspend()
107  *
108  * Forces CPU into sleep state.
109  *
110  * r0 = value for PWRMODE M field for desired sleep state
111  * r1 = v:p offset
112  */
113
114 ENTRY(pxa25x_cpu_suspend)
115         stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
116         mov     r2, r0                          @ save sleep mode
117         adr     r3, BSYM(pxa25x_finish_suspend)
118         bl      cpu_suspend
119         b       pxa_cpu_resume
120
121 pxa25x_finish_suspend:
122         @ prepare value for sleep mode
123         mov     r1, r0                          @ sleep mode
124
125         @ prepare pointer to physical address 0 (virtual mapping in generic.c)
126         mov     r2, #UNCACHED_PHYS_0
127
128         @ prepare SDRAM refresh settings
129         ldr     r4, =MDREFR
130         ldr     r5, [r4]
131
132         @ enable SDRAM self-refresh mode
133         orr     r5, r5, #MDREFR_SLFRSH
134
135         @ Intel PXA255 Specification Update notes problems
136         @ about suspending with PXBus operating above 133MHz
137         @ (see Errata 31, GPIO output signals, ... unpredictable in sleep
138         @
139         @ We keep the change-down close to the actual suspend on SDRAM
140         @ as possible to eliminate messing about with the refresh clock
141         @ as the system will restore with the original speed settings
142         @
143         @ Ben Dooks, 13-Sep-2004
144
145         ldr     r6, =CCCR
146         ldr     r8, [r6]                @ keep original value for resume
147
148         @ ensure x1 for run and turbo mode with memory clock
149         bic     r7, r8, #CCCR_M_MASK | CCCR_N_MASK
150         orr     r7, r7, #(1<<5) | (2<<7)
151
152         @ check that the memory frequency is within limits
153         and     r14, r7, #CCCR_L_MASK
154         teq     r14, #1
155         bicne   r7, r7, #CCCR_L_MASK
156         orrne   r7, r7, #1                      @@ 99.53MHz
157
158         @ get ready for the change
159
160         @ note, turbo is not preserved over sleep so there is no
161         @ point in preserving it here. we save it on the stack with the
162         @ other CP registers instead.
163         mov     r0, #0
164         mcr     p14, 0, r0, c6, c0, 0
165         orr     r0, r0, #2                      @ initiate change bit
166         b       pxa_cpu_do_suspend
167 #endif
168
169         .ltorg
170         .align  5
171 pxa_cpu_do_suspend:
172
173         @ All needed values are now in registers.
174         @ These last instructions should be in cache
175
176         @ initiate the frequency change...
177         str     r7, [r6]
178         mcr     p14, 0, r0, c6, c0, 0
179
180         @ restore the original cpu speed value for resume
181         str     r8, [r6]
182
183         @ need 6 13-MHz cycles before changing PWRMODE
184         @ just set frequency to 91-MHz... 6*91/13 = 42
185
186         mov     r0, #42
187 10:     subs    r0, r0, #1
188         bne     10b
189
190         @ Do not reorder...
191         @ Intel PXA270 Specification Update notes problems performing
192         @ external accesses after SDRAM is put in self-refresh mode
193         @ (see Errata 39 ...hangs when entering self-refresh mode)
194
195         @ force address lines low by reading at physical address 0
196         ldr     r3, [r2]
197
198         @ put SDRAM into self-refresh
199         str     r5, [r4]
200
201         @ enter sleep mode
202         mcr     p14, 0, r1, c7, c0, 0           @ PWRMODE
203
204 20:     b       20b                             @ loop waiting for sleep
205
206 /*
207  * pxa_cpu_resume()
208  *
209  * entry point from bootloader into kernel during resume
210  */
211         .align 5
212 pxa_cpu_resume:
213         ldmfd   sp!, {r2, r3}
214 #ifndef CONFIG_IWMMXT
215         mar     acc0, r2, r3
216 #endif
217         ldmfd   sp!, {r4 - r12, pc}             @ return to caller