blob: 92dfb8461392a66541a1370de2c7dce11c03a039 [file] [log] [blame]
Andrew Victoreaad2db2008-09-21 21:35:18 +01001/*
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
Nicolas Ferre7dca3342010-06-21 14:59:27 +010019#if defined(CONFIG_ARCH_AT91RM9200)
Andrew Victoreaad2db2008-09-21 21:35:18 +010020#include <mach/at91rm9200_mc.h>
Jean-Christophe PLAGNIOL-VILLARD17d2cc22011-11-18 00:36:21 +080021#elif defined(CONFIG_ARCH_AT91CAP9) \
22 || defined(CONFIG_ARCH_AT91SAM9G45)
Nicolas Ferre7dca3342010-06-21 14:59:27 +010023#include <mach/at91sam9_ddrsdr.h>
Andrew Victoreaad2db2008-09-21 21:35:18 +010024#else
25#include <mach/at91sam9_sdramc.h>
26#endif
27
28
29#ifdef CONFIG_ARCH_AT91SAM9263
30/*
31 * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
32 * handle those cases both here and in the Suspend-To-RAM support.
33 */
Andrew Victoreaad2db2008-09-21 21:35:18 +010034#warning Assuming EB1 SDRAM controller is *NOT* used
35#endif
36
37/*
38 * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
39 * clock during suspend by adjusting its prescalar and divisor.
40 * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
41 * are errata regarding adjusting the prescalar and divisor.
42 */
43#undef SLOWDOWN_MASTER_CLOCK
44
45#define MCKRDY_TIMEOUT 1000
46#define MOSCRDY_TIMEOUT 1000
47#define PLLALOCK_TIMEOUT 1000
48#define PLLBLOCK_TIMEOUT 1000
49
50
51/*
52 * Wait until master clock is ready (after switching master clock source)
53 */
54 .macro wait_mckrdy
55 mov r4, #MCKRDY_TIMEOUT
561: sub r4, r4, #1
57 cmp r4, #0
58 beq 2f
59 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
60 tst r3, #AT91_PMC_MCKRDY
61 beq 1b
622:
63 .endm
64
65/*
66 * Wait until master oscillator has stabilized.
67 */
68 .macro wait_moscrdy
69 mov r4, #MOSCRDY_TIMEOUT
701: sub r4, r4, #1
71 cmp r4, #0
72 beq 2f
73 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
74 tst r3, #AT91_PMC_MOSCS
75 beq 1b
762:
77 .endm
78
79/*
80 * Wait until PLLA has locked.
81 */
82 .macro wait_pllalock
83 mov r4, #PLLALOCK_TIMEOUT
841: sub r4, r4, #1
85 cmp r4, #0
86 beq 2f
87 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
88 tst r3, #AT91_PMC_LOCKA
89 beq 1b
902:
91 .endm
92
93/*
94 * Wait until PLLB has locked.
95 */
96 .macro wait_pllblock
97 mov r4, #PLLBLOCK_TIMEOUT
981: sub r4, r4, #1
99 cmp r4, #0
100 beq 2f
101 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
102 tst r3, #AT91_PMC_LOCKB
103 beq 1b
1042:
105 .endm
106
107 .text
108
109ENTRY(at91_slow_clock)
110 /* Save registers on stack */
111 stmfd sp!, {r0 - r12, lr}
112
113 /*
114 * Register usage:
115 * R1 = Base address of AT91_PMC
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100116 * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100117 * R3 = temporary register
118 * R4 = temporary register
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100119 * R5 = Base address of second RAM Controller or 0 if not present
Andrew Victoreaad2db2008-09-21 21:35:18 +0100120 */
121 ldr r1, .at91_va_base_pmc
122 ldr r2, .at91_va_base_sdramc
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100123 ldr r5, .at91_va_base_ramc1
Andrew Victoreaad2db2008-09-21 21:35:18 +0100124
125 /* Drain write buffer */
Nicolas Ferrea2a571b2010-10-22 18:55:39 +0200126 mov r0, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +0100127 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]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100133#elif defined(CONFIG_ARCH_AT91CAP9) \
134 || defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100135
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100136 /* 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]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100152#else
153 /* Enable SDRAM self-refresh mode */
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100154 ldr r3, [r2, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100155 str r3, .saved_sam9_lpr
156
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100157 bic r3, #AT91_SDRAMC_LPCB
158 orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
159 str r3, [r2, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100160#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
Andrew Victoreaad2db2008-09-21 21:35:18 +0100194 /* 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
Andrew Victoreaad2db2008-09-21 21:35:18 +0100201 /* 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
Anders Larsen9823f1a2010-04-08 11:48:16 +0100220 tst r3, #(AT91_PMC_MUL & 0xff0000)
221 bne 1f
222 tst r3, #(AT91_PMC_MUL & ~0xff0000)
223 beq 2f
2241:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100225 wait_pllblock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002262:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100227
228 /* Restore PLLA setting */
229 ldr r3, .saved_pllar
230 str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
231
Anders Larsen9823f1a2010-04-08 11:48:16 +0100232 tst r3, #(AT91_PMC_MUL & 0xff0000)
233 bne 3f
234 tst r3, #(AT91_PMC_MUL & ~0xff0000)
235 beq 4f
2363:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100237 wait_pllalock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002384:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100239
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 */
2592: 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. */
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100266#elif defined(CONFIG_ARCH_AT91CAP9) \
267 || defined(CONFIG_ARCH_AT91SAM9G45)
268 /* Restore LPR on AT91 with DDRAM */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100269 ldr r3, .saved_sam9_lpr
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100270 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
Andrew Victoreaad2db2008-09-21 21:35:18 +0100277#else
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100278 /* Restore LPR on AT91 with SDRAM */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100279 ldr r3, .saved_sam9_lpr
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100280 str r3, [r2, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100281#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
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100299.saved_sam9_lpr1:
300 .word 0
301
Andrew Victoreaad2db2008-09-21 21:35:18 +0100302.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
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100308#elif defined(CONFIG_ARCH_AT91CAP9) \
309 || defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100310.at91_va_base_sdramc:
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100311 .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
Andrew Victoreaad2db2008-09-21 21:35:18 +0100312#else
313.at91_va_base_sdramc:
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100314 .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
Andrew Victoreaad2db2008-09-21 21:35:18 +0100322#endif
323
324ENTRY(at91_slow_clock_sz)
325 .word .-at91_slow_clock