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