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>
19 #if defined(CONFIG_ARCH_AT91RM9200)
20 #include <mach/at91rm9200_mc.h>
21 #elif defined(CONFIG_ARCH_AT91CAP9)
22 #include <mach/at91cap9_ddrsdr.h>
23 #elif defined(CONFIG_ARCH_AT91SAM9G45)
24 #include <mach/at91sam9_ddrsdr.h>
26 #include <mach/at91sam9_sdramc.h>
30 #ifdef CONFIG_ARCH_AT91SAM9263
31 #warning Assuming EB1 SDRAM controller is *NOT* used
35 * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
36 * clock during suspend by adjusting its prescalar and divisor.
37 * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
38 * are errata regarding adjusting the prescalar and divisor.
40 #undef SLOWDOWN_MASTER_CLOCK
42 #define MCKRDY_TIMEOUT 1000
43 #define MOSCRDY_TIMEOUT 1000
44 #define PLLALOCK_TIMEOUT 1000
45 #define PLLBLOCK_TIMEOUT 1000
49 * Wait until master clock is ready (after switching master clock source)
52 mov r4, #MCKRDY_TIMEOUT
56 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
57 tst r3, #AT91_PMC_MCKRDY
63 * Wait until master oscillator has stabilized.
66 mov r4, #MOSCRDY_TIMEOUT
70 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
71 tst r3, #AT91_PMC_MOSCS
77 * Wait until PLLA has locked.
80 mov r4, #PLLALOCK_TIMEOUT
84 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
85 tst r3, #AT91_PMC_LOCKA
91 * Wait until PLLB has locked.
94 mov r4, #PLLBLOCK_TIMEOUT
98 ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
99 tst r3, #AT91_PMC_LOCKB
106 ENTRY(at91_slow_clock)
107 /* Save registers on stack */
108 stmfd sp!, {r0 - r12, lr}
112 * R1 = Base address of AT91_PMC
113 * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
114 * R3 = temporary register
115 * R4 = temporary register
116 * R5 = Base address of second RAM Controller or 0 if not present
118 ldr r1, .at91_va_base_pmc
119 ldr r2, .at91_va_base_sdramc
120 ldr r5, .at91_va_base_ramc1
122 /* Drain write buffer */
123 mcr p15, 0, r0, c7, c10, 4
125 #ifdef CONFIG_ARCH_AT91RM9200
126 /* Put SDRAM in self-refresh mode */
128 str r3, [r2, #AT91_SDRAMC_SRR]
129 #elif defined(CONFIG_ARCH_AT91CAP9) \
130 || defined(CONFIG_ARCH_AT91SAM9G45)
132 /* prepare for DDRAM self-refresh mode */
133 ldr r3, [r2, #AT91_DDRSDRC_LPR]
134 str r3, .saved_sam9_lpr
135 bic r3, #AT91_DDRSDRC_LPCB
136 orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
138 /* figure out if we use the second ram controller */
140 ldrne r4, [r5, #AT91_DDRSDRC_LPR]
141 strne r4, .saved_sam9_lpr1
142 bicne r4, #AT91_DDRSDRC_LPCB
143 orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH
145 /* Enable DDRAM self-refresh mode */
146 str r3, [r2, #AT91_DDRSDRC_LPR]
147 strne r4, [r5, #AT91_DDRSDRC_LPR]
149 /* Enable SDRAM self-refresh mode */
150 ldr r3, [r2, #AT91_SDRAMC_LPR]
151 str r3, .saved_sam9_lpr
153 bic r3, #AT91_SDRAMC_LPCB
154 orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
155 str r3, [r2, #AT91_SDRAMC_LPR]
158 /* Save Master clock setting */
159 ldr r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
163 * Set the Master clock source to slow clock
165 bic r3, r3, #AT91_PMC_CSS
166 str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
170 #ifdef SLOWDOWN_MASTER_CLOCK
172 * Set the Master Clock PRES and MDIV fields.
174 * See AT91RM9200 errata #27 and #28 for details.
177 str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
182 /* Save PLLA setting and disable it */
183 ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
186 mov r3, #AT91_PMC_PLLCOUNT
187 orr r3, r3, #(1 << 29) /* bit 29 always set */
188 str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
190 /* Save PLLB setting and disable it */
191 ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
194 mov r3, #AT91_PMC_PLLCOUNT
195 str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
197 /* Turn off the main oscillator */
198 ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
199 bic r3, r3, #AT91_PMC_MOSCEN
200 str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
202 /* Wait for interrupt */
203 mcr p15, 0, r0, c7, c0, 4
205 /* Turn on the main oscillator */
206 ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
207 orr r3, r3, #AT91_PMC_MOSCEN
208 str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
212 /* Restore PLLB setting */
214 str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
216 tst r3, #(AT91_PMC_MUL & 0xff0000)
218 tst r3, #(AT91_PMC_MUL & ~0xff0000)
224 /* Restore PLLA setting */
226 str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
228 tst r3, #(AT91_PMC_MUL & 0xff0000)
230 tst r3, #(AT91_PMC_MUL & ~0xff0000)
236 #ifdef SLOWDOWN_MASTER_CLOCK
238 * First set PRES if it was not 0,
239 * than set CSS and MDIV fields.
241 * See AT91RM9200 errata #27 and #28 for details.
244 tst r3, #AT91_PMC_PRES
246 and r3, r3, #AT91_PMC_PRES
247 str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
253 * Restore master clock setting
255 2: ldr r3, .saved_mckr
256 str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
260 #ifdef CONFIG_ARCH_AT91RM9200
261 /* Do nothing - self-refresh is automatically disabled. */
262 #elif defined(CONFIG_ARCH_AT91CAP9) \
263 || defined(CONFIG_ARCH_AT91SAM9G45)
264 /* Restore LPR on AT91 with DDRAM */
265 ldr r3, .saved_sam9_lpr
266 str r3, [r2, #AT91_DDRSDRC_LPR]
268 /* if we use the second ram controller */
270 ldrne r4, .saved_sam9_lpr1
271 strne r4, [r5, #AT91_DDRSDRC_LPR]
274 /* Restore LPR on AT91 with SDRAM */
275 ldr r3, .saved_sam9_lpr
276 str r3, [r2, #AT91_SDRAMC_LPR]
279 /* Restore registers, and return */
280 ldmfd sp!, {r0 - r12, pc}
299 .word AT91_VA_BASE_SYS + AT91_PMC
301 #ifdef CONFIG_ARCH_AT91RM9200
302 .at91_va_base_sdramc:
303 .word AT91_VA_BASE_SYS
304 #elif defined(CONFIG_ARCH_AT91CAP9) \
305 || defined(CONFIG_ARCH_AT91SAM9G45)
306 .at91_va_base_sdramc:
307 .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
309 .at91_va_base_sdramc:
310 .word AT91_VA_BASE_SYS + AT91_SDRAMC0
314 #if defined(CONFIG_ARCH_AT91SAM9G45)
315 .word AT91_VA_BASE_SYS + AT91_DDRSDRC1
320 ENTRY(at91_slow_clock_sz)
321 .word .-at91_slow_clock