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>
17 #include "generated/at91_pm_data-offsets.h"
19 #define SRAMC_SELF_FRESH_ACTIVE 0x01
20 #define SRAMC_SELF_FRESH_EXIT 0x00
27 * Wait until master clock is ready (after switching master clock source)
30 1: ldr tmp1, [pmc, #AT91_PMC_SR]
31 tst tmp1, #AT91_PMC_MCKRDY
36 * Wait until master oscillator has stabilized.
39 1: ldr tmp1, [pmc, #AT91_PMC_SR]
40 tst tmp1, #AT91_PMC_MOSCS
45 * Wait until PLLA has locked.
48 1: ldr tmp1, [pmc, #AT91_PMC_SR]
49 tst tmp1, #AT91_PMC_LOCKA
54 * Put the processor to enter the idle state
58 #if defined(CONFIG_CPU_V7)
59 mov tmp1, #AT91_PMC_PCK
60 str tmp1, [pmc, #AT91_PMC_SCDR]
64 wfi @ Wait For Interrupt
66 mcr p15, 0, tmp1, c7, c0, 4
76 * void at91_suspend_sram_fn(struct at91_pm_data*)
78 * @r0: base address of struct at91_pm_data
80 /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
82 ENTRY(at91_pm_suspend_in_sram)
83 /* Save registers on stack */
84 stmfd sp!, {r4 - r12, lr}
86 /* Drain write buffer */
88 mcr p15, 0, tmp1, c7, c10, 4
90 ldr tmp1, [r0, #PM_DATA_PMC]
92 ldr tmp1, [r0, #PM_DATA_RAMC0]
94 ldr tmp1, [r0, #PM_DATA_RAMC1]
95 str tmp1, .sramc1_base
96 ldr tmp1, [r0, #PM_DATA_MEMCTRL]
98 ldr tmp1, [r0, #PM_DATA_MODE]
101 /* Active the self-refresh mode */
102 mov r0, #SRAMC_SELF_FRESH_ACTIVE
103 bl at91_sramc_self_refresh
106 tst r0, #AT91_PM_SLOW_CLOCK
107 beq skip_disable_main_clock
111 /* Save Master clock setting */
112 ldr tmp1, [pmc, #AT91_PMC_MCKR]
113 str tmp1, .saved_mckr
116 * Set the Master clock source to slow clock
118 bic tmp1, tmp1, #AT91_PMC_CSS
119 str tmp1, [pmc, #AT91_PMC_MCKR]
123 /* Save PLLA setting and disable it */
124 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
125 str tmp1, .saved_pllar
127 mov tmp1, #AT91_PMC_PLLCOUNT
128 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
129 str tmp1, [pmc, #AT91_CKGR_PLLAR]
131 /* Turn off the main oscillator */
132 ldr tmp1, [pmc, #AT91_CKGR_MOR]
133 bic tmp1, tmp1, #AT91_PMC_MOSCEN
134 orr tmp1, tmp1, #AT91_PMC_KEY
135 str tmp1, [pmc, #AT91_CKGR_MOR]
137 skip_disable_main_clock:
140 /* Wait for interrupt */
144 tst r0, #AT91_PM_SLOW_CLOCK
145 beq skip_enable_main_clock
149 /* Turn on the main oscillator */
150 ldr tmp1, [pmc, #AT91_CKGR_MOR]
151 orr tmp1, tmp1, #AT91_PMC_MOSCEN
152 orr tmp1, tmp1, #AT91_PMC_KEY
153 str tmp1, [pmc, #AT91_CKGR_MOR]
157 /* Restore PLLA setting */
158 ldr tmp1, .saved_pllar
159 str tmp1, [pmc, #AT91_CKGR_PLLAR]
161 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
163 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
170 * Restore master clock setting
172 ldr tmp1, .saved_mckr
173 str tmp1, [pmc, #AT91_PMC_MCKR]
177 skip_enable_main_clock:
178 /* Exit the self-refresh mode */
179 mov r0, #SRAMC_SELF_FRESH_EXIT
180 bl at91_sramc_self_refresh
182 /* Restore registers, and return */
183 ldmfd sp!, {r4 - r12, pc}
184 ENDPROC(at91_pm_suspend_in_sram)
187 * void at91_sramc_self_refresh(unsigned int is_active)
190 * @r0: 1 - active self-refresh mode
191 * 0 - exit self-refresh mode
194 * @r2: base address of the sram controller
197 ENTRY(at91_sramc_self_refresh)
201 cmp r1, #AT91_MEMCTRL_MC
205 * at91rm9200 Memory controller
209 * For exiting the self-refresh mode, do nothing,
210 * automatically exit the self-refresh mode.
212 tst r0, #SRAMC_SELF_FRESH_ACTIVE
215 /* Active SDRAM self-refresh mode */
217 str r3, [r2, #AT91_MC_SDRAMC_SRR]
221 cmp r1, #AT91_MEMCTRL_DDRSDR
225 * DDR Memory controller
227 tst r0, #SRAMC_SELF_FRESH_ACTIVE
230 /* LPDDR1 --> force DDR2 mode during self-refresh */
231 ldr r3, [r2, #AT91_DDRSDRC_MDR]
232 str r3, .saved_sam9_mdr
233 bic r3, r3, #~AT91_DDRSDRC_MD
234 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
235 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
236 biceq r3, r3, #AT91_DDRSDRC_MD
237 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
238 streq r3, [r2, #AT91_DDRSDRC_MDR]
240 /* Active DDRC self-refresh mode */
241 ldr r3, [r2, #AT91_DDRSDRC_LPR]
242 str r3, .saved_sam9_lpr
243 bic r3, r3, #AT91_DDRSDRC_LPCB
244 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
245 str r3, [r2, #AT91_DDRSDRC_LPR]
247 /* If using the 2nd ddr controller */
252 ldr r3, [r2, #AT91_DDRSDRC_MDR]
253 str r3, .saved_sam9_mdr1
254 bic r3, r3, #~AT91_DDRSDRC_MD
255 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
256 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
257 biceq r3, r3, #AT91_DDRSDRC_MD
258 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
259 streq r3, [r2, #AT91_DDRSDRC_MDR]
261 /* Active DDRC self-refresh mode */
262 ldr r3, [r2, #AT91_DDRSDRC_LPR]
263 str r3, .saved_sam9_lpr1
264 bic r3, r3, #AT91_DDRSDRC_LPCB
265 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
266 str r3, [r2, #AT91_DDRSDRC_LPR]
272 /* Restore MDR in case of LPDDR1 */
273 ldr r3, .saved_sam9_mdr
274 str r3, [r2, #AT91_DDRSDRC_MDR]
275 /* Restore LPR on AT91 with DDRAM */
276 ldr r3, .saved_sam9_lpr
277 str r3, [r2, #AT91_DDRSDRC_LPR]
279 /* If using the 2nd ddr controller */
282 ldrne r3, .saved_sam9_mdr1
283 strne r3, [r2, #AT91_DDRSDRC_MDR]
284 ldrne r3, .saved_sam9_lpr1
285 strne r3, [r2, #AT91_DDRSDRC_LPR]
290 * SDRAMC Memory controller
293 tst r0, #SRAMC_SELF_FRESH_ACTIVE
296 /* Active SDRAMC self-refresh mode */
297 ldr r3, [r2, #AT91_SDRAMC_LPR]
298 str r3, .saved_sam9_lpr
299 bic r3, r3, #AT91_SDRAMC_LPCB
300 orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
301 str r3, [r2, #AT91_SDRAMC_LPR]
304 ldr r3, .saved_sam9_lpr
305 str r3, [r2, #AT91_SDRAMC_LPR]
309 ENDPROC(at91_sramc_self_refresh)
334 ENTRY(at91_pm_suspend_in_sram_sz)
335 .word .-at91_pm_suspend_in_sram