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.
14 #include <linux/linkage.h>
15 #include <linux/clk/at91_pmc.h>
18 #define SRAMC_SELF_FRESH_ACTIVE 0x01
19 #define SRAMC_SELF_FRESH_EXIT 0x00
26 * Wait until master clock is ready (after switching master clock source)
29 1: ldr tmp1, [pmc, #AT91_PMC_SR]
30 tst tmp1, #AT91_PMC_MCKRDY
35 * Wait until master oscillator has stabilized.
38 1: ldr tmp1, [pmc, #AT91_PMC_SR]
39 tst tmp1, #AT91_PMC_MOSCS
44 * Wait until PLLA has locked.
47 1: ldr tmp1, [pmc, #AT91_PMC_SR]
48 tst tmp1, #AT91_PMC_LOCKA
53 * Put the processor to enter the idle state
57 #if defined(CONFIG_CPU_V7)
58 mov tmp1, #AT91_PMC_PCK
59 str tmp1, [pmc, #AT91_PMC_SCDR]
63 wfi @ Wait For Interrupt
65 mcr p15, 0, tmp1, c7, c0, 4
75 * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
76 * void __iomem *ramc1, int memctrl)
78 * @r0: base address of AT91_PMC
79 * @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
80 * @r2: base address of second SDRAM Controller or 0 if not present
83 /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
85 ENTRY(at91_pm_suspend_in_sram)
86 /* Save registers on stack */
87 stmfd sp!, {r4 - r12, lr}
89 /* Drain write buffer */
91 mcr p15, 0, tmp1, c7, c10, 4
97 and r0, r3, #AT91_PM_MEMTYPE_MASK
100 lsr r0, r3, #AT91_PM_MODE_OFFSET
101 and r0, r0, #AT91_PM_MODE_MASK
104 /* Active the self-refresh mode */
105 mov r0, #SRAMC_SELF_FRESH_ACTIVE
106 bl at91_sramc_self_refresh
109 tst r0, #AT91_PM_SLOW_CLOCK
110 beq skip_disable_main_clock
114 /* Save Master clock setting */
115 ldr tmp1, [pmc, #AT91_PMC_MCKR]
116 str tmp1, .saved_mckr
119 * Set the Master clock source to slow clock
121 bic tmp1, tmp1, #AT91_PMC_CSS
122 str tmp1, [pmc, #AT91_PMC_MCKR]
126 /* Save PLLA setting and disable it */
127 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
128 str tmp1, .saved_pllar
130 mov tmp1, #AT91_PMC_PLLCOUNT
131 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
132 str tmp1, [pmc, #AT91_CKGR_PLLAR]
134 /* Turn off the main oscillator */
135 ldr tmp1, [pmc, #AT91_CKGR_MOR]
136 bic tmp1, tmp1, #AT91_PMC_MOSCEN
137 orr tmp1, tmp1, #AT91_PMC_KEY
138 str tmp1, [pmc, #AT91_CKGR_MOR]
140 skip_disable_main_clock:
143 /* Wait for interrupt */
147 tst r0, #AT91_PM_SLOW_CLOCK
148 beq skip_enable_main_clock
152 /* Turn on the main oscillator */
153 ldr tmp1, [pmc, #AT91_CKGR_MOR]
154 orr tmp1, tmp1, #AT91_PMC_MOSCEN
155 orr tmp1, tmp1, #AT91_PMC_KEY
156 str tmp1, [pmc, #AT91_CKGR_MOR]
160 /* Restore PLLA setting */
161 ldr tmp1, .saved_pllar
162 str tmp1, [pmc, #AT91_CKGR_PLLAR]
164 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
166 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
173 * Restore master clock setting
175 ldr tmp1, .saved_mckr
176 str tmp1, [pmc, #AT91_PMC_MCKR]
180 skip_enable_main_clock:
181 /* Exit the self-refresh mode */
182 mov r0, #SRAMC_SELF_FRESH_EXIT
183 bl at91_sramc_self_refresh
185 /* Restore registers, and return */
186 ldmfd sp!, {r4 - r12, pc}
187 ENDPROC(at91_pm_suspend_in_sram)
190 * void at91_sramc_self_refresh(unsigned int is_active)
193 * @r0: 1 - active self-refresh mode
194 * 0 - exit self-refresh mode
197 * @r2: base address of the sram controller
200 ENTRY(at91_sramc_self_refresh)
204 cmp r1, #AT91_MEMCTRL_MC
208 * at91rm9200 Memory controller
212 * For exiting the self-refresh mode, do nothing,
213 * automatically exit the self-refresh mode.
215 tst r0, #SRAMC_SELF_FRESH_ACTIVE
218 /* Active SDRAM self-refresh mode */
220 str r3, [r2, #AT91_MC_SDRAMC_SRR]
224 cmp r1, #AT91_MEMCTRL_DDRSDR
228 * DDR Memory controller
230 tst r0, #SRAMC_SELF_FRESH_ACTIVE
233 /* LPDDR1 --> force DDR2 mode during self-refresh */
234 ldr r3, [r2, #AT91_DDRSDRC_MDR]
235 str r3, .saved_sam9_mdr
236 bic r3, r3, #~AT91_DDRSDRC_MD
237 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
238 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
239 biceq r3, r3, #AT91_DDRSDRC_MD
240 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
241 streq r3, [r2, #AT91_DDRSDRC_MDR]
243 /* Active DDRC self-refresh mode */
244 ldr r3, [r2, #AT91_DDRSDRC_LPR]
245 str r3, .saved_sam9_lpr
246 bic r3, r3, #AT91_DDRSDRC_LPCB
247 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
248 str r3, [r2, #AT91_DDRSDRC_LPR]
250 /* If using the 2nd ddr controller */
255 ldr r3, [r2, #AT91_DDRSDRC_MDR]
256 str r3, .saved_sam9_mdr1
257 bic r3, r3, #~AT91_DDRSDRC_MD
258 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
259 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
260 biceq r3, r3, #AT91_DDRSDRC_MD
261 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
262 streq r3, [r2, #AT91_DDRSDRC_MDR]
264 /* Active DDRC self-refresh mode */
265 ldr r3, [r2, #AT91_DDRSDRC_LPR]
266 str r3, .saved_sam9_lpr1
267 bic r3, r3, #AT91_DDRSDRC_LPCB
268 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
269 str r3, [r2, #AT91_DDRSDRC_LPR]
275 /* Restore MDR in case of LPDDR1 */
276 ldr r3, .saved_sam9_mdr
277 str r3, [r2, #AT91_DDRSDRC_MDR]
278 /* Restore LPR on AT91 with DDRAM */
279 ldr r3, .saved_sam9_lpr
280 str r3, [r2, #AT91_DDRSDRC_LPR]
282 /* If using the 2nd ddr controller */
285 ldrne r3, .saved_sam9_mdr1
286 strne r3, [r2, #AT91_DDRSDRC_MDR]
287 ldrne r3, .saved_sam9_lpr1
288 strne r3, [r2, #AT91_DDRSDRC_LPR]
293 * SDRAMC Memory controller
296 tst r0, #SRAMC_SELF_FRESH_ACTIVE
299 /* Active SDRAMC self-refresh mode */
300 ldr r3, [r2, #AT91_SDRAMC_LPR]
301 str r3, .saved_sam9_lpr
302 bic r3, r3, #AT91_SDRAMC_LPCB
303 orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
304 str r3, [r2, #AT91_SDRAMC_LPR]
307 ldr r3, .saved_sam9_lpr
308 str r3, [r2, #AT91_SDRAMC_LPR]
312 ENDPROC(at91_sramc_self_refresh)
337 ENTRY(at91_pm_suspend_in_sram_sz)
338 .word .-at91_pm_suspend_in_sram