Merge git://git.infradead.org/iommu-2.6
[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 #if defined(CONFIG_ARCH_AT91RM9200)
20 #include <mach/at91rm9200_mc.h>
21 #elif defined(CONFIG_ARCH_AT91CAP9)
22 #include <mach/at91cap9_ddrsdr.h>
23 #elif defined(CONFIG_ARCH_AT91SAM9G45)
24 #include <mach/at91sam9_ddrsdr.h>
25 #else
26 #include <mach/at91sam9_sdramc.h>
27 #endif
28
29
30 #ifdef CONFIG_ARCH_AT91SAM9263
31 /*
32  * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
33  * handle those cases both here and in the Suspend-To-RAM support.
34  */
35 #warning Assuming EB1 SDRAM controller is *NOT* used
36 #endif
37
38 /*
39  * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
40  * clock during suspend by adjusting its prescalar and divisor.
41  * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
42  *       are errata regarding adjusting the prescalar and divisor.
43  */
44 #undef SLOWDOWN_MASTER_CLOCK
45
46 #define MCKRDY_TIMEOUT          1000
47 #define MOSCRDY_TIMEOUT         1000
48 #define PLLALOCK_TIMEOUT        1000
49 #define PLLBLOCK_TIMEOUT        1000
50
51
52 /*
53  * Wait until master clock is ready (after switching master clock source)
54  */
55         .macro wait_mckrdy
56         mov     r4, #MCKRDY_TIMEOUT
57 1:      sub     r4, r4, #1
58         cmp     r4, #0
59         beq     2f
60         ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
61         tst     r3, #AT91_PMC_MCKRDY
62         beq     1b
63 2:
64         .endm
65
66 /*
67  * Wait until master oscillator has stabilized.
68  */
69         .macro wait_moscrdy
70         mov     r4, #MOSCRDY_TIMEOUT
71 1:      sub     r4, r4, #1
72         cmp     r4, #0
73         beq     2f
74         ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
75         tst     r3, #AT91_PMC_MOSCS
76         beq     1b
77 2:
78         .endm
79
80 /*
81  * Wait until PLLA has locked.
82  */
83         .macro wait_pllalock
84         mov     r4, #PLLALOCK_TIMEOUT
85 1:      sub     r4, r4, #1
86         cmp     r4, #0
87         beq     2f
88         ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
89         tst     r3, #AT91_PMC_LOCKA
90         beq     1b
91 2:
92         .endm
93
94 /*
95  * Wait until PLLB has locked.
96  */
97         .macro wait_pllblock
98         mov     r4, #PLLBLOCK_TIMEOUT
99 1:      sub     r4, r4, #1
100         cmp     r4, #0
101         beq     2f
102         ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
103         tst     r3, #AT91_PMC_LOCKB
104         beq     1b
105 2:
106         .endm
107
108         .text
109
110 ENTRY(at91_slow_clock)
111         /* Save registers on stack */
112         stmfd   sp!, {r0 - r12, lr}
113
114         /*
115          * Register usage:
116          *  R1 = Base address of AT91_PMC
117          *  R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
118          *  R3 = temporary register
119          *  R4 = temporary register
120          *  R5 = Base address of second RAM Controller or 0 if not present
121          */
122         ldr     r1, .at91_va_base_pmc
123         ldr     r2, .at91_va_base_sdramc
124         ldr     r5, .at91_va_base_ramc1
125
126         /* Drain write buffer */
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