blob: aee0b2c9ff4572e2bd9f78a37ff22b3da70453e2 [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-VILLARD1a269ad2011-11-16 02:58:31 +080021#include <mach/at91rm9200_sdramc.h>
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +010022#elif 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
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +010050pmc .req r0
51sdramc .req r1
52ramc1 .req r2
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010053tmp1 .req r3
54tmp2 .req r4
Andrew Victoreaad2db2008-09-21 21:35:18 +010055
56/*
57 * Wait until master clock is ready (after switching master clock source)
58 */
59 .macro wait_mckrdy
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010060 mov tmp2, #MCKRDY_TIMEOUT
611: sub tmp2, tmp2, #1
62 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010063 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010064 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
65 tst tmp1, #AT91_PMC_MCKRDY
Andrew Victoreaad2db2008-09-21 21:35:18 +010066 beq 1b
672:
68 .endm
69
70/*
71 * Wait until master oscillator has stabilized.
72 */
73 .macro wait_moscrdy
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010074 mov tmp2, #MOSCRDY_TIMEOUT
751: sub tmp2, tmp2, #1
76 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010077 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010078 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
79 tst tmp1, #AT91_PMC_MOSCS
Andrew Victoreaad2db2008-09-21 21:35:18 +010080 beq 1b
812:
82 .endm
83
84/*
85 * Wait until PLLA has locked.
86 */
87 .macro wait_pllalock
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010088 mov tmp2, #PLLALOCK_TIMEOUT
891: sub tmp2, tmp2, #1
90 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +010091 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010092 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
93 tst tmp1, #AT91_PMC_LOCKA
Andrew Victoreaad2db2008-09-21 21:35:18 +010094 beq 1b
952:
96 .endm
97
98/*
99 * Wait until PLLB has locked.
100 */
101 .macro wait_pllblock
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100102 mov tmp2, #PLLBLOCK_TIMEOUT
1031: sub tmp2, tmp2, #1
104 cmp tmp2, #0
Andrew Victoreaad2db2008-09-21 21:35:18 +0100105 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100106 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
107 tst tmp1, #AT91_PMC_LOCKB
Andrew Victoreaad2db2008-09-21 21:35:18 +0100108 beq 1b
1092:
110 .endm
111
112 .text
113
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100114/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, void __iomem *ramc1) */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100115ENTRY(at91_slow_clock)
116 /* Save registers on stack */
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100117 stmfd sp!, {r3 - r12, lr}
Andrew Victoreaad2db2008-09-21 21:35:18 +0100118
119 /*
120 * Register usage:
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100121 * R0 = Base address of AT91_PMC
122 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
123 * R2 = Base address of second RAM Controller or 0 if not present
Andrew Victoreaad2db2008-09-21 21:35:18 +0100124 * R3 = temporary register
125 * R4 = temporary register
126 */
Andrew Victoreaad2db2008-09-21 21:35:18 +0100127
128 /* Drain write buffer */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100129 mov tmp1, #0
130 mcr p15, 0, tmp1, c7, c10, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100131
132#ifdef CONFIG_ARCH_AT91RM9200
133 /* Put SDRAM in self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100134 mov tmp1, #1
Jean-Christophe PLAGNIOL-VILLARD1a269ad2011-11-16 02:58:31 +0800135 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100136#elif defined(CONFIG_ARCH_AT91SAM9G45)
Andrew Victoreaad2db2008-09-21 21:35:18 +0100137
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100138 /* prepare for DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100139 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
140 str tmp1, .saved_sam9_lpr
141 bic tmp1, #AT91_DDRSDRC_LPCB
142 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100143
144 /* figure out if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100145 cmp ramc1, #0
146 ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
147 strne tmp2, .saved_sam9_lpr1
148 bicne tmp2, #AT91_DDRSDRC_LPCB
149 orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100150
151 /* Enable DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100152 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
153 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100154#else
155 /* Enable SDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100156 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
157 str tmp1, .saved_sam9_lpr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100158
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100159 bic tmp1, #AT91_SDRAMC_LPCB
160 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
161 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100162#endif
163
164 /* Save Master clock setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100165 ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
166 str tmp1, .saved_mckr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100167
168 /*
169 * Set the Master clock source to slow clock
170 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100171 bic tmp1, tmp1, #AT91_PMC_CSS
172 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100173
174 wait_mckrdy
175
176#ifdef SLOWDOWN_MASTER_CLOCK
177 /*
178 * Set the Master Clock PRES and MDIV fields.
179 *
180 * See AT91RM9200 errata #27 and #28 for details.
181 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100182 mov tmp1, #0
183 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100184
185 wait_mckrdy
186#endif
187
188 /* Save PLLA setting and disable it */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100189 ldr tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
190 str tmp1, .saved_pllar
Andrew Victoreaad2db2008-09-21 21:35:18 +0100191
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100192 mov tmp1, #AT91_PMC_PLLCOUNT
193 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
194 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100195
Andrew Victoreaad2db2008-09-21 21:35:18 +0100196 /* Save PLLB setting and disable it */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100197 ldr tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
198 str tmp1, .saved_pllbr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100199
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100200 mov tmp1, #AT91_PMC_PLLCOUNT
201 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100202
Andrew Victoreaad2db2008-09-21 21:35:18 +0100203 /* Turn off the main oscillator */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100204 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
205 bic tmp1, tmp1, #AT91_PMC_MOSCEN
206 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100207
208 /* Wait for interrupt */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100209 mcr p15, 0, tmp1, c7, c0, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100210
211 /* Turn on the main oscillator */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100212 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
213 orr tmp1, tmp1, #AT91_PMC_MOSCEN
214 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100215
216 wait_moscrdy
217
218 /* Restore PLLB setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100219 ldr tmp1, .saved_pllbr
220 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100221
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100222 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100223 bne 1f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100224 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100225 beq 2f
2261:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100227 wait_pllblock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002282:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100229
230 /* Restore PLLA setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100231 ldr tmp1, .saved_pllar
232 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100233
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100234 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100235 bne 3f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100236 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100237 beq 4f
2383:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100239 wait_pllalock
Anders Larsen9823f1a2010-04-08 11:48:16 +01002404:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100241
242#ifdef SLOWDOWN_MASTER_CLOCK
243 /*
244 * First set PRES if it was not 0,
245 * than set CSS and MDIV fields.
246 *
247 * See AT91RM9200 errata #27 and #28 for details.
248 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100249 ldr tmp1, .saved_mckr
250 tst tmp1, #AT91_PMC_PRES
Andrew Victoreaad2db2008-09-21 21:35:18 +0100251 beq 2f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100252 and tmp1, tmp1, #AT91_PMC_PRES
253 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100254
255 wait_mckrdy
256#endif
257
258 /*
259 * Restore master clock setting
260 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +01002612: ldr tmp1, .saved_mckr
262 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100263
264 wait_mckrdy
265
266#ifdef CONFIG_ARCH_AT91RM9200
267 /* Do nothing - self-refresh is automatically disabled. */
Jean-Christophe PLAGNIOL-VILLARD9918cea2012-01-26 14:07:09 +0100268#elif defined(CONFIG_ARCH_AT91SAM9G45)
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100269 /* Restore LPR on AT91 with DDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100270 ldr tmp1, .saved_sam9_lpr
271 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100272
273 /* if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100274 cmp ramc1, #0
275 ldrne tmp2, .saved_sam9_lpr1
276 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100277
Andrew Victoreaad2db2008-09-21 21:35:18 +0100278#else
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100279 /* Restore LPR on AT91 with SDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100280 ldr tmp1, .saved_sam9_lpr
281 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100282#endif
283
284 /* Restore registers, and return */
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +0100285 ldmfd sp!, {r3 - r12, pc}
Andrew Victoreaad2db2008-09-21 21:35:18 +0100286
287
288.saved_mckr:
289 .word 0
290
291.saved_pllar:
292 .word 0
293
294.saved_pllbr:
295 .word 0
296
297.saved_sam9_lpr:
298 .word 0
299
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100300.saved_sam9_lpr1:
301 .word 0
302
Andrew Victoreaad2db2008-09-21 21:35:18 +0100303ENTRY(at91_slow_clock_sz)
304 .word .-at91_slow_clock