2 * arch/arm/mach-at91/pm_slow_clock.S
4 * Copyright (C) 2006 Savin Zlobec
7 * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
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.
15 #include <linux/linkage.h>
16 #include <mach/hardware.h>
17 #include <mach/at91_pmc.h>
18 #include <mach/at91_ramc.h>
21 #ifdef CONFIG_SOC_AT91SAM9263
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.
26 #warning Assuming EB1 SDRAM controller is *NOT* used
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.
35 #undef SLOWDOWN_MASTER_CLOCK
37 #define MCKRDY_TIMEOUT 1000
38 #define MOSCRDY_TIMEOUT 1000
39 #define PLLALOCK_TIMEOUT 1000
40 #define PLLBLOCK_TIMEOUT 1000
50 * Wait until master clock is ready (after switching master clock source)
53 mov tmp2, #MCKRDY_TIMEOUT
57 ldr tmp1, [pmc, #AT91_PMC_SR]
58 tst tmp1, #AT91_PMC_MCKRDY
64 * Wait until master oscillator has stabilized.
67 mov tmp2, #MOSCRDY_TIMEOUT
71 ldr tmp1, [pmc, #AT91_PMC_SR]
72 tst tmp1, #AT91_PMC_MOSCS
78 * Wait until PLLA has locked.
81 mov tmp2, #PLLALOCK_TIMEOUT
85 ldr tmp1, [pmc, #AT91_PMC_SR]
86 tst tmp1, #AT91_PMC_LOCKA
92 * Wait until PLLB has locked.
95 mov tmp2, #PLLBLOCK_TIMEOUT
99 ldr tmp1, [pmc, #AT91_PMC_SR]
100 tst tmp1, #AT91_PMC_LOCKB
107 /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
108 * void __iomem *ramc1, int memctrl)
110 ENTRY(at91_slow_clock)
111 /* Save registers on stack */
112 stmfd sp!, {r4 - r12, lr}
116 * R0 = Base address of AT91_PMC
117 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
118 * R2 = Base address of second RAM Controller or 0 if not present
119 * R3 = Memory controller
120 * R4 = temporary register
121 * R5 = temporary register
124 /* Drain write buffer */
126 mcr p15, 0, tmp1, c7, c10, 4
128 cmp memctrl, #AT91_MEMCTRL_MC
132 * at91rm9200 Memory controller
134 /* Put SDRAM in self-refresh mode */
136 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
140 * DDRSDR Memory controller
143 cmp memctrl, #AT91_MEMCTRL_DDRSDR
146 /* prepare for DDRAM self-refresh mode */
147 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
148 str tmp1, .saved_sam9_lpr
149 bic tmp1, #AT91_DDRSDRC_LPCB
150 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
152 /* figure out if we use the second ram controller */
154 ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
155 strne tmp2, .saved_sam9_lpr1
156 bicne tmp2, #AT91_DDRSDRC_LPCB
157 orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
159 /* Enable DDRAM self-refresh mode */
160 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
161 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
166 * SDRAMC Memory controller
169 /* Enable SDRAM self-refresh mode */
170 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
171 str tmp1, .saved_sam9_lpr
173 bic tmp1, #AT91_SDRAMC_LPCB
174 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
175 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
178 /* Save Master clock setting */
179 ldr tmp1, [pmc, #AT91_PMC_MCKR]
180 str tmp1, .saved_mckr
183 * Set the Master clock source to slow clock
185 bic tmp1, tmp1, #AT91_PMC_CSS
186 str tmp1, [pmc, #AT91_PMC_MCKR]
190 #ifdef SLOWDOWN_MASTER_CLOCK
192 * Set the Master Clock PRES and MDIV fields.
194 * See AT91RM9200 errata #27 and #28 for details.
197 str tmp1, [pmc, #AT91_PMC_MCKR]
202 /* Save PLLA setting and disable it */
203 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
204 str tmp1, .saved_pllar
206 mov tmp1, #AT91_PMC_PLLCOUNT
207 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
208 str tmp1, [pmc, #AT91_CKGR_PLLAR]
210 /* Save PLLB setting and disable it */
211 ldr tmp1, [pmc, #AT91_CKGR_PLLBR]
212 str tmp1, .saved_pllbr
214 mov tmp1, #AT91_PMC_PLLCOUNT
215 str tmp1, [pmc, #AT91_CKGR_PLLBR]
217 /* Turn off the main oscillator */
218 ldr tmp1, [pmc, #AT91_CKGR_MOR]
219 bic tmp1, tmp1, #AT91_PMC_MOSCEN
220 str tmp1, [pmc, #AT91_CKGR_MOR]
222 /* Wait for interrupt */
223 mcr p15, 0, tmp1, c7, c0, 4
225 /* Turn on the main oscillator */
226 ldr tmp1, [pmc, #AT91_CKGR_MOR]
227 orr tmp1, tmp1, #AT91_PMC_MOSCEN
228 str tmp1, [pmc, #AT91_CKGR_MOR]
232 /* Restore PLLB setting */
233 ldr tmp1, .saved_pllbr
234 str tmp1, [pmc, #AT91_CKGR_PLLBR]
236 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
238 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
244 /* Restore PLLA setting */
245 ldr tmp1, .saved_pllar
246 str tmp1, [pmc, #AT91_CKGR_PLLAR]
248 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
250 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
256 #ifdef SLOWDOWN_MASTER_CLOCK
258 * First set PRES if it was not 0,
259 * than set CSS and MDIV fields.
261 * See AT91RM9200 errata #27 and #28 for details.
263 ldr tmp1, .saved_mckr
264 tst tmp1, #AT91_PMC_PRES
266 and tmp1, tmp1, #AT91_PMC_PRES
267 str tmp1, [pmc, #AT91_PMC_MCKR]
273 * Restore master clock setting
275 2: ldr tmp1, .saved_mckr
276 str tmp1, [pmc, #AT91_PMC_MCKR]
281 * at91rm9200 Memory controller
282 * Do nothing - self-refresh is automatically disabled.
284 cmp memctrl, #AT91_MEMCTRL_MC
288 * DDRSDR Memory controller
290 cmp memctrl, #AT91_MEMCTRL_DDRSDR
292 /* Restore LPR on AT91 with DDRAM */
293 ldr tmp1, .saved_sam9_lpr
294 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
296 /* if we use the second ram controller */
298 ldrne tmp2, .saved_sam9_lpr1
299 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
304 * SDRAMC Memory controller
307 /* Restore LPR on AT91 with SDRAM */
308 ldr tmp1, .saved_sam9_lpr
309 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
312 /* Restore registers, and return */
313 ldmfd sp!, {r4 - r12, pc}
331 ENTRY(at91_slow_clock_sz)
332 .word .-at91_slow_clock