1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * arch/arm/mach-at91/pm_slow_clock.S
5 * Copyright (C) 2006 Savin Zlobec
8 * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
10 #include <linux/linkage.h>
11 #include <linux/clk/at91_pmc.h>
13 #include "pm_data-offsets.h"
15 #define SRAMC_SELF_FRESH_ACTIVE 0x01
16 #define SRAMC_SELF_FRESH_EXIT 0x00
24 * Wait until master clock is ready (after switching master clock source)
27 1: ldr tmp1, [pmc, #AT91_PMC_SR]
28 tst tmp1, #AT91_PMC_MCKRDY
33 * Wait until master oscillator has stabilized.
36 1: ldr tmp1, [pmc, #AT91_PMC_SR]
37 tst tmp1, #AT91_PMC_MOSCS
42 * Wait for main oscillator selection is done
45 1: ldr tmp1, [pmc, #AT91_PMC_SR]
46 tst tmp1, #AT91_PMC_MOSCSELS
51 * Put the processor to enter the idle state
55 #if defined(CONFIG_CPU_V7)
56 mov tmp1, #AT91_PMC_PCK
57 str tmp1, [pmc, #AT91_PMC_SCDR]
61 wfi @ Wait For Interrupt
63 mcr p15, 0, tmp1, c7, c0, 4
73 * void at91_suspend_sram_fn(struct at91_pm_data*)
75 * @r0: base address of struct at91_pm_data
77 /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
79 ENTRY(at91_pm_suspend_in_sram)
80 /* Save registers on stack */
81 stmfd sp!, {r4 - r12, lr}
83 /* Drain write buffer */
85 mcr p15, 0, tmp1, c7, c10, 4
87 ldr tmp1, [r0, #PM_DATA_PMC]
89 ldr tmp1, [r0, #PM_DATA_RAMC0]
91 ldr tmp1, [r0, #PM_DATA_RAMC1]
92 str tmp1, .sramc1_base
93 ldr tmp1, [r0, #PM_DATA_MEMCTRL]
95 ldr tmp1, [r0, #PM_DATA_MODE]
97 ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
98 str tmp1, .mckr_offset
99 ldr tmp1, [r0, #PM_DATA_PMC_VERSION]
100 str tmp1, .pmc_version
101 /* Both ldrne below are here to preload their address in the TLB */
102 ldr tmp1, [r0, #PM_DATA_SHDWC]
105 ldrne tmp2, [tmp1, #0]
106 ldr tmp1, [r0, #PM_DATA_SFRBU]
109 ldrne tmp2, [tmp1, #0x10]
111 /* Active the self-refresh mode */
112 mov r0, #SRAMC_SELF_FRESH_ACTIVE
113 bl at91_sramc_self_refresh
116 cmp r0, #AT91_PM_STANDBY
118 cmp r0, #AT91_PM_BACKUP
125 /* Wait for interrupt */
135 /* Exit the self-refresh mode */
136 mov r0, #SRAMC_SELF_FRESH_EXIT
137 bl at91_sramc_self_refresh
139 /* Restore registers, and return */
140 ldmfd sp!, {r4 - r12, pc}
141 ENDPROC(at91_pm_suspend_in_sram)
143 ENTRY(at91_backup_mode)
144 /* Switch the master clock source to slow clock. */
146 ldr tmp2, .mckr_offset
147 ldr tmp1, [pmc, tmp2]
148 bic tmp1, tmp1, #AT91_PMC_CSS
149 str tmp1, [pmc, tmp2]
156 str tmp1, [r0, #0x10]
160 mov tmp1, #0xA5000000
163 ENDPROC(at91_backup_mode)
165 .macro at91_pm_ulp0_mode
168 /* Turn off the crystal oscillator */
169 ldr tmp1, [pmc, #AT91_CKGR_MOR]
170 bic tmp1, tmp1, #AT91_PMC_MOSCEN
171 orr tmp1, tmp1, #AT91_PMC_KEY
172 str tmp1, [pmc, #AT91_CKGR_MOR]
174 /* Save RC oscillator state */
175 ldr tmp1, [pmc, #AT91_PMC_SR]
176 str tmp1, .saved_osc_status
177 tst tmp1, #AT91_PMC_MOSCRCS
180 /* Turn off RC oscillator */
181 ldr tmp1, [pmc, #AT91_CKGR_MOR]
182 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
183 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
184 orr tmp1, tmp1, #AT91_PMC_KEY
185 str tmp1, [pmc, #AT91_CKGR_MOR]
187 /* Wait main RC disabled done */
188 2: ldr tmp1, [pmc, #AT91_PMC_SR]
189 tst tmp1, #AT91_PMC_MOSCRCS
192 /* Wait for interrupt */
195 /* Restore RC oscillator state */
196 ldr tmp1, .saved_osc_status
197 tst tmp1, #AT91_PMC_MOSCRCS
200 /* Turn on RC oscillator */
201 ldr tmp1, [pmc, #AT91_CKGR_MOR]
202 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
203 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
204 orr tmp1, tmp1, #AT91_PMC_KEY
205 str tmp1, [pmc, #AT91_CKGR_MOR]
207 /* Wait main RC stabilization */
208 3: ldr tmp1, [pmc, #AT91_PMC_SR]
209 tst tmp1, #AT91_PMC_MOSCRCS
212 /* Turn on the crystal oscillator */
213 4: ldr tmp1, [pmc, #AT91_CKGR_MOR]
214 orr tmp1, tmp1, #AT91_PMC_MOSCEN
215 orr tmp1, tmp1, #AT91_PMC_KEY
216 str tmp1, [pmc, #AT91_CKGR_MOR]
222 * Note: This procedure only applies on the platform which uses
223 * the external crystal oscillator as a main clock source.
225 .macro at91_pm_ulp1_mode
227 ldr tmp2, .mckr_offset
229 /* Save RC oscillator state and check if it is enabled. */
230 ldr tmp1, [pmc, #AT91_PMC_SR]
231 str tmp1, .saved_osc_status
232 tst tmp1, #AT91_PMC_MOSCRCS
235 /* Enable RC oscillator */
236 ldr tmp1, [pmc, #AT91_CKGR_MOR]
237 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
238 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
239 orr tmp1, tmp1, #AT91_PMC_KEY
240 str tmp1, [pmc, #AT91_CKGR_MOR]
242 /* Wait main RC stabilization */
243 1: ldr tmp1, [pmc, #AT91_PMC_SR]
244 tst tmp1, #AT91_PMC_MOSCRCS
247 /* Switch the main clock source to 12-MHz RC oscillator */
248 2: ldr tmp1, [pmc, #AT91_CKGR_MOR]
249 bic tmp1, tmp1, #AT91_PMC_MOSCSEL
250 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
251 orr tmp1, tmp1, #AT91_PMC_KEY
252 str tmp1, [pmc, #AT91_CKGR_MOR]
256 /* Disable the crystal oscillator */
257 ldr tmp1, [pmc, #AT91_CKGR_MOR]
258 bic tmp1, tmp1, #AT91_PMC_MOSCEN
259 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
260 orr tmp1, tmp1, #AT91_PMC_KEY
261 str tmp1, [pmc, #AT91_CKGR_MOR]
263 /* Switch the master clock source to main clock */
264 ldr tmp1, [pmc, tmp2]
265 bic tmp1, tmp1, #AT91_PMC_CSS
266 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
267 str tmp1, [pmc, tmp2]
271 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
272 ldr tmp1, [pmc, #AT91_CKGR_MOR]
273 orr tmp1, tmp1, #AT91_PMC_WAITMODE
274 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
275 orr tmp1, tmp1, #AT91_PMC_KEY
276 str tmp1, [pmc, #AT91_CKGR_MOR]
278 /* Quirk for SAM9X60's PMC */
284 /* Enable the crystal oscillator */
285 ldr tmp1, [pmc, #AT91_CKGR_MOR]
286 orr tmp1, tmp1, #AT91_PMC_MOSCEN
287 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
288 orr tmp1, tmp1, #AT91_PMC_KEY
289 str tmp1, [pmc, #AT91_CKGR_MOR]
293 /* Switch the master clock source to slow clock */
294 ldr tmp1, [pmc, tmp2]
295 bic tmp1, tmp1, #AT91_PMC_CSS
296 str tmp1, [pmc, tmp2]
300 /* Switch main clock source to crystal oscillator */
301 ldr tmp1, [pmc, #AT91_CKGR_MOR]
302 orr tmp1, tmp1, #AT91_PMC_MOSCSEL
303 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
304 orr tmp1, tmp1, #AT91_PMC_KEY
305 str tmp1, [pmc, #AT91_CKGR_MOR]
309 /* Switch the master clock source to main clock */
310 ldr tmp1, [pmc, tmp2]
311 bic tmp1, tmp1, #AT91_PMC_CSS
312 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
313 str tmp1, [pmc, tmp2]
317 /* Restore RC oscillator state */
318 ldr tmp1, .saved_osc_status
319 tst tmp1, #AT91_PMC_MOSCRCS
322 /* Disable RC oscillator */
323 ldr tmp1, [pmc, #AT91_CKGR_MOR]
324 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
325 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
326 orr tmp1, tmp1, #AT91_PMC_KEY
327 str tmp1, [pmc, #AT91_CKGR_MOR]
329 /* Wait RC oscillator disable done */
330 4: ldr tmp1, [pmc, #AT91_PMC_SR]
331 tst tmp1, #AT91_PMC_MOSCRCS
337 .macro at91_plla_disable
338 /* Save PLLA setting and disable it */
339 ldr tmp1, .pmc_version
340 cmp tmp1, #AT91_PMC_V1
343 #ifdef CONFIG_SOC_SAM9X60
344 /* Save PLLA settings. */
345 ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT]
346 bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID
347 str tmp2, [pmc, #AT91_PMC_PLL_UPDT]
351 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
352 bic tmp2, tmp2, #0xffffff00
356 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1]
357 bic tmp2, tmp2, #0xffffff
359 str tmp1, .saved_pllar
362 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
363 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
364 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
365 str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
368 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
369 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
370 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
371 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
374 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
375 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
376 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
377 str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
380 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
381 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
382 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
385 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
386 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
387 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
388 str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
393 1: /* Save PLLA setting and disable it */
394 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
395 str tmp1, .saved_pllar
398 mov tmp1, #AT91_PMC_PLLCOUNT
399 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
400 str tmp1, [pmc, #AT91_CKGR_PLLAR]
404 .macro at91_plla_enable
405 ldr tmp2, .saved_pllar
406 ldr tmp3, .pmc_version
407 cmp tmp3, #AT91_PMC_V1
410 #ifdef CONFIG_SOC_SAM9X60
412 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
413 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
414 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
415 str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
418 ldr tmp1, =#AT91_PMC_PLL_ACR_DEFAULT_PLLA
419 str tmp1, [pmc, #AT91_PMC_PLL_ACR]
422 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
424 bic tmp3, tmp3, #0xffffff
426 str tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
429 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
430 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
431 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
432 str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
435 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
436 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK
437 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
438 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
439 bic tmp1, tmp1, #0xff
441 bic tmp3, tmp3, #0xffffff00
443 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
446 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
447 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
448 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
449 str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
452 3: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0]
458 /* Restore PLLA setting */
459 4: str tmp2, [pmc, #AT91_CKGR_PLLAR]
462 tst tmp2, #(AT91_PMC_MUL & 0xff0000)
464 tst tmp2, #(AT91_PMC_MUL & ~0xff0000)
467 1: ldr tmp1, [pmc, #AT91_PMC_SR]
468 tst tmp1, #AT91_PMC_LOCKA
475 ldr tmp2, .mckr_offset
477 /* Save Master clock setting */
478 ldr tmp1, [pmc, tmp2]
479 str tmp1, .saved_mckr
482 * Set the Master clock source to slow clock
484 bic tmp1, tmp1, #AT91_PMC_CSS
485 str tmp1, [pmc, tmp2]
492 cmp r0, #AT91_PM_ULP1
508 * Restore master clock setting
510 ldr tmp1, .mckr_offset
511 ldr tmp2, .saved_mckr
512 str tmp2, [pmc, tmp1]
517 ENDPROC(at91_ulp_mode)
520 * void at91_sramc_self_refresh(unsigned int is_active)
523 * @r0: 1 - active self-refresh mode
524 * 0 - exit self-refresh mode
527 * @r2: base address of the sram controller
530 ENTRY(at91_sramc_self_refresh)
534 cmp r1, #AT91_MEMCTRL_MC
538 * at91rm9200 Memory controller
542 * For exiting the self-refresh mode, do nothing,
543 * automatically exit the self-refresh mode.
545 tst r0, #SRAMC_SELF_FRESH_ACTIVE
548 /* Active SDRAM self-refresh mode */
550 str r3, [r2, #AT91_MC_SDRAMC_SRR]
554 cmp r1, #AT91_MEMCTRL_DDRSDR
558 * DDR Memory controller
560 tst r0, #SRAMC_SELF_FRESH_ACTIVE
563 /* LPDDR1 --> force DDR2 mode during self-refresh */
564 ldr r3, [r2, #AT91_DDRSDRC_MDR]
565 str r3, .saved_sam9_mdr
566 bic r3, r3, #~AT91_DDRSDRC_MD
567 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
568 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
569 biceq r3, r3, #AT91_DDRSDRC_MD
570 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
571 streq r3, [r2, #AT91_DDRSDRC_MDR]
573 /* Active DDRC self-refresh mode */
574 ldr r3, [r2, #AT91_DDRSDRC_LPR]
575 str r3, .saved_sam9_lpr
576 bic r3, r3, #AT91_DDRSDRC_LPCB
577 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
578 str r3, [r2, #AT91_DDRSDRC_LPR]
580 /* If using the 2nd ddr controller */
585 ldr r3, [r2, #AT91_DDRSDRC_MDR]
586 str r3, .saved_sam9_mdr1
587 bic r3, r3, #~AT91_DDRSDRC_MD
588 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
589 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
590 biceq r3, r3, #AT91_DDRSDRC_MD
591 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
592 streq r3, [r2, #AT91_DDRSDRC_MDR]
594 /* Active DDRC self-refresh mode */
595 ldr r3, [r2, #AT91_DDRSDRC_LPR]
596 str r3, .saved_sam9_lpr1
597 bic r3, r3, #AT91_DDRSDRC_LPCB
598 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
599 str r3, [r2, #AT91_DDRSDRC_LPR]
605 /* Restore MDR in case of LPDDR1 */
606 ldr r3, .saved_sam9_mdr
607 str r3, [r2, #AT91_DDRSDRC_MDR]
608 /* Restore LPR on AT91 with DDRAM */
609 ldr r3, .saved_sam9_lpr
610 str r3, [r2, #AT91_DDRSDRC_LPR]
612 /* If using the 2nd ddr controller */
615 ldrne r3, .saved_sam9_mdr1
616 strne r3, [r2, #AT91_DDRSDRC_MDR]
617 ldrne r3, .saved_sam9_lpr1
618 strne r3, [r2, #AT91_DDRSDRC_LPR]
623 * SDRAMC Memory controller
626 tst r0, #SRAMC_SELF_FRESH_ACTIVE
629 /* Active SDRAMC self-refresh mode */
630 ldr r3, [r2, #AT91_SDRAMC_LPR]
631 str r3, .saved_sam9_lpr
632 bic r3, r3, #AT91_SDRAMC_LPCB
633 orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
634 str r3, [r2, #AT91_SDRAMC_LPR]
637 ldr r3, .saved_sam9_lpr
638 str r3, [r2, #AT91_SDRAMC_LPR]
642 ENDPROC(at91_sramc_self_refresh)
677 ENTRY(at91_pm_suspend_in_sram_sz)
678 .word .-at91_pm_suspend_in_sram