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_ARCH_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
49 * Wait until master clock is ready (after switching master clock source)
52 mov tmp2, #MCKRDY_TIMEOUT
56 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
57 tst tmp1, #AT91_PMC_MCKRDY
63 * Wait until master oscillator has stabilized.
66 mov tmp2, #MOSCRDY_TIMEOUT
70 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
71 tst tmp1, #AT91_PMC_MOSCS
77 * Wait until PLLA has locked.
80 mov tmp2, #PLLALOCK_TIMEOUT
84 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
85 tst tmp1, #AT91_PMC_LOCKA
91 * Wait until PLLB has locked.
94 mov tmp2, #PLLBLOCK_TIMEOUT
98 ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
99 tst tmp1, #AT91_PMC_LOCKB
106 /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, void __iomem *ramc1) */
107 ENTRY(at91_slow_clock)
108 /* Save registers on stack */
109 stmfd sp!, {r3 - r12, lr}
113 * 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
116 * R3 = temporary register
117 * R4 = temporary register
120 /* Drain write buffer */
122 mcr p15, 0, tmp1, c7, c10, 4
124 #ifdef CONFIG_ARCH_AT91RM9200
125 /* Put SDRAM in self-refresh mode */
127 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
128 #elif defined(CONFIG_ARCH_AT91SAM9G45)
130 /* prepare for DDRAM self-refresh mode */
131 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
136 /* figure out if we use the second ram controller */
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
143 /* Enable DDRAM self-refresh mode */
144 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
145 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
147 /* Enable SDRAM self-refresh mode */
148 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
149 str tmp1, .saved_sam9_lpr
151 bic tmp1, #AT91_SDRAMC_LPCB
152 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
153 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
156 /* Save Master clock setting */
157 ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
158 str tmp1, .saved_mckr
161 * Set the Master clock source to slow clock
163 bic tmp1, tmp1, #AT91_PMC_CSS
164 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
168 #ifdef SLOWDOWN_MASTER_CLOCK
170 * Set the Master Clock PRES and MDIV fields.
172 * See AT91RM9200 errata #27 and #28 for details.
175 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
180 /* Save PLLA setting and disable it */
181 ldr tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
182 str tmp1, .saved_pllar
184 mov tmp1, #AT91_PMC_PLLCOUNT
185 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
186 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
188 /* Save PLLB setting and disable it */
189 ldr tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
190 str tmp1, .saved_pllbr
192 mov tmp1, #AT91_PMC_PLLCOUNT
193 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
195 /* Turn off the main oscillator */
196 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
197 bic tmp1, tmp1, #AT91_PMC_MOSCEN
198 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
200 /* Wait for interrupt */
201 mcr p15, 0, tmp1, c7, c0, 4
203 /* Turn on the main oscillator */
204 ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
205 orr tmp1, tmp1, #AT91_PMC_MOSCEN
206 str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
210 /* Restore PLLB setting */
211 ldr tmp1, .saved_pllbr
212 str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
214 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
216 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
222 /* Restore PLLA setting */
223 ldr tmp1, .saved_pllar
224 str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
226 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
228 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
234 #ifdef SLOWDOWN_MASTER_CLOCK
236 * First set PRES if it was not 0,
237 * than set CSS and MDIV fields.
239 * See AT91RM9200 errata #27 and #28 for details.
241 ldr tmp1, .saved_mckr
242 tst tmp1, #AT91_PMC_PRES
244 and tmp1, tmp1, #AT91_PMC_PRES
245 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
251 * Restore master clock setting
253 2: ldr tmp1, .saved_mckr
254 str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
258 #ifdef CONFIG_ARCH_AT91RM9200
259 /* Do nothing - self-refresh is automatically disabled. */
260 #elif defined(CONFIG_ARCH_AT91SAM9G45)
261 /* Restore LPR on AT91 with DDRAM */
262 ldr tmp1, .saved_sam9_lpr
263 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
265 /* if we use the second ram controller */
267 ldrne tmp2, .saved_sam9_lpr1
268 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
271 /* Restore LPR on AT91 with SDRAM */
272 ldr tmp1, .saved_sam9_lpr
273 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
276 /* Restore registers, and return */
277 ldmfd sp!, {r3 - r12, pc}
295 ENTRY(at91_slow_clock_sz)
296 .word .-at91_slow_clock