blob: c802d309582fc757df725b29a43755d62e147c03 [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
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010049pmc .req r1
50sdramc .req r2
51tmp1 .req r3
52tmp2 .req r4
53ramc1 .req r5
Andrew Victoreaad2db2008-09-21 21:35:18 +010054
55/*
56 * Wait until master clock is ready (after switching master clock source)
57 */
58 .macro wait_mckrdy
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010059 mov tmp2, #MCKRDY_TIMEOUT
601: sub tmp2, tmp2, #1
61 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010062 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010063 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
64 tst tmp1, #AT91_PMC_MCKRDY
Andrew Victoreaad2db2008-09-21 21:35:18 +010065 beq 1b
662:
67 .endm
68
69/*
70 * Wait until master oscillator has stabilized.
71 */
72 .macro wait_moscrdy
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010073 mov tmp2, #MOSCRDY_TIMEOUT
741: sub tmp2, tmp2, #1
75 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010076 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010077 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
78 tst tmp1, #AT91_PMC_MOSCS
Andrew Victoreaad2db2008-09-21 21:35:18 +010079 beq 1b
802:
81 .endm
82
83/*
84 * Wait until PLLA has locked.
85 */
86 .macro wait_pllalock
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010087 mov tmp2, #PLLALOCK_TIMEOUT
881: sub tmp2, tmp2, #1
89 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010090 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010091 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
92 tst tmp1, #AT91_PMC_LOCKA
Andrew Victoreaad2db2008-09-21 21:35:18 +010093 beq 1b
942:
95 .endm
96
97/*
98 * Wait until PLLB has locked.
99 */
100 .macro wait_pllblock
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100101 mov tmp2, #PLLBLOCK_TIMEOUT
1021: sub tmp2, tmp2, #1
103 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +0100104 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100105 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
106 tst tmp1, #AT91_PMC_LOCKB
Andrew Victoreaad2db2008-09-21 21:35:18 +0100107 beq 1b
1082:
109 .endm
110
111 .text
112
113ENTRY(at91_slow_clock)
114 /* Save registers on stack */
115 stmfd sp!, {r0 - r12, lr}
116
117 /*
118 * Register usage:
119 * R1 = Base address of AT91_PMC
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100120 * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100121 * R3 = temporary register
122 * R4 = temporary register
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100123 * R5 = Base address of second RAM Controller or 0 if not present
Andrew Victoreaad2db2008-09-21 21:35:18 +0100124 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100125 ldr pmc, .at91_va_base_pmc
126 ldr sdramc, .at91_va_base_sdramc
127 ldr ramc1, .at91_va_base_ramc1
Andrew Victoreaad2db2008-09-21 21:35:18 +0100128
129 /* Drain write buffer */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100130 mov tmp1, #0
131 mcr p15, 0, tmp1, c7, c10, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100132
133#ifdef CONFIG_ARCH_AT91RM9200
134 /* Put SDRAM in self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100135 mov tmp1, #1
136 str tmp1, [sdramc, #AT91_SDRAMC_SRR]
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100137#elif defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100138
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100139 /* prepare for DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100140 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
141 str tmp1, .saved_sam9_lpr
142 bic tmp1, #AT91_DDRSDRC_LPCB
143 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100144
145 /* figure out if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100146 cmp ramc1, #0
147 ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
148 strne tmp2, .saved_sam9_lpr1
149 bicne tmp2, #AT91_DDRSDRC_LPCB
150 orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100151
152 /* Enable DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100153 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
154 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100155#else
156 /* Enable SDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100157 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
158 str tmp1, .saved_sam9_lpr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100159
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100160 bic tmp1, #AT91_SDRAMC_LPCB
161 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
162 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100163#endif
164
165 /* Save Master clock setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100166 ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
167 str tmp1, .saved_mckr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100168
169 /*
170 * Set the Master clock source to slow clock
171 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100172 bic tmp1, tmp1, #AT91_PMC_CSS
173 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100174
175 wait_mckrdy
176
177#ifdef SLOWDOWN_MASTER_CLOCK
178 /*
179 * Set the Master Clock PRES and MDIV fields.
180 *
181 * See AT91RM9200 errata #27 and #28 for details.
182 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100183 mov tmp1, #0
184 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100185
186 wait_mckrdy
187#endif
188
189 /* Save PLLA setting and disable it */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100190 ldr tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
191 str tmp1, .saved_pllar
Andrew Victoreaad2db2008-09-21 21:35:18 +0100192
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100193 mov tmp1, #AT91_PMC_PLLCOUNT
194 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
195 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100196
Andrew Victoreaad2db2008-09-21 21:35:18 +0100197 /* Save PLLB setting and disable it */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100198 ldr tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
199 str tmp1, .saved_pllbr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100200
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100201 mov tmp1, #AT91_PMC_PLLCOUNT
202 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100203
Andrew Victoreaad2db2008-09-21 21:35:18 +0100204 /* Turn off the main oscillator */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100205 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
206 bic tmp1, tmp1, #AT91_PMC_MOSCEN
207 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100208
209 /* Wait for interrupt */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100210 mcr p15, 0, tmp1, c7, c0, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100211
212 /* Turn on the main oscillator */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100213 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
214 orr tmp1, tmp1, #AT91_PMC_MOSCEN
215 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100216
217 wait_moscrdy
218
219 /* Restore PLLB setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100220 ldr tmp1, .saved_pllbr
221 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100222
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100223 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100224 bne 1f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100225 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100226 beq 2f
2271:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100228 wait_pllblock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002292:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100230
231 /* Restore PLLA setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100232 ldr tmp1, .saved_pllar
233 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100234
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100235 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100236 bne 3f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100237 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100238 beq 4f
2393:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100240 wait_pllalock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002414:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100242
243#ifdef SLOWDOWN_MASTER_CLOCK
244 /*
245 * First set PRES if it was not 0,
246 * than set CSS and MDIV fields.
247 *
248 * See AT91RM9200 errata #27 and #28 for details.
249 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100250 ldr tmp1, .saved_mckr
251 tst tmp1, #AT91_PMC_PRES
Andrew Victoreaad2db2008-09-21 21:35:18 +0100252 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100253 and tmp1, tmp1, #AT91_PMC_PRES
254 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100255
256 wait_mckrdy
257#endif
258
259 /*
260 * Restore master clock setting
261 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +01002622: ldr tmp1, .saved_mckr
263 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100264
265 wait_mckrdy
266
267#ifdef CONFIG_ARCH_AT91RM9200
268 /* Do nothing - self-refresh is automatically disabled. */
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100269#elif defined(CONFIG_ARCH_AT91SAM9G45)
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100270 /* Restore LPR on AT91 with DDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100271 ldr tmp1, .saved_sam9_lpr
272 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100273
274 /* if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100275 cmp ramc1, #0
276 ldrne tmp2, .saved_sam9_lpr1
277 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100278
Andrew Victoreaad2db2008-09-21 21:35:18 +0100279#else
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100280 /* Restore LPR on AT91 with SDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100281 ldr tmp1, .saved_sam9_lpr
282 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100283#endif
284
285 /* Restore registers, and return */
286 ldmfd sp!, {r0 - r12, pc}
287
288
289.saved_mckr:
290 .word 0
291
292.saved_pllar:
293 .word 0
294
295.saved_pllbr:
296 .word 0
297
298.saved_sam9_lpr:
299 .word 0
300
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100301.saved_sam9_lpr1:
302 .word 0
303
Andrew Victoreaad2db2008-09-21 21:35:18 +0100304.at91_va_base_pmc:
305 .word AT91_VA_BASE_SYS + AT91_PMC
306
307#ifdef CONFIG_ARCH_AT91RM9200
308.at91_va_base_sdramc:
309 .word AT91_VA_BASE_SYS
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100310#elif defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100311.at91_va_base_sdramc:
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100312 .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
Andrew Victoreaad2db2008-09-21 21:35:18 +0100313#else
314.at91_va_base_sdramc:
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100315 .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
Andrew Victoreaad2db2008-09-21 21:35:18 +0100323#endif
324
325ENTRY(at91_slow_clock_sz)
326 .word .-at91_slow_clock