blob: e31a5f222d8625574e5e1ca1dcb4b797010a35fd [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-VILLARD8ff12ad32012-02-22 17:50:54 +010049pmc .req r0
50sdramc .req r1
51ramc1 .req r2
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010052tmp1 .req r3
53tmp2 .req r4
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
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100113/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, void __iomem *ramc1) */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100114ENTRY(at91_slow_clock)
115 /* Save registers on stack */
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100116 stmfd sp!, {r3 - r12, lr}
Andrew Victoreaad2db2008-09-21 21:35:18 +0100117
118 /*
119 * Register usage:
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100120 * R0 = Base address of AT91_PMC
121 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
122 * R2 = Base address of second RAM Controller or 0 if not present
Andrew Victoreaad2db2008-09-21 21:35:18 +0100123 * R3 = temporary register
124 * R4 = temporary register
125 */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100126
127 /* Drain write buffer */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100128 mov tmp1, #0
129 mcr p15, 0, tmp1, c7, c10, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100130
131#ifdef CONFIG_ARCH_AT91RM9200
132 /* Put SDRAM in self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100133 mov tmp1, #1
134 str tmp1, [sdramc, #AT91_SDRAMC_SRR]
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100135#elif defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100136
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100137 /* prepare for DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100138 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
139 str tmp1, .saved_sam9_lpr
140 bic tmp1, #AT91_DDRSDRC_LPCB
141 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100142
143 /* figure out if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100144 cmp ramc1, #0
145 ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
146 strne tmp2, .saved_sam9_lpr1
147 bicne tmp2, #AT91_DDRSDRC_LPCB
148 orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100149
150 /* Enable DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100151 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
152 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100153#else
154 /* Enable SDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100155 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
156 str tmp1, .saved_sam9_lpr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100157
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100158 bic tmp1, #AT91_SDRAMC_LPCB
159 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
160 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100161#endif
162
163 /* Save Master clock setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100164 ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
165 str tmp1, .saved_mckr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100166
167 /*
168 * Set the Master clock source to slow clock
169 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100170 bic tmp1, tmp1, #AT91_PMC_CSS
171 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100172
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 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100181 mov tmp1, #0
182 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100183
184 wait_mckrdy
185#endif
186
187 /* Save PLLA setting and disable it */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100188 ldr tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
189 str tmp1, .saved_pllar
Andrew Victoreaad2db2008-09-21 21:35:18 +0100190
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100191 mov tmp1, #AT91_PMC_PLLCOUNT
192 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
193 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100194
Andrew Victoreaad2db2008-09-21 21:35:18 +0100195 /* Save PLLB setting and disable it */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100196 ldr tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
197 str tmp1, .saved_pllbr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100198
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100199 mov tmp1, #AT91_PMC_PLLCOUNT
200 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100201
Andrew Victoreaad2db2008-09-21 21:35:18 +0100202 /* Turn off the main oscillator */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100203 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
204 bic tmp1, tmp1, #AT91_PMC_MOSCEN
205 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100206
207 /* Wait for interrupt */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100208 mcr p15, 0, tmp1, c7, c0, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100209
210 /* Turn on the main oscillator */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100211 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
212 orr tmp1, tmp1, #AT91_PMC_MOSCEN
213 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100214
215 wait_moscrdy
216
217 /* Restore PLLB setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100218 ldr tmp1, .saved_pllbr
219 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100220
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100221 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100222 bne 1f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100223 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100224 beq 2f
2251:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100226 wait_pllblock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002272:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100228
229 /* Restore PLLA setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100230 ldr tmp1, .saved_pllar
231 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100232
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100233 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100234 bne 3f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100235 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100236 beq 4f
2373:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100238 wait_pllalock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002394:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100240
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 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100248 ldr tmp1, .saved_mckr
249 tst tmp1, #AT91_PMC_PRES
Andrew Victoreaad2db2008-09-21 21:35:18 +0100250 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100251 and tmp1, tmp1, #AT91_PMC_PRES
252 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100253
254 wait_mckrdy
255#endif
256
257 /*
258 * Restore master clock setting
259 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +01002602: ldr tmp1, .saved_mckr
261 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100262
263 wait_mckrdy
264
265#ifdef CONFIG_ARCH_AT91RM9200
266 /* Do nothing - self-refresh is automatically disabled. */
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100267#elif defined(CONFIG_ARCH_AT91SAM9G45)
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100268 /* Restore LPR on AT91 with DDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100269 ldr tmp1, .saved_sam9_lpr
270 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100271
272 /* if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100273 cmp ramc1, #0
274 ldrne tmp2, .saved_sam9_lpr1
275 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100276
Andrew Victoreaad2db2008-09-21 21:35:18 +0100277#else
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100278 /* Restore LPR on AT91 with SDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100279 ldr tmp1, .saved_sam9_lpr
280 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100281#endif
282
283 /* Restore registers, and return */
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100284 ldmfd sp!, {r3 - r12, pc}
Andrew Victoreaad2db2008-09-21 21:35:18 +0100285
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 +0100302ENTRY(at91_slow_clock_sz)
303 .word .-at91_slow_clock