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