Merge branch 'rc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuil...
[pandora-kernel.git] / arch / arm / mach-at91 / pm_slowclock.S
1 /*
2  * arch/arm/mach-at91/pm_slow_clock.S
3  *
4  *  Copyright (C) 2006 Savin Zlobec
5  *
6  * AT91SAM9 support:
7  *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  */
14
15 #include <linux/linkage.h>
16 #include <mach/hardware.h>
17 #include <mach/at91_pmc.h>
18
19 #ifdef CONFIG_ARCH_AT91RM9200
20 #include <mach/at91rm9200_mc.h>
21 #elif defined(CONFIG_ARCH_AT91CAP9)
22 #include <mach/at91cap9_ddrsdr.h>
23 #else
24 #include <mach/at91sam9_sdramc.h>
25 #endif
26
27
28 #ifdef CONFIG_ARCH_AT91SAM9263
29 /*
30  * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
31  * handle those cases both here and in the Suspend-To-RAM support.
32  */
33 #define AT91_SDRAMC     AT91_SDRAMC0
34 #warning Assuming EB1 SDRAM controller is *NOT* used
35 #endif
36
37 /*
38  * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
39  * clock during suspend by adjusting its prescalar and divisor.
40  * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
41  *       are errata regarding adjusting the prescalar and divisor.
42  */
43 #undef SLOWDOWN_MASTER_CLOCK
44
45 #define MCKRDY_TIMEOUT          1000
46 #define MOSCRDY_TIMEOUT         1000
47 #define PLLALOCK_TIMEOUT        1000
48 #define PLLBLOCK_TIMEOUT        1000
49
50
51 /*
52  * Wait until master clock is ready (after switching master clock source)
53  */
54         .macro wait_mckrdy
55         mov     r4, #MCKRDY_TIMEOUT
56 1:      sub     r4, r4, #1
57         cmp     r4, #0
58         beq     2f
59         ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
60         tst     r3, #AT91_PMC_MCKRDY
61         beq     1b
62 2:
63         .endm
64
65 /*
66  * Wait until master oscillator has stabilized.
67  */
68         .macro wait_moscrdy
69         mov     r4, #MOSCRDY_TIMEOUT
70 1:      sub     r4, r4, #1
71         cmp     r4, #0
72         beq     2f
73         ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
74         tst     r3, #AT91_PMC_MOSCS
75         beq     1b
76 2:
77         .endm
78
79 /*
80  * Wait until PLLA has locked.
81  */
82         .macro wait_pllalock
83         mov     r4, #PLLALOCK_TIMEOUT
84 1:      sub     r4, r4, #1
85         cmp     r4, #0
86         beq     2f
87         ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
88         tst     r3, #AT91_PMC_LOCKA
89         beq     1b
90 2:
91         .endm
92
93 /*
94  * Wait until PLLB has locked.
95  */
96         .macro wait_pllblock
97         mov     r4, #PLLBLOCK_TIMEOUT
98 1:      sub     r4, r4, #1
99         cmp     r4, #0
100         beq     2f
101         ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
102         tst     r3, #AT91_PMC_LOCKB
103         beq     1b
104 2:
105         .endm
106
107         .text
108
109 ENTRY(at91_slow_clock)
110         /* Save registers on stack */
111         stmfd   sp!, {r0 - r12, lr}
112
113         /*
114          * Register usage:
115          *  R1 = Base address of AT91_PMC
116          *  R2 = Base address of AT91_SDRAMC (or AT91_SYS on AT91RM9200)
117          *  R3 = temporary register
118          *  R4 = temporary register
119          */
120         ldr     r1, .at91_va_base_pmc
121         ldr     r2, .at91_va_base_sdramc
122
123         /* Drain write buffer */
124         mcr     p15, 0, r0, c7, c10, 4
125
126 #ifdef CONFIG_ARCH_AT91RM9200
127         /* Put SDRAM in self-refresh mode */
128         mov     r3, #1
129         str     r3, [r2, #AT91_SDRAMC_SRR]
130 #elif defined(CONFIG_ARCH_AT91CAP9)
131         /* Enable SDRAM self-refresh mode */
132         ldr     r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
133         str     r3, .saved_sam9_lpr
134
135         mov     r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
136         str     r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
137 #else
138         /* Enable SDRAM self-refresh mode */
139         ldr     r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
140         str     r3, .saved_sam9_lpr
141
142         mov     r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
143         str     r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
144 #endif
145
146         /* Save Master clock setting */
147         ldr     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
148         str     r3, .saved_mckr
149
150         /*
151          * Set the Master clock source to slow clock
152          */
153         bic     r3, r3, #AT91_PMC_CSS
154         str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
155
156         wait_mckrdy
157
158 #ifdef SLOWDOWN_MASTER_CLOCK
159         /*
160          * Set the Master Clock PRES and MDIV fields.
161          *
162          * See AT91RM9200 errata #27 and #28 for details.
163          */
164         mov     r3, #0
165         str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
166
167         wait_mckrdy
168 #endif
169
170         /* Save PLLA setting and disable it */
171         ldr     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
172         str     r3, .saved_pllar
173
174         mov     r3, #AT91_PMC_PLLCOUNT
175         orr     r3, r3, #(1 << 29)              /* bit 29 always set */
176         str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
177
178         /* Save PLLB setting and disable it */
179         ldr     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
180         str     r3, .saved_pllbr
181
182         mov     r3, #AT91_PMC_PLLCOUNT
183         str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
184
185         /* Turn off the main oscillator */
186         ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
187         bic     r3, r3, #AT91_PMC_MOSCEN
188         str     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
189
190         /* Wait for interrupt */
191         mcr     p15, 0, r0, c7, c0, 4
192
193         /* Turn on the main oscillator */
194         ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
195         orr     r3, r3, #AT91_PMC_MOSCEN
196         str     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
197
198         wait_moscrdy
199
200         /* Restore PLLB setting */
201         ldr     r3, .saved_pllbr
202         str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
203
204         tst     r3, #(AT91_PMC_MUL &  0xff0000)
205         bne     1f
206         tst     r3, #(AT91_PMC_MUL & ~0xff0000)
207         beq     2f
208 1:
209         wait_pllblock
210 2:
211
212         /* Restore PLLA setting */
213         ldr     r3, .saved_pllar
214         str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
215
216         tst     r3, #(AT91_PMC_MUL &  0xff0000)
217         bne     3f
218         tst     r3, #(AT91_PMC_MUL & ~0xff0000)
219         beq     4f
220 3:
221         wait_pllalock
222 4:
223
224 #ifdef SLOWDOWN_MASTER_CLOCK
225         /*
226          * First set PRES if it was not 0,
227          * than set CSS and MDIV fields.
228          *
229          * See AT91RM9200 errata #27 and #28 for details.
230          */
231         ldr     r3, .saved_mckr
232         tst     r3, #AT91_PMC_PRES
233         beq     2f
234         and     r3, r3, #AT91_PMC_PRES
235         str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
236
237         wait_mckrdy
238 #endif
239
240         /*
241          * Restore master clock setting
242          */
243 2:      ldr     r3, .saved_mckr
244         str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
245
246         wait_mckrdy
247
248 #ifdef CONFIG_ARCH_AT91RM9200
249         /* Do nothing - self-refresh is automatically disabled. */
250 #elif defined(CONFIG_ARCH_AT91CAP9)
251         /* Restore LPR on AT91CAP9 */
252         ldr     r3, .saved_sam9_lpr
253         str     r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
254 #else
255         /* Restore LPR on AT91SAM9 */
256         ldr     r3, .saved_sam9_lpr
257         str     r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
258 #endif
259
260         /* Restore registers, and return */
261         ldmfd   sp!, {r0 - r12, pc}
262
263
264 .saved_mckr:
265         .word 0
266
267 .saved_pllar:
268         .word 0
269
270 .saved_pllbr:
271         .word 0
272
273 .saved_sam9_lpr:
274         .word 0
275
276 .at91_va_base_pmc:
277         .word AT91_VA_BASE_SYS + AT91_PMC
278
279 #ifdef CONFIG_ARCH_AT91RM9200
280 .at91_va_base_sdramc:
281         .word AT91_VA_BASE_SYS
282 #elif defined(CONFIG_ARCH_AT91CAP9)
283 .at91_va_base_sdramc:
284         .word AT91_VA_BASE_SYS + AT91_DDRSDRC
285 #else
286 .at91_va_base_sdramc:
287         .word AT91_VA_BASE_SYS + AT91_SDRAMC
288 #endif
289
290 ENTRY(at91_slow_clock_sz)
291         .word .-at91_slow_clock