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
CommitLineData
eaad2db0
AV
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
7dca3343 19#if defined(CONFIG_ARCH_AT91RM9200)
eaad2db0
AV
20#include <mach/at91rm9200_mc.h>
21#elif defined(CONFIG_ARCH_AT91CAP9)
22#include <mach/at91cap9_ddrsdr.h>
7dca3343
NF
23#elif defined(CONFIG_ARCH_AT91SAM9G45)
24#include <mach/at91sam9_ddrsdr.h>
eaad2db0
AV
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 */
eaad2db0
AV
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
571: 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
632:
64 .endm
65
66/*
67 * Wait until master oscillator has stabilized.
68 */
69 .macro wait_moscrdy
70 mov r4, #MOSCRDY_TIMEOUT
711: 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
772:
78 .endm
79
80/*
81 * Wait until PLLA has locked.
82 */
83 .macro wait_pllalock
84 mov r4, #PLLALOCK_TIMEOUT
851: 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
912:
92 .endm
93
94/*
95 * Wait until PLLB has locked.
96 */
97 .macro wait_pllblock
98 mov r4, #PLLBLOCK_TIMEOUT
991: 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
1052:
106 .endm
107
108 .text
109
110ENTRY(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
7dca3343 117 * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
eaad2db0
AV
118 * R3 = temporary register
119 * R4 = temporary register
7dca3343 120 * R5 = Base address of second RAM Controller or 0 if not present
eaad2db0
AV
121 */
122 ldr r1, .at91_va_base_pmc
123 ldr r2, .at91_va_base_sdramc
7dca3343 124 ldr r5, .at91_va_base_ramc1
eaad2db0
AV
125
126 /* Drain write buffer */
a2a571b7 127 mov r0, #0
eaad2db0
AV
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]
7dca3343
NF
134#elif defined(CONFIG_ARCH_AT91CAP9) \
135 || defined(CONFIG_ARCH_AT91SAM9G45)
eaad2db0 136
7dca3343
NF
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]
eaad2db0
AV
153#else
154 /* Enable SDRAM self-refresh mode */
7dca3343 155 ldr r3, [r2, #AT91_SDRAMC_LPR]
eaad2db0
AV
156 str r3, .saved_sam9_lpr
157
7dca3343
NF
158 bic r3, #AT91_SDRAMC_LPCB
159 orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
160 str r3, [r2, #AT91_SDRAMC_LPR]
eaad2db0
AV
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
eaad2db0
AV
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
eaad2db0
AV
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
9823f1a8
AL
221 tst r3, #(AT91_PMC_MUL & 0xff0000)
222 bne 1f
223 tst r3, #(AT91_PMC_MUL & ~0xff0000)
224 beq 2f
2251:
eaad2db0 226 wait_pllblock
9823f1a8 2272:
eaad2db0
AV
228
229 /* Restore PLLA setting */
230 ldr r3, .saved_pllar
231 str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
232
9823f1a8
AL
233 tst r3, #(AT91_PMC_MUL & 0xff0000)
234 bne 3f
235 tst r3, #(AT91_PMC_MUL & ~0xff0000)
236 beq 4f
2373:
eaad2db0 238 wait_pllalock
9823f1a8 2394:
eaad2db0
AV
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 */
2602: 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. */
7dca3343
NF
267#elif defined(CONFIG_ARCH_AT91CAP9) \
268 || defined(CONFIG_ARCH_AT91SAM9G45)
269 /* Restore LPR on AT91 with DDRAM */
eaad2db0 270 ldr r3, .saved_sam9_lpr
7dca3343
NF
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
eaad2db0 278#else
7dca3343 279 /* Restore LPR on AT91 with SDRAM */
eaad2db0 280 ldr r3, .saved_sam9_lpr
7dca3343 281 str r3, [r2, #AT91_SDRAMC_LPR]
eaad2db0
AV
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
7dca3343
NF
300.saved_sam9_lpr1:
301 .word 0
302
eaad2db0
AV
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
7dca3343
NF
309#elif defined(CONFIG_ARCH_AT91CAP9) \
310 || defined(CONFIG_ARCH_AT91SAM9G45)
eaad2db0 311.at91_va_base_sdramc:
7dca3343 312 .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
eaad2db0
AV
313#else
314.at91_va_base_sdramc:
7dca3343
NF
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
eaad2db0
AV
323#endif
324
325ENTRY(at91_slow_clock_sz)
326 .word .-at91_slow_clock