blob: f8539a8bcd6cda36dca3cd7a639f198c7ed5d8cd [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-VILLARD9918cea2012-01-26 14:07:09 +010021#elif defined(CONFIG_ARCH_AT91SAM9G45)
Nicolas Ferre7dca3342010-06-21 14:59:27 +010022#include <mach/at91sam9_ddrsdr.h>
Andrew Victoreaad2db2008-09-21 21:35:18 +010023#else
24#include <mach/at91sam9_sdramc.h>
25#endif
26
27
28#ifdef CONFIG_ARCH_AT91SAM9263
29/*
30 * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
31 * handle those cases both here and in the Suspend-To-RAM support.
32 */
Andrew Victoreaad2db2008-09-21 21:35:18 +010033#warning Assuming EB1 SDRAM controller is *NOT* used
34#endif
35
36/*
37 * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
38 * clock during suspend by adjusting its prescalar and divisor.
39 * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
40 * are errata regarding adjusting the prescalar and divisor.
41 */
42#undef SLOWDOWN_MASTER_CLOCK
43
44#define MCKRDY_TIMEOUT 1000
45#define MOSCRDY_TIMEOUT 1000
46#define PLLALOCK_TIMEOUT 1000
47#define PLLBLOCK_TIMEOUT 1000
48
49
50/*
51 * Wait until master clock is ready (after switching master clock source)
52 */
53 .macro wait_mckrdy
54 mov r4, #MCKRDY_TIMEOUT
551: sub r4, r4, #1
56 cmp r4, #0
57 beq 2f
58 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
59 tst r3, #AT91_PMC_MCKRDY
60 beq 1b
612:
62 .endm
63
64/*
65 * Wait until master oscillator has stabilized.
66 */
67 .macro wait_moscrdy
68 mov r4, #MOSCRDY_TIMEOUT
691: sub r4, r4, #1
70 cmp r4, #0
71 beq 2f
72 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
73 tst r3, #AT91_PMC_MOSCS
74 beq 1b
752:
76 .endm
77
78/*
79 * Wait until PLLA has locked.
80 */
81 .macro wait_pllalock
82 mov r4, #PLLALOCK_TIMEOUT
831: sub r4, r4, #1
84 cmp r4, #0
85 beq 2f
86 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
87 tst r3, #AT91_PMC_LOCKA
88 beq 1b
892:
90 .endm
91
92/*
93 * Wait until PLLB has locked.
94 */
95 .macro wait_pllblock
96 mov r4, #PLLBLOCK_TIMEOUT
971: sub r4, r4, #1
98 cmp r4, #0
99 beq 2f
100 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
101 tst r3, #AT91_PMC_LOCKB
102 beq 1b
1032:
104 .endm
105
106 .text
107
108ENTRY(at91_slow_clock)
109 /* Save registers on stack */
110 stmfd sp!, {r0 - r12, lr}
111
112 /*
113 * Register usage:
114 * R1 = Base address of AT91_PMC
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100115 * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100116 * R3 = temporary register
117 * R4 = temporary register
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100118 * R5 = Base address of second RAM Controller or 0 if not present
Andrew Victoreaad2db2008-09-21 21:35:18 +0100119 */
120 ldr r1, .at91_va_base_pmc
121 ldr r2, .at91_va_base_sdramc
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100122 ldr r5, .at91_va_base_ramc1
Andrew Victoreaad2db2008-09-21 21:35:18 +0100123
124 /* Drain write buffer */
Nicolas Ferrea2a571b2010-10-22 18:55:39 +0200125 mov r0, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +0100126 mcr p15, 0, r0, c7, c10, 4
127
128#ifdef CONFIG_ARCH_AT91RM9200
129 /* Put SDRAM in self-refresh mode */
130 mov r3, #1
131 str r3, [r2, #AT91_SDRAMC_SRR]
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100132#elif defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100133
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100134 /* prepare for DDRAM self-refresh mode */
135 ldr r3, [r2, #AT91_DDRSDRC_LPR]
136 str r3, .saved_sam9_lpr
137 bic r3, #AT91_DDRSDRC_LPCB
138 orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
139
140 /* figure out if we use the second ram controller */
141 cmp r5, #0
142 ldrne r4, [r5, #AT91_DDRSDRC_LPR]
143 strne r4, .saved_sam9_lpr1
144 bicne r4, #AT91_DDRSDRC_LPCB
145 orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH
146
147 /* Enable DDRAM self-refresh mode */
148 str r3, [r2, #AT91_DDRSDRC_LPR]
149 strne r4, [r5, #AT91_DDRSDRC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100150#else
151 /* Enable SDRAM self-refresh mode */
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100152 ldr r3, [r2, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100153 str r3, .saved_sam9_lpr
154
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100155 bic r3, #AT91_SDRAMC_LPCB
156 orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
157 str r3, [r2, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100158#endif
159
160 /* Save Master clock setting */
161 ldr r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
162 str r3, .saved_mckr
163
164 /*
165 * Set the Master clock source to slow clock
166 */
167 bic r3, r3, #AT91_PMC_CSS
168 str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
169
170 wait_mckrdy
171
172#ifdef SLOWDOWN_MASTER_CLOCK
173 /*
174 * Set the Master Clock PRES and MDIV fields.
175 *
176 * See AT91RM9200 errata #27 and #28 for details.
177 */
178 mov r3, #0
179 str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
180
181 wait_mckrdy
182#endif
183
184 /* Save PLLA setting and disable it */
185 ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
186 str r3, .saved_pllar
187
188 mov r3, #AT91_PMC_PLLCOUNT
189 orr r3, r3, #(1 << 29) /* bit 29 always set */
190 str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
191
Andrew Victoreaad2db2008-09-21 21:35:18 +0100192 /* Save PLLB setting and disable it */
193 ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
194 str r3, .saved_pllbr
195
196 mov r3, #AT91_PMC_PLLCOUNT
197 str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
198
Andrew Victoreaad2db2008-09-21 21:35:18 +0100199 /* Turn off the main oscillator */
200 ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
201 bic r3, r3, #AT91_PMC_MOSCEN
202 str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
203
204 /* Wait for interrupt */
205 mcr p15, 0, r0, c7, c0, 4
206
207 /* Turn on the main oscillator */
208 ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
209 orr r3, r3, #AT91_PMC_MOSCEN
210 str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
211
212 wait_moscrdy
213
214 /* Restore PLLB setting */
215 ldr r3, .saved_pllbr
216 str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
217
Anders Larsen9823f1a2010-04-08 11:48:16 +0100218 tst r3, #(AT91_PMC_MUL & 0xff0000)
219 bne 1f
220 tst r3, #(AT91_PMC_MUL & ~0xff0000)
221 beq 2f
2221:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100223 wait_pllblock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002242:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100225
226 /* Restore PLLA setting */
227 ldr r3, .saved_pllar
228 str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
229
Anders Larsen9823f1a2010-04-08 11:48:16 +0100230 tst r3, #(AT91_PMC_MUL & 0xff0000)
231 bne 3f
232 tst r3, #(AT91_PMC_MUL & ~0xff0000)
233 beq 4f
2343:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100235 wait_pllalock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002364:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100237
238#ifdef SLOWDOWN_MASTER_CLOCK
239 /*
240 * First set PRES if it was not 0,
241 * than set CSS and MDIV fields.
242 *
243 * See AT91RM9200 errata #27 and #28 for details.
244 */
245 ldr r3, .saved_mckr
246 tst r3, #AT91_PMC_PRES
247 beq 2f
248 and r3, r3, #AT91_PMC_PRES
249 str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
250
251 wait_mckrdy
252#endif
253
254 /*
255 * Restore master clock setting
256 */
2572: ldr r3, .saved_mckr
258 str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
259
260 wait_mckrdy
261
262#ifdef CONFIG_ARCH_AT91RM9200
263 /* Do nothing - self-refresh is automatically disabled. */
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100264#elif defined(CONFIG_ARCH_AT91SAM9G45)
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100265 /* Restore LPR on AT91 with DDRAM */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100266 ldr r3, .saved_sam9_lpr
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100267 str r3, [r2, #AT91_DDRSDRC_LPR]
268
269 /* if we use the second ram controller */
270 cmp r5, #0
271 ldrne r4, .saved_sam9_lpr1
272 strne r4, [r5, #AT91_DDRSDRC_LPR]
273
Andrew Victoreaad2db2008-09-21 21:35:18 +0100274#else
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100275 /* Restore LPR on AT91 with SDRAM */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100276 ldr r3, .saved_sam9_lpr
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100277 str r3, [r2, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100278#endif
279
280 /* Restore registers, and return */
281 ldmfd sp!, {r0 - r12, pc}
282
283
284.saved_mckr:
285 .word 0
286
287.saved_pllar:
288 .word 0
289
290.saved_pllbr:
291 .word 0
292
293.saved_sam9_lpr:
294 .word 0
295
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100296.saved_sam9_lpr1:
297 .word 0
298
Andrew Victoreaad2db2008-09-21 21:35:18 +0100299.at91_va_base_pmc:
300 .word AT91_VA_BASE_SYS + AT91_PMC
301
302#ifdef CONFIG_ARCH_AT91RM9200
303.at91_va_base_sdramc:
304 .word AT91_VA_BASE_SYS
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100305#elif defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100306.at91_va_base_sdramc:
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100307 .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
Andrew Victoreaad2db2008-09-21 21:35:18 +0100308#else
309.at91_va_base_sdramc:
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100310 .word AT91_VA_BASE_SYS + AT91_SDRAMC0
311#endif
312
313.at91_va_base_ramc1:
314#if defined(CONFIG_ARCH_AT91SAM9G45)
315 .word AT91_VA_BASE_SYS + AT91_DDRSDRC1
316#else
317 .word 0
Andrew Victoreaad2db2008-09-21 21:35:18 +0100318#endif
319
320ENTRY(at91_slow_clock_sz)
321 .word .-at91_slow_clock