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 for main oscillator selection is done
48 1: ldr tmp1, [pmc, #AT91_PMC_SR]
49 tst tmp1, #AT91_PMC_MOSCSELS
54 * Wait until PLLA has locked.
57 1: ldr tmp1, [pmc, #AT91_PMC_SR]
58 tst tmp1, #AT91_PMC_LOCKA
63 * Put the processor to enter the idle state
67 #if defined(CONFIG_CPU_V7)
68 mov tmp1, #AT91_PMC_PCK
69 str tmp1, [pmc, #AT91_PMC_SCDR]
73 wfi @ Wait For Interrupt
75 mcr p15, 0, tmp1, c7, c0, 4
85 * void at91_suspend_sram_fn(struct at91_pm_data*)
87 * @r0: base address of struct at91_pm_data
89 /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
91 ENTRY(at91_pm_suspend_in_sram)
92 /* Save registers on stack */
93 stmfd sp!, {r4 - r12, lr}
95 /* Drain write buffer */
97 mcr p15, 0, tmp1, c7, c10, 4
99 ldr tmp1, [r0, #PM_DATA_PMC]
101 ldr tmp1, [r0, #PM_DATA_RAMC0]
102 str tmp1, .sramc_base
103 ldr tmp1, [r0, #PM_DATA_RAMC1]
104 str tmp1, .sramc1_base
105 ldr tmp1, [r0, #PM_DATA_MEMCTRL]
107 ldr tmp1, [r0, #PM_DATA_MODE]
109 /* Both ldrne below are here to preload their address in the TLB */
110 ldr tmp1, [r0, #PM_DATA_SHDWC]
113 ldrne tmp2, [tmp1, #0]
114 ldr tmp1, [r0, #PM_DATA_SFRBU]
117 ldrne tmp2, [tmp1, #0x10]
119 /* Active the self-refresh mode */
120 mov r0, #SRAMC_SELF_FRESH_ACTIVE
121 bl at91_sramc_self_refresh
124 cmp r0, #AT91_PM_STANDBY
126 cmp r0, #AT91_PM_BACKUP
133 /* Wait for interrupt */
143 /* Exit the self-refresh mode */
144 mov r0, #SRAMC_SELF_FRESH_EXIT
145 bl at91_sramc_self_refresh
147 /* Restore registers, and return */
148 ldmfd sp!, {r4 - r12, pc}
149 ENDPROC(at91_pm_suspend_in_sram)
151 ENTRY(at91_backup_mode)
152 /* Switch the master clock source to slow clock. */
154 ldr tmp1, [pmc, #AT91_PMC_MCKR]
155 bic tmp1, tmp1, #AT91_PMC_CSS
156 str tmp1, [pmc, #AT91_PMC_MCKR]
163 str tmp1, [r0, #0x10]
167 mov tmp1, #0xA5000000
170 ENDPROC(at91_backup_mode)
172 .macro at91_pm_ulp0_mode
175 /* Turn off the crystal oscillator */
176 ldr tmp1, [pmc, #AT91_CKGR_MOR]
177 bic tmp1, tmp1, #AT91_PMC_MOSCEN
178 orr tmp1, tmp1, #AT91_PMC_KEY
179 str tmp1, [pmc, #AT91_CKGR_MOR]
181 /* Wait for interrupt */
184 /* Turn on the crystal oscillator */
185 ldr tmp1, [pmc, #AT91_CKGR_MOR]
186 orr tmp1, tmp1, #AT91_PMC_MOSCEN
187 orr tmp1, tmp1, #AT91_PMC_KEY
188 str tmp1, [pmc, #AT91_CKGR_MOR]
194 * Note: This procedure only applies on the platform which uses
195 * the external crystal oscillator as a main clock source.
197 .macro at91_pm_ulp1_mode
200 /* Switch the main clock source to 12-MHz RC oscillator */
201 ldr tmp1, [pmc, #AT91_CKGR_MOR]
202 bic tmp1, tmp1, #AT91_PMC_MOSCSEL
203 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
204 orr tmp1, tmp1, #AT91_PMC_KEY
205 str tmp1, [pmc, #AT91_CKGR_MOR]
209 /* Disable the crystal oscillator */
210 ldr tmp1, [pmc, #AT91_CKGR_MOR]
211 bic tmp1, tmp1, #AT91_PMC_MOSCEN
212 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
213 orr tmp1, tmp1, #AT91_PMC_KEY
214 str tmp1, [pmc, #AT91_CKGR_MOR]
216 /* Switch the master clock source to main clock */
217 ldr tmp1, [pmc, #AT91_PMC_MCKR]
218 bic tmp1, tmp1, #AT91_PMC_CSS
219 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
220 str tmp1, [pmc, #AT91_PMC_MCKR]
224 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
225 ldr tmp1, [pmc, #AT91_CKGR_MOR]
226 orr tmp1, tmp1, #AT91_PMC_WAITMODE
227 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
228 orr tmp1, tmp1, #AT91_PMC_KEY
229 str tmp1, [pmc, #AT91_CKGR_MOR]
233 /* Enable the crystal oscillator */
234 ldr tmp1, [pmc, #AT91_CKGR_MOR]
235 orr tmp1, tmp1, #AT91_PMC_MOSCEN
236 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
237 orr tmp1, tmp1, #AT91_PMC_KEY
238 str tmp1, [pmc, #AT91_CKGR_MOR]
242 /* Switch the master clock source to slow clock */
243 ldr tmp1, [pmc, #AT91_PMC_MCKR]
244 bic tmp1, tmp1, #AT91_PMC_CSS
245 str tmp1, [pmc, #AT91_PMC_MCKR]
249 /* Switch main clock source to crystal oscillator */
250 ldr tmp1, [pmc, #AT91_CKGR_MOR]
251 orr tmp1, tmp1, #AT91_PMC_MOSCSEL
252 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
253 orr tmp1, tmp1, #AT91_PMC_KEY
254 str tmp1, [pmc, #AT91_CKGR_MOR]
258 /* Switch the master clock source to main clock */
259 ldr tmp1, [pmc, #AT91_PMC_MCKR]
260 bic tmp1, tmp1, #AT91_PMC_CSS
261 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
262 str tmp1, [pmc, #AT91_PMC_MCKR]
270 /* Save Master clock setting */
271 ldr tmp1, [pmc, #AT91_PMC_MCKR]
272 str tmp1, .saved_mckr
275 * Set the Master clock source to slow clock
277 bic tmp1, tmp1, #AT91_PMC_CSS
278 str tmp1, [pmc, #AT91_PMC_MCKR]
282 /* Save PLLA setting and disable it */
283 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
284 str tmp1, .saved_pllar
286 mov tmp1, #AT91_PMC_PLLCOUNT
287 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
288 str tmp1, [pmc, #AT91_CKGR_PLLAR]
291 cmp r0, #AT91_PM_ULP1
304 /* Restore PLLA setting */
305 ldr tmp1, .saved_pllar
306 str tmp1, [pmc, #AT91_CKGR_PLLAR]
308 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
310 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
317 * Restore master clock setting
319 ldr tmp1, .saved_mckr
320 str tmp1, [pmc, #AT91_PMC_MCKR]
325 ENDPROC(at91_ulp_mode)
328 * void at91_sramc_self_refresh(unsigned int is_active)
331 * @r0: 1 - active self-refresh mode
332 * 0 - exit self-refresh mode
335 * @r2: base address of the sram controller
338 ENTRY(at91_sramc_self_refresh)
342 cmp r1, #AT91_MEMCTRL_MC
346 * at91rm9200 Memory controller
350 * For exiting the self-refresh mode, do nothing,
351 * automatically exit the self-refresh mode.
353 tst r0, #SRAMC_SELF_FRESH_ACTIVE
356 /* Active SDRAM self-refresh mode */
358 str r3, [r2, #AT91_MC_SDRAMC_SRR]
362 cmp r1, #AT91_MEMCTRL_DDRSDR
366 * DDR Memory controller
368 tst r0, #SRAMC_SELF_FRESH_ACTIVE
371 /* LPDDR1 --> force DDR2 mode during self-refresh */
372 ldr r3, [r2, #AT91_DDRSDRC_MDR]
373 str r3, .saved_sam9_mdr
374 bic r3, r3, #~AT91_DDRSDRC_MD
375 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
376 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
377 biceq r3, r3, #AT91_DDRSDRC_MD
378 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
379 streq r3, [r2, #AT91_DDRSDRC_MDR]
381 /* Active DDRC self-refresh mode */
382 ldr r3, [r2, #AT91_DDRSDRC_LPR]
383 str r3, .saved_sam9_lpr
384 bic r3, r3, #AT91_DDRSDRC_LPCB
385 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
386 str r3, [r2, #AT91_DDRSDRC_LPR]
388 /* If using the 2nd ddr controller */
393 ldr r3, [r2, #AT91_DDRSDRC_MDR]
394 str r3, .saved_sam9_mdr1
395 bic r3, r3, #~AT91_DDRSDRC_MD
396 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
397 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
398 biceq r3, r3, #AT91_DDRSDRC_MD
399 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
400 streq r3, [r2, #AT91_DDRSDRC_MDR]
402 /* Active DDRC self-refresh mode */
403 ldr r3, [r2, #AT91_DDRSDRC_LPR]
404 str r3, .saved_sam9_lpr1
405 bic r3, r3, #AT91_DDRSDRC_LPCB
406 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
407 str r3, [r2, #AT91_DDRSDRC_LPR]
413 /* Restore MDR in case of LPDDR1 */
414 ldr r3, .saved_sam9_mdr
415 str r3, [r2, #AT91_DDRSDRC_MDR]
416 /* Restore LPR on AT91 with DDRAM */
417 ldr r3, .saved_sam9_lpr
418 str r3, [r2, #AT91_DDRSDRC_LPR]
420 /* If using the 2nd ddr controller */
423 ldrne r3, .saved_sam9_mdr1
424 strne r3, [r2, #AT91_DDRSDRC_MDR]
425 ldrne r3, .saved_sam9_lpr1
426 strne r3, [r2, #AT91_DDRSDRC_LPR]
431 * SDRAMC Memory controller
434 tst r0, #SRAMC_SELF_FRESH_ACTIVE
437 /* Active SDRAMC self-refresh mode */
438 ldr r3, [r2, #AT91_SDRAMC_LPR]
439 str r3, .saved_sam9_lpr
440 bic r3, r3, #AT91_SDRAMC_LPCB
441 orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
442 str r3, [r2, #AT91_SDRAMC_LPR]
445 ldr r3, .saved_sam9_lpr
446 str r3, [r2, #AT91_SDRAMC_LPR]
450 ENDPROC(at91_sramc_self_refresh)
479 ENTRY(at91_pm_suspend_in_sram_sz)
480 .word .-at91_pm_suspend_in_sram