blob: a2835a81bc846d4086005add6961c674987b0dbe [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>
Jean-Christophe PLAGNIOL-VILLARDf363c402012-02-13 12:58:53 +080018#include <mach/at91_ramc.h>
Andrew Victoreaad2db2008-09-21 21:35:18 +010019
20
21#ifdef CONFIG_ARCH_AT91SAM9263
22/*
23 * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
24 * handle those cases both here and in the Suspend-To-RAM support.
25 */
Andrew Victoreaad2db2008-09-21 21:35:18 +010026#warning Assuming EB1 SDRAM controller is *NOT* used
27#endif
28
29/*
30 * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
31 * clock during suspend by adjusting its prescalar and divisor.
32 * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
33 * are errata regarding adjusting the prescalar and divisor.
34 */
35#undef SLOWDOWN_MASTER_CLOCK
36
37#define MCKRDY_TIMEOUT 1000
38#define MOSCRDY_TIMEOUT 1000
39#define PLLALOCK_TIMEOUT 1000
40#define PLLBLOCK_TIMEOUT 1000
41
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +010042pmc .req r0
43sdramc .req r1
44ramc1 .req r2
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010045tmp1 .req r3
46tmp2 .req r4
Andrew Victoreaad2db2008-09-21 21:35:18 +010047
48/*
49 * Wait until master clock is ready (after switching master clock source)
50 */
51 .macro wait_mckrdy
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010052 mov tmp2, #MCKRDY_TIMEOUT
531: sub tmp2, tmp2, #1
54 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010055 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010056 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
57 tst tmp1, #AT91_PMC_MCKRDY
Andrew Victoreaad2db2008-09-21 21:35:18 +010058 beq 1b
592:
60 .endm
61
62/*
63 * Wait until master oscillator has stabilized.
64 */
65 .macro wait_moscrdy
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010066 mov tmp2, #MOSCRDY_TIMEOUT
671: sub tmp2, tmp2, #1
68 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010069 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010070 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
71 tst tmp1, #AT91_PMC_MOSCS
Andrew Victoreaad2db2008-09-21 21:35:18 +010072 beq 1b
732:
74 .endm
75
76/*
77 * Wait until PLLA has locked.
78 */
79 .macro wait_pllalock
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010080 mov tmp2, #PLLALOCK_TIMEOUT
811: sub tmp2, tmp2, #1
82 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010083 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010084 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
85 tst tmp1, #AT91_PMC_LOCKA
Andrew Victoreaad2db2008-09-21 21:35:18 +010086 beq 1b
872:
88 .endm
89
90/*
91 * Wait until PLLB has locked.
92 */
93 .macro wait_pllblock
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010094 mov tmp2, #PLLBLOCK_TIMEOUT
951: sub tmp2, tmp2, #1
96 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010097 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010098 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
99 tst tmp1, #AT91_PMC_LOCKB
Andrew Victoreaad2db2008-09-21 21:35:18 +0100100 beq 1b
1012:
102 .endm
103
104 .text
105
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100106/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, void __iomem *ramc1) */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100107ENTRY(at91_slow_clock)
108 /* Save registers on stack */
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100109 stmfd sp!, {r3 - r12, lr}
Andrew Victoreaad2db2008-09-21 21:35:18 +0100110
111 /*
112 * Register usage:
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100113 * R0 = Base address of AT91_PMC
114 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
115 * R2 = Base address of second RAM Controller or 0 if not present
Andrew Victoreaad2db2008-09-21 21:35:18 +0100116 * R3 = temporary register
117 * R4 = temporary register
118 */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100119
120 /* Drain write buffer */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100121 mov tmp1, #0
122 mcr p15, 0, tmp1, c7, c10, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100123
124#ifdef CONFIG_ARCH_AT91RM9200
125 /* Put SDRAM in self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100126 mov tmp1, #1
Jean-Christophe PLAGNIOL-VILLARD1a269ad2011-11-16 02:58:31 +0800127 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100128#elif defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100129
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100130 /* prepare for DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100131 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
132 str tmp1, .saved_sam9_lpr
133 bic tmp1, #AT91_DDRSDRC_LPCB
134 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100135
136 /* figure out if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100137 cmp ramc1, #0
138 ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
139 strne tmp2, .saved_sam9_lpr1
140 bicne tmp2, #AT91_DDRSDRC_LPCB
141 orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100142
143 /* Enable DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100144 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
145 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100146#else
147 /* Enable SDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100148 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
149 str tmp1, .saved_sam9_lpr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100150
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100151 bic tmp1, #AT91_SDRAMC_LPCB
152 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
153 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100154#endif
155
156 /* Save Master clock setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100157 ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
158 str tmp1, .saved_mckr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100159
160 /*
161 * Set the Master clock source to slow clock
162 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100163 bic tmp1, tmp1, #AT91_PMC_CSS
164 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100165
166 wait_mckrdy
167
168#ifdef SLOWDOWN_MASTER_CLOCK
169 /*
170 * Set the Master Clock PRES and MDIV fields.
171 *
172 * See AT91RM9200 errata #27 and #28 for details.
173 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100174 mov tmp1, #0
175 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100176
177 wait_mckrdy
178#endif
179
180 /* Save PLLA setting and disable it */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100181 ldr tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
182 str tmp1, .saved_pllar
Andrew Victoreaad2db2008-09-21 21:35:18 +0100183
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100184 mov tmp1, #AT91_PMC_PLLCOUNT
185 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
186 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100187
Andrew Victoreaad2db2008-09-21 21:35:18 +0100188 /* Save PLLB setting and disable it */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100189 ldr tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
190 str tmp1, .saved_pllbr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100191
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100192 mov tmp1, #AT91_PMC_PLLCOUNT
193 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100194
Andrew Victoreaad2db2008-09-21 21:35:18 +0100195 /* Turn off the main oscillator */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100196 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
197 bic tmp1, tmp1, #AT91_PMC_MOSCEN
198 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100199
200 /* Wait for interrupt */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100201 mcr p15, 0, tmp1, c7, c0, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100202
203 /* Turn on the main oscillator */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100204 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
205 orr tmp1, tmp1, #AT91_PMC_MOSCEN
206 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100207
208 wait_moscrdy
209
210 /* Restore PLLB setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100211 ldr tmp1, .saved_pllbr
212 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100213
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100214 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100215 bne 1f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100216 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100217 beq 2f
2181:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100219 wait_pllblock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002202:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100221
222 /* Restore PLLA setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100223 ldr tmp1, .saved_pllar
224 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100225
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100226 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100227 bne 3f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100228 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100229 beq 4f
2303:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100231 wait_pllalock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002324:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100233
234#ifdef SLOWDOWN_MASTER_CLOCK
235 /*
236 * First set PRES if it was not 0,
237 * than set CSS and MDIV fields.
238 *
239 * See AT91RM9200 errata #27 and #28 for details.
240 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100241 ldr tmp1, .saved_mckr
242 tst tmp1, #AT91_PMC_PRES
Andrew Victoreaad2db2008-09-21 21:35:18 +0100243 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100244 and tmp1, tmp1, #AT91_PMC_PRES
245 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100246
247 wait_mckrdy
248#endif
249
250 /*
251 * Restore master clock setting
252 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +01002532: ldr tmp1, .saved_mckr
254 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100255
256 wait_mckrdy
257
258#ifdef CONFIG_ARCH_AT91RM9200
259 /* Do nothing - self-refresh is automatically disabled. */
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100260#elif defined(CONFIG_ARCH_AT91SAM9G45)
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100261 /* Restore LPR on AT91 with DDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100262 ldr tmp1, .saved_sam9_lpr
263 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100264
265 /* if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100266 cmp ramc1, #0
267 ldrne tmp2, .saved_sam9_lpr1
268 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100269
Andrew Victoreaad2db2008-09-21 21:35:18 +0100270#else
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100271 /* Restore LPR on AT91 with SDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100272 ldr tmp1, .saved_sam9_lpr
273 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100274#endif
275
276 /* Restore registers, and return */
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100277 ldmfd sp!, {r3 - r12, pc}
Andrew Victoreaad2db2008-09-21 21:35:18 +0100278
279
280.saved_mckr:
281 .word 0
282
283.saved_pllar:
284 .word 0
285
286.saved_pllbr:
287 .word 0
288
289.saved_sam9_lpr:
290 .word 0
291
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100292.saved_sam9_lpr1:
293 .word 0
294
Andrew Victoreaad2db2008-09-21 21:35:18 +0100295ENTRY(at91_slow_clock_sz)
296 .word .-at91_slow_clock