Merge tag 'for-linus' of git://github.com/prasad-joshi/logfs_upstream
[sfrench/cifs-2.6.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 #if defined(CONFIG_ARCH_AT91RM9200)
20 #include <mach/at91rm9200_mc.h>
21 #elif defined(CONFIG_ARCH_AT91CAP9) \
22         || defined(CONFIG_ARCH_AT91SAM9G45)
23 #include <mach/at91sam9_ddrsdr.h>
24 #else
25 #include <mach/at91sam9_sdramc.h>
26 #endif
27
28
29 #ifdef CONFIG_ARCH_AT91SAM9263
30 /*
31  * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
32  * handle those cases both here and in the Suspend-To-RAM support.
33  */
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 RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
117          *  R3 = temporary register
118          *  R4 = temporary register
119          *  R5 = Base address of second RAM Controller or 0 if not present
120          */
121         ldr     r1, .at91_va_base_pmc
122         ldr     r2, .at91_va_base_sdramc
123         ldr     r5, .at91_va_base_ramc1
124
125         /* Drain write buffer */
126         mov     r0, #0
127         mcr     p15, 0, r0, c7, c10, 4
128
129 #ifdef CONFIG_ARCH_AT91RM9200
130         /* Put SDRAM in self-refresh mode */
131         mov     r3, #1
132         str     r3, [r2, #AT91_SDRAMC_SRR]
133 #elif defined(CONFIG_ARCH_AT91CAP9) \
134         || defined(CONFIG_ARCH_AT91SAM9G45)
135
136         /* prepare for DDRAM self-refresh mode */
137         ldr     r3, [r2, #AT91_DDRSDRC_LPR]
138         str     r3, .saved_sam9_lpr
139         bic     r3, #AT91_DDRSDRC_LPCB
140         orr     r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
141
142         /* figure out if we use the second ram controller */
143         cmp     r5, #0
144         ldrne   r4, [r5, #AT91_DDRSDRC_LPR]
145         strne   r4, .saved_sam9_lpr1
146         bicne   r4, #AT91_DDRSDRC_LPCB
147         orrne   r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH
148
149         /* Enable DDRAM self-refresh mode */
150         str     r3, [r2, #AT91_DDRSDRC_LPR]
151         strne   r4, [r5, #AT91_DDRSDRC_LPR]
152 #else
153         /* Enable SDRAM self-refresh mode */
154         ldr     r3, [r2, #AT91_SDRAMC_LPR]
155         str     r3, .saved_sam9_lpr
156
157         bic     r3, #AT91_SDRAMC_LPCB
158         orr     r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
159         str     r3, [r2, #AT91_SDRAMC_LPR]
160 #endif
161
162         /* Save Master clock setting */
163         ldr     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
164         str     r3, .saved_mckr
165
166         /*
167          * Set the Master clock source to slow clock
168          */
169         bic     r3, r3, #AT91_PMC_CSS
170         str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
171
172         wait_mckrdy
173
174 #ifdef SLOWDOWN_MASTER_CLOCK
175         /*
176          * Set the Master Clock PRES and MDIV fields.
177          *
178          * See AT91RM9200 errata #27 and #28 for details.
179          */
180         mov     r3, #0
181         str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
182
183         wait_mckrdy
184 #endif
185
186         /* Save PLLA setting and disable it */
187         ldr     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
188         str     r3, .saved_pllar
189
190         mov     r3, #AT91_PMC_PLLCOUNT
191         orr     r3, r3, #(1 << 29)              /* bit 29 always set */
192         str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
193
194         /* Save PLLB setting and disable it */
195         ldr     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
196         str     r3, .saved_pllbr
197
198         mov     r3, #AT91_PMC_PLLCOUNT
199         str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
200
201         /* Turn off the main oscillator */
202         ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
203         bic     r3, r3, #AT91_PMC_MOSCEN
204         str     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
205
206         /* Wait for interrupt */
207         mcr     p15, 0, r0, c7, c0, 4
208
209         /* Turn on the main oscillator */
210         ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
211         orr     r3, r3, #AT91_PMC_MOSCEN
212         str     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
213
214         wait_moscrdy
215
216         /* Restore PLLB setting */
217         ldr     r3, .saved_pllbr
218         str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
219
220         tst     r3, #(AT91_PMC_MUL &  0xff0000)
221         bne     1f
222         tst     r3, #(AT91_PMC_MUL & ~0xff0000)
223         beq     2f
224 1:
225         wait_pllblock
226 2:
227
228         /* Restore PLLA setting */
229         ldr     r3, .saved_pllar
230         str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
231
232         tst     r3, #(AT91_PMC_MUL &  0xff0000)
233         bne     3f
234         tst     r3, #(AT91_PMC_MUL & ~0xff0000)
235         beq     4f
236 3:
237         wait_pllalock
238 4:
239
240 #ifdef SLOWDOWN_MASTER_CLOCK
241         /*
242          * First set PRES if it was not 0,
243          * than set CSS and MDIV fields.
244          *
245          * See AT91RM9200 errata #27 and #28 for details.
246          */
247         ldr     r3, .saved_mckr
248         tst     r3, #AT91_PMC_PRES
249         beq     2f
250         and     r3, r3, #AT91_PMC_PRES
251         str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
252
253         wait_mckrdy
254 #endif
255
256         /*
257          * Restore master clock setting
258          */
259 2:      ldr     r3, .saved_mckr
260         str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
261
262         wait_mckrdy
263
264 #ifdef CONFIG_ARCH_AT91RM9200
265         /* Do nothing - self-refresh is automatically disabled. */
266 #elif defined(CONFIG_ARCH_AT91CAP9) \
267         || defined(CONFIG_ARCH_AT91SAM9G45)
268         /* Restore LPR on AT91 with DDRAM */
269         ldr     r3, .saved_sam9_lpr
270         str     r3, [r2, #AT91_DDRSDRC_LPR]
271
272         /* if we use the second ram controller */
273         cmp     r5, #0
274         ldrne   r4, .saved_sam9_lpr1
275         strne   r4, [r5, #AT91_DDRSDRC_LPR]
276
277 #else
278         /* Restore LPR on AT91 with SDRAM */
279         ldr     r3, .saved_sam9_lpr
280         str     r3, [r2, #AT91_SDRAMC_LPR]
281 #endif
282
283         /* Restore registers, and return */
284         ldmfd   sp!, {r0 - r12, pc}
285
286
287 .saved_mckr:
288         .word 0
289
290 .saved_pllar:
291         .word 0
292
293 .saved_pllbr:
294         .word 0
295
296 .saved_sam9_lpr:
297         .word 0
298
299 .saved_sam9_lpr1:
300         .word 0
301
302 .at91_va_base_pmc:
303         .word AT91_VA_BASE_SYS + AT91_PMC
304
305 #ifdef CONFIG_ARCH_AT91RM9200
306 .at91_va_base_sdramc:
307         .word AT91_VA_BASE_SYS
308 #elif defined(CONFIG_ARCH_AT91CAP9) \
309         || defined(CONFIG_ARCH_AT91SAM9G45)
310 .at91_va_base_sdramc:
311         .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
312 #else
313 .at91_va_base_sdramc:
314         .word AT91_VA_BASE_SYS + AT91_SDRAMC0
315 #endif
316
317 .at91_va_base_ramc1:
318 #if defined(CONFIG_ARCH_AT91SAM9G45)
319         .word AT91_VA_BASE_SYS + AT91_DDRSDRC1
320 #else
321         .word 0
322 #endif
323
324 ENTRY(at91_slow_clock_sz)
325         .word .-at91_slow_clock