ARM: at91: pm: remove warning to remove SOC_AT91SAM9263 usage
[cascardo/linux.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 <linux/clk/at91_pmc.h>
17 #include <mach/hardware.h>
18 #include <mach/at91_ramc.h>
19
20 /*
21  * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
22  * clock during suspend by adjusting its prescalar and divisor.
23  * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
24  *       are errata regarding adjusting the prescalar and divisor.
25  */
26 #undef SLOWDOWN_MASTER_CLOCK
27
28 #define MCKRDY_TIMEOUT          1000
29 #define MOSCRDY_TIMEOUT         1000
30 #define PLLALOCK_TIMEOUT        1000
31 #define PLLBLOCK_TIMEOUT        1000
32
33 pmc     .req    r0
34 sdramc  .req    r1
35 ramc1   .req    r2
36 memctrl .req    r3
37 tmp1    .req    r4
38 tmp2    .req    r5
39
40 /*
41  * Wait until master clock is ready (after switching master clock source)
42  */
43         .macro wait_mckrdy
44         mov     tmp2, #MCKRDY_TIMEOUT
45 1:      sub     tmp2, tmp2, #1
46         cmp     tmp2, #0
47         beq     2f
48         ldr     tmp1, [pmc, #AT91_PMC_SR]
49         tst     tmp1, #AT91_PMC_MCKRDY
50         beq     1b
51 2:
52         .endm
53
54 /*
55  * Wait until master oscillator has stabilized.
56  */
57         .macro wait_moscrdy
58         mov     tmp2, #MOSCRDY_TIMEOUT
59 1:      sub     tmp2, tmp2, #1
60         cmp     tmp2, #0
61         beq     2f
62         ldr     tmp1, [pmc, #AT91_PMC_SR]
63         tst     tmp1, #AT91_PMC_MOSCS
64         beq     1b
65 2:
66         .endm
67
68 /*
69  * Wait until PLLA has locked.
70  */
71         .macro wait_pllalock
72         mov     tmp2, #PLLALOCK_TIMEOUT
73 1:      sub     tmp2, tmp2, #1
74         cmp     tmp2, #0
75         beq     2f
76         ldr     tmp1, [pmc, #AT91_PMC_SR]
77         tst     tmp1, #AT91_PMC_LOCKA
78         beq     1b
79 2:
80         .endm
81
82 /*
83  * Wait until PLLB has locked.
84  */
85         .macro wait_pllblock
86         mov     tmp2, #PLLBLOCK_TIMEOUT
87 1:      sub     tmp2, tmp2, #1
88         cmp     tmp2, #0
89         beq     2f
90         ldr     tmp1, [pmc, #AT91_PMC_SR]
91         tst     tmp1, #AT91_PMC_LOCKB
92         beq     1b
93 2:
94         .endm
95
96         .text
97
98 /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
99  *                      void __iomem *ramc1, int memctrl)
100  */
101 ENTRY(at91_slow_clock)
102         /* Save registers on stack */
103         stmfd   sp!, {r4 - r12, lr}
104
105         /*
106          * Register usage:
107          *  R0 = Base address of AT91_PMC
108          *  R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
109          *  R2 = Base address of second RAM Controller or 0 if not present
110          *  R3 = Memory controller
111          *  R4 = temporary register
112          *  R5 = temporary register
113          */
114
115         /* Drain write buffer */
116         mov     tmp1, #0
117         mcr     p15, 0, tmp1, c7, c10, 4
118
119         cmp     memctrl, #AT91_MEMCTRL_MC
120         bne     ddr_sr_enable
121
122         /*
123          * at91rm9200 Memory controller
124          */
125         /* Put SDRAM in self-refresh mode */
126         mov     tmp1, #1
127         str     tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
128         b       sdr_sr_done
129
130         /*
131          * DDRSDR Memory controller
132          */
133 ddr_sr_enable:
134         cmp     memctrl, #AT91_MEMCTRL_DDRSDR
135         bne     sdr_sr_enable
136
137         /* prepare for DDRAM self-refresh mode */
138         ldr     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
139         str     tmp1, .saved_sam9_lpr
140         bic     tmp1, #AT91_DDRSDRC_LPCB
141         orr     tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
142
143         /* figure out if we use the second ram controller */
144         cmp     ramc1, #0
145         ldrne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
146         strne   tmp2, .saved_sam9_lpr1
147         bicne   tmp2, #AT91_DDRSDRC_LPCB
148         orrne   tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
149
150         /* Enable DDRAM self-refresh mode */
151         str     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
152         strne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
153
154         b       sdr_sr_done
155
156         /*
157          * SDRAMC Memory controller
158          */
159 sdr_sr_enable:
160         /* Enable SDRAM self-refresh mode */
161         ldr     tmp1, [sdramc, #AT91_SDRAMC_LPR]
162         str     tmp1, .saved_sam9_lpr
163
164         bic     tmp1, #AT91_SDRAMC_LPCB
165         orr     tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
166         str     tmp1, [sdramc, #AT91_SDRAMC_LPR]
167
168 sdr_sr_done:
169         /* Save Master clock setting */
170         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
171         str     tmp1, .saved_mckr
172
173         /*
174          * Set the Master clock source to slow clock
175          */
176         bic     tmp1, tmp1, #AT91_PMC_CSS
177         str     tmp1, [pmc, #AT91_PMC_MCKR]
178
179         wait_mckrdy
180
181 #ifdef SLOWDOWN_MASTER_CLOCK
182         /*
183          * Set the Master Clock PRES and MDIV fields.
184          *
185          * See AT91RM9200 errata #27 and #28 for details.
186          */
187         mov     tmp1, #0
188         str     tmp1, [pmc, #AT91_PMC_MCKR]
189
190         wait_mckrdy
191 #endif
192
193         /* Save PLLA setting and disable it */
194         ldr     tmp1, [pmc, #AT91_CKGR_PLLAR]
195         str     tmp1, .saved_pllar
196
197         mov     tmp1, #AT91_PMC_PLLCOUNT
198         orr     tmp1, tmp1, #(1 << 29)          /* bit 29 always set */
199         str     tmp1, [pmc, #AT91_CKGR_PLLAR]
200
201         /* Save PLLB setting and disable it */
202         ldr     tmp1, [pmc, #AT91_CKGR_PLLBR]
203         str     tmp1, .saved_pllbr
204
205         mov     tmp1, #AT91_PMC_PLLCOUNT
206         str     tmp1, [pmc, #AT91_CKGR_PLLBR]
207
208         /* Turn off the main oscillator */
209         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
210         bic     tmp1, tmp1, #AT91_PMC_MOSCEN
211         str     tmp1, [pmc, #AT91_CKGR_MOR]
212
213         /* Wait for interrupt */
214         mcr     p15, 0, tmp1, c7, c0, 4
215
216         /* Turn on the main oscillator */
217         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
218         orr     tmp1, tmp1, #AT91_PMC_MOSCEN
219         str     tmp1, [pmc, #AT91_CKGR_MOR]
220
221         wait_moscrdy
222
223         /* Restore PLLB setting */
224         ldr     tmp1, .saved_pllbr
225         str     tmp1, [pmc, #AT91_CKGR_PLLBR]
226
227         tst     tmp1, #(AT91_PMC_MUL &  0xff0000)
228         bne     1f
229         tst     tmp1, #(AT91_PMC_MUL & ~0xff0000)
230         beq     2f
231 1:
232         wait_pllblock
233 2:
234
235         /* Restore PLLA setting */
236         ldr     tmp1, .saved_pllar
237         str     tmp1, [pmc, #AT91_CKGR_PLLAR]
238
239         tst     tmp1, #(AT91_PMC_MUL &  0xff0000)
240         bne     3f
241         tst     tmp1, #(AT91_PMC_MUL & ~0xff0000)
242         beq     4f
243 3:
244         wait_pllalock
245 4:
246
247 #ifdef SLOWDOWN_MASTER_CLOCK
248         /*
249          * First set PRES if it was not 0,
250          * than set CSS and MDIV fields.
251          *
252          * See AT91RM9200 errata #27 and #28 for details.
253          */
254         ldr     tmp1, .saved_mckr
255         tst     tmp1, #AT91_PMC_PRES
256         beq     2f
257         and     tmp1, tmp1, #AT91_PMC_PRES
258         str     tmp1, [pmc, #AT91_PMC_MCKR]
259
260         wait_mckrdy
261 #endif
262
263         /*
264          * Restore master clock setting
265          */
266 2:      ldr     tmp1, .saved_mckr
267         str     tmp1, [pmc, #AT91_PMC_MCKR]
268
269         wait_mckrdy
270
271         /*
272          * at91rm9200 Memory controller
273          * Do nothing - self-refresh is automatically disabled.
274          */
275         cmp     memctrl, #AT91_MEMCTRL_MC
276         beq     ram_restored
277
278         /*
279          * DDRSDR Memory controller
280          */
281         cmp     memctrl, #AT91_MEMCTRL_DDRSDR
282         bne     sdr_en_restore
283         /* Restore LPR on AT91 with DDRAM */
284         ldr     tmp1, .saved_sam9_lpr
285         str     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
286
287         /* if we use the second ram controller */
288         cmp     ramc1, #0
289         ldrne   tmp2, .saved_sam9_lpr1
290         strne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
291
292         b       ram_restored
293
294         /*
295          * SDRAMC Memory controller
296          */
297 sdr_en_restore:
298         /* Restore LPR on AT91 with SDRAM */
299         ldr     tmp1, .saved_sam9_lpr
300         str     tmp1, [sdramc, #AT91_SDRAMC_LPR]
301
302 ram_restored:
303         /* Restore registers, and return */
304         ldmfd   sp!, {r4 - r12, pc}
305
306
307 .saved_mckr:
308         .word 0
309
310 .saved_pllar:
311         .word 0
312
313 .saved_pllbr:
314         .word 0
315
316 .saved_sam9_lpr:
317         .word 0
318
319 .saved_sam9_lpr1:
320         .word 0
321
322 ENTRY(at91_slow_clock_sz)
323         .word .-at91_slow_clock