Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * arch/arm/mach-at91/pm_slow_clock.S
0004  *
0005  *  Copyright (C) 2006 Savin Zlobec
0006  *
0007  * AT91SAM9 support:
0008  *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
0009  */
0010 #include <linux/linkage.h>
0011 #include <linux/clk/at91_pmc.h>
0012 #include "pm.h"
0013 #include "pm_data-offsets.h"
0014 
0015 #define SRAMC_SELF_FRESH_ACTIVE     0x01
0016 #define SRAMC_SELF_FRESH_EXIT       0x00
0017 
0018 pmc .req    r0
0019 tmp1    .req    r4
0020 tmp2    .req    r5
0021 tmp3    .req    r6
0022 
0023 /*
0024  * Wait until master clock is ready (after switching master clock source)
0025  *
0026  * @r_mckid:    register holding master clock identifier
0027  *
0028  * Side effects: overwrites r7, r8
0029  */
0030     .macro wait_mckrdy r_mckid
0031 #ifdef CONFIG_SOC_SAMA7
0032     cmp \r_mckid, #0
0033     beq 1f
0034     mov r7, #AT91_PMC_MCKXRDY
0035     b   2f
0036 #endif
0037 1:  mov r7, #AT91_PMC_MCKRDY
0038 2:  ldr r8, [pmc, #AT91_PMC_SR]
0039     and r8, r7
0040     cmp r8, r7
0041     bne 2b
0042     .endm
0043 
0044 /*
0045  * Wait until master oscillator has stabilized.
0046  *
0047  * Side effects: overwrites r7
0048  */
0049     .macro wait_moscrdy
0050 1:  ldr r7, [pmc, #AT91_PMC_SR]
0051     tst r7, #AT91_PMC_MOSCS
0052     beq 1b
0053     .endm
0054 
0055 /*
0056  * Wait for main oscillator selection is done
0057  *
0058  * Side effects: overwrites r7
0059  */
0060     .macro wait_moscsels
0061 1:  ldr r7, [pmc, #AT91_PMC_SR]
0062     tst r7, #AT91_PMC_MOSCSELS
0063     beq 1b
0064     .endm
0065 
0066 /*
0067  * Put the processor to enter the idle state
0068  *
0069  * Side effects: overwrites r7
0070  */
0071     .macro at91_cpu_idle
0072 
0073 #if defined(CONFIG_CPU_V7)
0074     mov r7, #AT91_PMC_PCK
0075     str r7, [pmc, #AT91_PMC_SCDR]
0076 
0077     dsb
0078 
0079     wfi     @ Wait For Interrupt
0080 #else
0081     mcr p15, 0, tmp1, c7, c0, 4
0082 #endif
0083 
0084     .endm
0085 
0086 /**
0087  * Set state for 2.5V low power regulator
0088  * @ena: 0 - disable regulator
0089  *   1 - enable regulator
0090  *
0091  * Side effects: overwrites r7, r8, r9, r10
0092  */
0093     .macro at91_2_5V_reg_set_low_power ena
0094 #ifdef CONFIG_SOC_SAMA7
0095     ldr r7, .sfrbu
0096     mov r8, #\ena
0097     ldr r9, [r7, #AT91_SFRBU_25LDOCR]
0098     orr r9, r9, #AT91_SFRBU_25LDOCR_LP
0099     cmp r8, #1
0100     beq lp_done_\ena
0101     bic r9, r9, #AT91_SFRBU_25LDOCR_LP
0102 lp_done_\ena:
0103     ldr r10, =AT91_SFRBU_25LDOCR_LDOANAKEY
0104     orr r9, r9, r10
0105     str r9, [r7, #AT91_SFRBU_25LDOCR]
0106 #endif
0107     .endm
0108 
0109     .macro at91_backup_set_lpm reg
0110 #ifdef CONFIG_SOC_SAMA7
0111     orr \reg, \reg, #0x200000
0112 #endif
0113     .endm
0114 
0115     .text
0116 
0117     .arm
0118 
0119 #ifdef CONFIG_SOC_SAMA7
0120 /**
0121  * Enable self-refresh
0122  *
0123  * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3, r7
0124  */
0125 .macro at91_sramc_self_refresh_ena
0126     ldr r2, .sramc_base
0127     ldr r3, .sramc_phy_base
0128     ldr r7, .pm_mode
0129 
0130     dsb
0131 
0132     /* Disable all AXI ports. */
0133     ldr tmp1, [r2, #UDDRC_PCTRL_0]
0134     bic tmp1, tmp1, #0x1
0135     str tmp1, [r2, #UDDRC_PCTRL_0]
0136 
0137     ldr tmp1, [r2, #UDDRC_PCTRL_1]
0138     bic tmp1, tmp1, #0x1
0139     str tmp1, [r2, #UDDRC_PCTRL_1]
0140 
0141     ldr tmp1, [r2, #UDDRC_PCTRL_2]
0142     bic tmp1, tmp1, #0x1
0143     str tmp1, [r2, #UDDRC_PCTRL_2]
0144 
0145     ldr tmp1, [r2, #UDDRC_PCTRL_3]
0146     bic tmp1, tmp1, #0x1
0147     str tmp1, [r2, #UDDRC_PCTRL_3]
0148 
0149     ldr tmp1, [r2, #UDDRC_PCTRL_4]
0150     bic tmp1, tmp1, #0x1
0151     str tmp1, [r2, #UDDRC_PCTRL_4]
0152 
0153 sr_ena_1:
0154     /* Wait for all ports to disable. */
0155     ldr tmp1, [r2, #UDDRC_PSTAT]
0156     ldr tmp2, =UDDRC_PSTAT_ALL_PORTS
0157     tst tmp1, tmp2
0158     bne sr_ena_1
0159 
0160     /* Switch to self-refresh. */
0161     ldr tmp1, [r2, #UDDRC_PWRCTL]
0162     orr tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
0163     str tmp1, [r2, #UDDRC_PWRCTL]
0164 
0165 sr_ena_2:
0166     /* Wait for self-refresh enter. */
0167     ldr tmp1, [r2, #UDDRC_STAT]
0168     bic tmp1, tmp1, #~UDDRC_STAT_SELFREF_TYPE_MSK
0169     cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW
0170     bne sr_ena_2
0171 
0172     /* Put DDR PHY's DLL in bypass mode for non-backup modes. */
0173     cmp r7, #AT91_PM_BACKUP
0174     beq sr_ena_3
0175 
0176     /* Disable DX DLLs. */
0177     ldr tmp1, [r3, #DDR3PHY_DX0DLLCR]
0178     orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
0179     str tmp1, [r3, #DDR3PHY_DX0DLLCR]
0180 
0181     ldr tmp1, [r3, #DDR3PHY_DX1DLLCR]
0182     orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
0183     str tmp1, [r3, #DDR3PHY_DX1DLLCR]
0184 
0185 sr_ena_3:
0186     /* Power down DDR PHY data receivers. */
0187     ldr tmp1, [r3, #DDR3PHY_DXCCR]
0188     orr tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR
0189     str tmp1, [r3, #DDR3PHY_DXCCR]
0190 
0191     /* Power down ADDR/CMD IO. */
0192     ldr tmp1, [r3, #DDR3PHY_ACIOCR]
0193     orr tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD
0194     orr tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0
0195     orr tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0
0196     str tmp1, [r3, #DDR3PHY_ACIOCR]
0197 
0198     /* Power down ODT. */
0199     ldr tmp1, [r3, #DDR3PHY_DSGCR]
0200     orr tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0
0201     str tmp1, [r3, #DDR3PHY_DSGCR]
0202 .endm
0203 
0204 /**
0205  * Disable self-refresh
0206  *
0207  * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3
0208  */
0209 .macro at91_sramc_self_refresh_dis
0210     ldr r2, .sramc_base
0211     ldr r3, .sramc_phy_base
0212 
0213     /* Power up DDR PHY data receivers. */
0214     ldr tmp1, [r3, #DDR3PHY_DXCCR]
0215     bic tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR
0216     str tmp1, [r3, #DDR3PHY_DXCCR]
0217 
0218     /* Power up the output of CK and CS pins. */
0219     ldr tmp1, [r3, #DDR3PHY_ACIOCR]
0220     bic tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD
0221     bic tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0
0222     bic tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0
0223     str tmp1, [r3, #DDR3PHY_ACIOCR]
0224 
0225     /* Power up ODT. */
0226     ldr tmp1, [r3, #DDR3PHY_DSGCR]
0227     bic tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0
0228     str tmp1, [r3, #DDR3PHY_DSGCR]
0229 
0230     /* Enable DX DLLs. */
0231     ldr tmp1, [r3, #DDR3PHY_DX0DLLCR]
0232     bic tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
0233     str tmp1, [r3, #DDR3PHY_DX0DLLCR]
0234 
0235     ldr tmp1, [r3, #DDR3PHY_DX1DLLCR]
0236     bic tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
0237     str tmp1, [r3, #DDR3PHY_DX1DLLCR]
0238 
0239     /* Enable quasi-dynamic programming. */
0240     mov tmp1, #0
0241     str tmp1, [r2, #UDDRC_SWCTRL]
0242 
0243     /* De-assert SDRAM initialization. */
0244     ldr tmp1, [r2, #UDDRC_DFIMISC]
0245     bic tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN
0246     str tmp1, [r2, #UDDRC_DFIMISC]
0247 
0248     /* Quasi-dynamic programming done. */
0249     mov tmp1, #UDDRC_SWCTRL_SW_DONE
0250     str tmp1, [r2, #UDDRC_SWCTRL]
0251 
0252 sr_dis_1:
0253     ldr tmp1, [r2, #UDDRC_SWSTAT]
0254     tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK
0255     beq sr_dis_1
0256 
0257     /* DLL soft-reset + DLL lock wait + ITM reset */
0258     mov tmp1, #(DDR3PHY_PIR_INIT | DDR3PHY_PIR_DLLSRST | \
0259             DDR3PHY_PIR_DLLLOCK | DDR3PHY_PIR_ITMSRST)
0260     str tmp1, [r3, #DDR3PHY_PIR]
0261 
0262 sr_dis_4:
0263     /* Wait for it. */
0264     ldr tmp1, [r3, #DDR3PHY_PGSR]
0265     tst tmp1, #DDR3PHY_PGSR_IDONE
0266     beq sr_dis_4
0267 
0268     /* Enable quasi-dynamic programming. */
0269     mov tmp1, #0
0270     str tmp1, [r2, #UDDRC_SWCTRL]
0271 
0272     /* Assert PHY init complete enable signal. */
0273     ldr tmp1, [r2, #UDDRC_DFIMISC]
0274     orr tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN
0275     str tmp1, [r2, #UDDRC_DFIMISC]
0276 
0277     /* Programming is done. Set sw_done. */
0278     mov tmp1, #UDDRC_SWCTRL_SW_DONE
0279     str tmp1, [r2, #UDDRC_SWCTRL]
0280 
0281 sr_dis_5:
0282     /* Wait for it. */
0283     ldr tmp1, [r2, #UDDRC_SWSTAT]
0284     tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK
0285     beq sr_dis_5
0286 
0287     /* Trigger self-refresh exit. */
0288     ldr tmp1, [r2, #UDDRC_PWRCTL]
0289     bic tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
0290     str tmp1, [r2, #UDDRC_PWRCTL]
0291 
0292 sr_dis_6:
0293     /* Wait for self-refresh exit done. */
0294     ldr tmp1, [r2, #UDDRC_STAT]
0295     bic tmp1, tmp1, #~UDDRC_STAT_OPMODE_MSK
0296     cmp tmp1, #UDDRC_STAT_OPMODE_NORMAL
0297     bne sr_dis_6
0298 
0299     /* Enable all AXI ports. */
0300     ldr tmp1, [r2, #UDDRC_PCTRL_0]
0301     orr tmp1, tmp1, #0x1
0302     str tmp1, [r2, #UDDRC_PCTRL_0]
0303 
0304     ldr tmp1, [r2, #UDDRC_PCTRL_1]
0305     orr tmp1, tmp1, #0x1
0306     str tmp1, [r2, #UDDRC_PCTRL_1]
0307 
0308     ldr tmp1, [r2, #UDDRC_PCTRL_2]
0309     orr tmp1, tmp1, #0x1
0310     str tmp1, [r2, #UDDRC_PCTRL_2]
0311 
0312     ldr tmp1, [r2, #UDDRC_PCTRL_3]
0313     orr tmp1, tmp1, #0x1
0314     str tmp1, [r2, #UDDRC_PCTRL_3]
0315 
0316     ldr tmp1, [r2, #UDDRC_PCTRL_4]
0317     orr tmp1, tmp1, #0x1
0318     str tmp1, [r2, #UDDRC_PCTRL_4]
0319 
0320     dsb
0321 .endm
0322 #else
0323 /**
0324  * Enable self-refresh
0325  *
0326  * register usage:
0327  *  @r1: memory type
0328  *  @r2: base address of the sram controller
0329  *  @r3: temporary
0330  */
0331 .macro at91_sramc_self_refresh_ena
0332     ldr r1, .memtype
0333     ldr r2, .sramc_base
0334 
0335     cmp r1, #AT91_MEMCTRL_MC
0336     bne sr_ena_ddrc_sf
0337 
0338     /* Active SDRAM self-refresh mode */
0339     mov r3, #1
0340     str r3, [r2, #AT91_MC_SDRAMC_SRR]
0341     b   sr_ena_exit
0342 
0343 sr_ena_ddrc_sf:
0344     cmp r1, #AT91_MEMCTRL_DDRSDR
0345     bne sr_ena_sdramc_sf
0346 
0347     /*
0348      * DDR Memory controller
0349      */
0350 
0351     /* LPDDR1 --> force DDR2 mode during self-refresh */
0352     ldr r3, [r2, #AT91_DDRSDRC_MDR]
0353     str r3, .saved_sam9_mdr
0354     bic r3, r3, #~AT91_DDRSDRC_MD
0355     cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
0356     ldreq   r3, [r2, #AT91_DDRSDRC_MDR]
0357     biceq   r3, r3, #AT91_DDRSDRC_MD
0358     orreq   r3, r3, #AT91_DDRSDRC_MD_DDR2
0359     streq   r3, [r2, #AT91_DDRSDRC_MDR]
0360 
0361     /* Active DDRC self-refresh mode */
0362     ldr r3, [r2, #AT91_DDRSDRC_LPR]
0363     str r3, .saved_sam9_lpr
0364     bic r3, r3, #AT91_DDRSDRC_LPCB
0365     orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
0366     str r3, [r2, #AT91_DDRSDRC_LPR]
0367 
0368     /* If using the 2nd ddr controller */
0369     ldr r2, .sramc1_base
0370     cmp r2, #0
0371     beq sr_ena_no_2nd_ddrc
0372 
0373     ldr r3, [r2, #AT91_DDRSDRC_MDR]
0374     str r3, .saved_sam9_mdr1
0375     bic r3, r3, #~AT91_DDRSDRC_MD
0376     cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
0377     ldreq   r3, [r2, #AT91_DDRSDRC_MDR]
0378     biceq   r3, r3, #AT91_DDRSDRC_MD
0379     orreq   r3, r3, #AT91_DDRSDRC_MD_DDR2
0380     streq   r3, [r2, #AT91_DDRSDRC_MDR]
0381 
0382     /* Active DDRC self-refresh mode */
0383     ldr r3, [r2, #AT91_DDRSDRC_LPR]
0384     str r3, .saved_sam9_lpr1
0385     bic r3, r3, #AT91_DDRSDRC_LPCB
0386     orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
0387     str r3, [r2, #AT91_DDRSDRC_LPR]
0388 
0389 sr_ena_no_2nd_ddrc:
0390     b   sr_ena_exit
0391 
0392     /*
0393      * SDRAMC Memory controller
0394      */
0395 sr_ena_sdramc_sf:
0396     /* Active SDRAMC self-refresh mode */
0397     ldr r3, [r2, #AT91_SDRAMC_LPR]
0398     str r3, .saved_sam9_lpr
0399     bic r3, r3, #AT91_SDRAMC_LPCB
0400     orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
0401     str r3, [r2, #AT91_SDRAMC_LPR]
0402 
0403     ldr r3, .saved_sam9_lpr
0404     str r3, [r2, #AT91_SDRAMC_LPR]
0405 
0406 sr_ena_exit:
0407 .endm
0408 
0409 /**
0410  * Disable self-refresh
0411  *
0412  * register usage:
0413  *  @r1: memory type
0414  *  @r2: base address of the sram controller
0415  *  @r3: temporary
0416  */
0417 .macro at91_sramc_self_refresh_dis
0418     ldr r1, .memtype
0419     ldr r2, .sramc_base
0420 
0421     cmp r1, #AT91_MEMCTRL_MC
0422     bne sr_dis_ddrc_exit_sf
0423 
0424     /*
0425      * at91rm9200 Memory controller
0426      */
0427 
0428      /*
0429       * For exiting the self-refresh mode, do nothing,
0430       * automatically exit the self-refresh mode.
0431       */
0432     b   sr_dis_exit
0433 
0434 sr_dis_ddrc_exit_sf:
0435     cmp r1, #AT91_MEMCTRL_DDRSDR
0436     bne sdramc_exit_sf
0437 
0438     /* DDR Memory controller */
0439 
0440     /* Restore MDR in case of LPDDR1 */
0441     ldr r3, .saved_sam9_mdr
0442     str r3, [r2, #AT91_DDRSDRC_MDR]
0443     /* Restore LPR on AT91 with DDRAM */
0444     ldr r3, .saved_sam9_lpr
0445     str r3, [r2, #AT91_DDRSDRC_LPR]
0446 
0447     /* If using the 2nd ddr controller */
0448     ldr r2, .sramc1_base
0449     cmp r2, #0
0450     ldrne   r3, .saved_sam9_mdr1
0451     strne   r3, [r2, #AT91_DDRSDRC_MDR]
0452     ldrne   r3, .saved_sam9_lpr1
0453     strne   r3, [r2, #AT91_DDRSDRC_LPR]
0454 
0455     b   sr_dis_exit
0456 
0457 sdramc_exit_sf:
0458     /* SDRAMC Memory controller */
0459     ldr r3, .saved_sam9_lpr
0460     str r3, [r2, #AT91_SDRAMC_LPR]
0461 
0462 sr_dis_exit:
0463 .endm
0464 #endif
0465 
0466 .macro at91_pm_ulp0_mode
0467     ldr pmc, .pmc_base
0468     ldr tmp2, .pm_mode
0469     ldr tmp3, .mckr_offset
0470 
0471     /* Check if ULP0 fast variant has been requested. */
0472     cmp tmp2, #AT91_PM_ULP0_FAST
0473     bne 0f
0474 
0475     /* Set highest prescaler for power saving */
0476     ldr tmp1, [pmc, tmp3]
0477     bic tmp1, tmp1, #AT91_PMC_PRES
0478     orr tmp1, tmp1, #AT91_PMC_PRES_64
0479     str tmp1, [pmc, tmp3]
0480 
0481     mov tmp3, #0
0482     wait_mckrdy tmp3
0483     b   1f
0484 
0485 0:
0486     /* Turn off the crystal oscillator */
0487     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0488     bic tmp1, tmp1, #AT91_PMC_MOSCEN
0489     orr tmp1, tmp1, #AT91_PMC_KEY
0490     str tmp1, [pmc, #AT91_CKGR_MOR]
0491 
0492     /* Save RC oscillator state */
0493     ldr tmp1, [pmc, #AT91_PMC_SR]
0494     str tmp1, .saved_osc_status
0495     tst tmp1, #AT91_PMC_MOSCRCS
0496     bne 1f
0497 
0498     /* Turn off RC oscillator */
0499     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0500     bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
0501     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0502     orr tmp1, tmp1, #AT91_PMC_KEY
0503     str tmp1, [pmc, #AT91_CKGR_MOR]
0504 
0505     /* Wait main RC disabled done */
0506 2:  ldr tmp1, [pmc, #AT91_PMC_SR]
0507     tst tmp1, #AT91_PMC_MOSCRCS
0508     bne 2b
0509 
0510     /* Wait for interrupt */
0511 1:  at91_cpu_idle
0512 
0513     /* Check if ULP0 fast variant has been requested. */
0514     cmp tmp2, #AT91_PM_ULP0_FAST
0515     bne 5f
0516 
0517     /* Set lowest prescaler for fast resume. */
0518     ldr tmp3, .mckr_offset
0519     ldr tmp1, [pmc, tmp3]
0520     bic tmp1, tmp1, #AT91_PMC_PRES
0521     str tmp1, [pmc, tmp3]
0522 
0523     mov tmp3, #0
0524     wait_mckrdy tmp3
0525     b   6f
0526 
0527 5:  /* Restore RC oscillator state */
0528     ldr tmp1, .saved_osc_status
0529     tst tmp1, #AT91_PMC_MOSCRCS
0530     beq 4f
0531 
0532     /* Turn on RC oscillator */
0533     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0534     orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
0535     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0536     orr tmp1, tmp1, #AT91_PMC_KEY
0537     str tmp1, [pmc, #AT91_CKGR_MOR]
0538 
0539     /* Wait main RC stabilization */
0540 3:  ldr tmp1, [pmc, #AT91_PMC_SR]
0541     tst tmp1, #AT91_PMC_MOSCRCS
0542     beq 3b
0543 
0544     /* Turn on the crystal oscillator */
0545 4:  ldr tmp1, [pmc, #AT91_CKGR_MOR]
0546     orr tmp1, tmp1, #AT91_PMC_MOSCEN
0547     orr tmp1, tmp1, #AT91_PMC_KEY
0548     str tmp1, [pmc, #AT91_CKGR_MOR]
0549 
0550     wait_moscrdy
0551 6:
0552 .endm
0553 
0554 /**
0555  * Note: This procedure only applies on the platform which uses
0556  * the external crystal oscillator as a main clock source.
0557  */
0558 .macro at91_pm_ulp1_mode
0559     ldr pmc, .pmc_base
0560     ldr tmp2, .mckr_offset
0561     mov tmp3, #0
0562 
0563     /* Save RC oscillator state and check if it is enabled. */
0564     ldr tmp1, [pmc, #AT91_PMC_SR]
0565     str tmp1, .saved_osc_status
0566     tst tmp1, #AT91_PMC_MOSCRCS
0567     bne 2f
0568 
0569     /* Enable RC oscillator */
0570     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0571     orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
0572     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0573     orr tmp1, tmp1, #AT91_PMC_KEY
0574     str tmp1, [pmc, #AT91_CKGR_MOR]
0575 
0576     /* Wait main RC stabilization */
0577 1:  ldr tmp1, [pmc, #AT91_PMC_SR]
0578     tst tmp1, #AT91_PMC_MOSCRCS
0579     beq 1b
0580 
0581     /* Switch the main clock source to 12-MHz RC oscillator */
0582 2:  ldr tmp1, [pmc, #AT91_CKGR_MOR]
0583     bic tmp1, tmp1, #AT91_PMC_MOSCSEL
0584     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0585     orr tmp1, tmp1, #AT91_PMC_KEY
0586     str tmp1, [pmc, #AT91_CKGR_MOR]
0587 
0588     wait_moscsels
0589 
0590     /* Disable the crystal oscillator */
0591     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0592     bic tmp1, tmp1, #AT91_PMC_MOSCEN
0593     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0594     orr tmp1, tmp1, #AT91_PMC_KEY
0595     str tmp1, [pmc, #AT91_CKGR_MOR]
0596 
0597     /* Switch the master clock source to main clock */
0598     ldr tmp1, [pmc, tmp2]
0599     bic tmp1, tmp1, #AT91_PMC_CSS
0600     orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
0601     str tmp1, [pmc, tmp2]
0602 
0603     wait_mckrdy tmp3
0604 
0605     /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
0606     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0607     orr tmp1, tmp1, #AT91_PMC_WAITMODE
0608     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0609     orr tmp1, tmp1, #AT91_PMC_KEY
0610     str tmp1, [pmc, #AT91_CKGR_MOR]
0611 
0612     /* Quirk for SAM9X60's PMC */
0613     nop
0614     nop
0615 
0616     wait_mckrdy tmp3
0617 
0618     /* Enable the crystal oscillator */
0619     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0620     orr tmp1, tmp1, #AT91_PMC_MOSCEN
0621     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0622     orr tmp1, tmp1, #AT91_PMC_KEY
0623     str tmp1, [pmc, #AT91_CKGR_MOR]
0624 
0625     wait_moscrdy
0626 
0627     /* Switch the master clock source to slow clock */
0628     ldr tmp1, [pmc, tmp2]
0629     bic tmp1, tmp1, #AT91_PMC_CSS
0630     str tmp1, [pmc, tmp2]
0631 
0632     wait_mckrdy tmp3
0633 
0634     /* Switch main clock source to crystal oscillator */
0635     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0636     orr tmp1, tmp1, #AT91_PMC_MOSCSEL
0637     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0638     orr tmp1, tmp1, #AT91_PMC_KEY
0639     str tmp1, [pmc, #AT91_CKGR_MOR]
0640 
0641     wait_moscsels
0642 
0643     /* Switch the master clock source to main clock */
0644     ldr tmp1, [pmc, tmp2]
0645     bic tmp1, tmp1, #AT91_PMC_CSS
0646     orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
0647     str tmp1, [pmc, tmp2]
0648 
0649     wait_mckrdy tmp3
0650 
0651     /* Restore RC oscillator state */
0652     ldr tmp1, .saved_osc_status
0653     tst tmp1, #AT91_PMC_MOSCRCS
0654     bne 3f
0655 
0656     /* Disable RC oscillator */
0657     ldr tmp1, [pmc, #AT91_CKGR_MOR]
0658     bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
0659     bic tmp1, tmp1, #AT91_PMC_KEY_MASK
0660     orr tmp1, tmp1, #AT91_PMC_KEY
0661     str tmp1, [pmc, #AT91_CKGR_MOR]
0662 
0663     /* Wait RC oscillator disable done */
0664 4:  ldr tmp1, [pmc, #AT91_PMC_SR]
0665     tst tmp1, #AT91_PMC_MOSCRCS
0666     bne 4b
0667 
0668 3:
0669 .endm
0670 
0671 .macro at91_plla_disable
0672     /* Save PLLA setting and disable it */
0673     ldr tmp1, .pmc_version
0674     cmp tmp1, #AT91_PMC_V1
0675     beq 1f
0676 
0677 #ifdef CONFIG_HAVE_AT91_SAM9X60_PLL
0678     /* Save PLLA settings. */
0679     ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT]
0680     bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID
0681     str tmp2, [pmc, #AT91_PMC_PLL_UPDT]
0682 
0683     /* save div. */
0684     mov tmp1, #0
0685     ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
0686     bic tmp2, tmp2, #0xffffff00
0687     orr tmp1, tmp1, tmp2
0688 
0689     /* save mul. */
0690     ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1]
0691     bic tmp2, tmp2, #0xffffff
0692     orr tmp1, tmp1, tmp2
0693     str tmp1, .saved_pllar
0694 
0695     /* step 2. */
0696     ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0697     bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
0698     bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
0699     str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0700 
0701     /* step 3. */
0702     ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
0703     bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
0704     orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
0705     str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
0706 
0707     /* step 4. */
0708     ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0709     orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
0710     bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
0711     str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0712 
0713     /* step 5. */
0714     ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
0715     bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
0716     str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
0717 
0718     /* step 7. */
0719     ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0720     orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
0721     bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
0722     str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0723 
0724     b   2f
0725 #endif
0726 
0727 1:  /* Save PLLA setting and disable it */
0728     ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
0729     str tmp1, .saved_pllar
0730 
0731     /* Disable PLLA. */
0732     mov tmp1, #AT91_PMC_PLLCOUNT
0733     orr tmp1, tmp1, #(1 << 29)      /* bit 29 always set */
0734     str tmp1, [pmc, #AT91_CKGR_PLLAR]
0735 2:
0736 .endm
0737 
0738 .macro at91_plla_enable
0739     ldr tmp2, .saved_pllar
0740     ldr tmp3, .pmc_version
0741     cmp tmp3, #AT91_PMC_V1
0742     beq 4f
0743 
0744 #ifdef CONFIG_HAVE_AT91_SAM9X60_PLL
0745     /* step 1. */
0746     ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0747     bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
0748     bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
0749     str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0750 
0751     /* step 2. */
0752     ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA
0753     str tmp1, [pmc, #AT91_PMC_PLL_ACR]
0754 
0755     /* step 3. */
0756     ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
0757     mov tmp3, tmp2
0758     bic tmp3, tmp3, #0xffffff
0759     orr tmp1, tmp1, tmp3
0760     str tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
0761 
0762     /* step 8. */
0763     ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0764     bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
0765     orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
0766     str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0767 
0768     /* step 9. */
0769     ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
0770     orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK
0771     orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
0772     orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
0773     bic tmp1, tmp1, #0xff
0774     mov tmp3, tmp2
0775     bic tmp3, tmp3, #0xffffff00
0776     orr tmp1, tmp1, tmp3
0777     str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
0778 
0779     /* step 10. */
0780     ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0781     orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
0782     bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
0783     str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
0784 
0785     /* step 11. */
0786 3:  ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0]
0787     tst tmp1, #0x1
0788     beq 3b
0789     b   2f
0790 #endif
0791 
0792     /* Restore PLLA setting */
0793 4:  str tmp2, [pmc, #AT91_CKGR_PLLAR]
0794 
0795     /* Enable PLLA. */
0796     tst tmp2, #(AT91_PMC_MUL &  0xff0000)
0797     bne 1f
0798     tst tmp2, #(AT91_PMC_MUL & ~0xff0000)
0799     beq 2f
0800 
0801 1:  ldr tmp1, [pmc, #AT91_PMC_SR]
0802     tst tmp1, #AT91_PMC_LOCKA
0803     beq 1b
0804 2:
0805 .endm
0806 
0807 /**
0808  * at91_mckx_ps_enable: save MCK1..4 settings and switch it to main clock
0809  *
0810  * Side effects: overwrites tmp1, tmp2
0811  */
0812 .macro at91_mckx_ps_enable
0813 #ifdef CONFIG_SOC_SAMA7
0814     ldr pmc, .pmc_base
0815 
0816     /* There are 4 MCKs we need to handle: MCK1..4 */
0817     mov tmp1, #1
0818 e_loop: cmp tmp1, #5
0819     beq e_done
0820 
0821     /* Write MCK ID to retrieve the settings. */
0822     str tmp1, [pmc, #AT91_PMC_MCR_V2]
0823     ldr tmp2, [pmc, #AT91_PMC_MCR_V2]
0824 
0825 e_save_mck1:
0826     cmp tmp1, #1
0827     bne e_save_mck2
0828     str tmp2, .saved_mck1
0829     b   e_ps
0830 
0831 e_save_mck2:
0832     cmp tmp1, #2
0833     bne e_save_mck3
0834     str tmp2, .saved_mck2
0835     b   e_ps
0836 
0837 e_save_mck3:
0838     cmp tmp1, #3
0839     bne e_save_mck4
0840     str tmp2, .saved_mck3
0841     b   e_ps
0842 
0843 e_save_mck4:
0844     str tmp2, .saved_mck4
0845 
0846 e_ps:
0847     /* Use CSS=MAINCK and DIV=1. */
0848     bic tmp2, tmp2, #AT91_PMC_MCR_V2_CSS
0849     bic tmp2, tmp2, #AT91_PMC_MCR_V2_DIV
0850     orr tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MAINCK
0851     orr tmp2, tmp2, #AT91_PMC_MCR_V2_DIV1
0852     str tmp2, [pmc, #AT91_PMC_MCR_V2]
0853 
0854     wait_mckrdy tmp1
0855 
0856     add tmp1, tmp1, #1
0857     b   e_loop
0858 
0859 e_done:
0860 #endif
0861 .endm
0862 
0863 /**
0864  * at91_mckx_ps_restore: restore MCK1..4 settings
0865  *
0866  * Side effects: overwrites tmp1, tmp2
0867  */
0868 .macro at91_mckx_ps_restore
0869 #ifdef CONFIG_SOC_SAMA7
0870     ldr pmc, .pmc_base
0871 
0872     /* There are 4 MCKs we need to handle: MCK1..4 */
0873     mov tmp1, #1
0874 r_loop: cmp tmp1, #5
0875     beq r_done
0876 
0877 r_save_mck1:
0878     cmp tmp1, #1
0879     bne r_save_mck2
0880     ldr tmp2, .saved_mck1
0881     b   r_ps
0882 
0883 r_save_mck2:
0884     cmp tmp1, #2
0885     bne r_save_mck3
0886     ldr tmp2, .saved_mck2
0887     b   r_ps
0888 
0889 r_save_mck3:
0890     cmp tmp1, #3
0891     bne r_save_mck4
0892     ldr tmp2, .saved_mck3
0893     b   r_ps
0894 
0895 r_save_mck4:
0896     ldr tmp2, .saved_mck4
0897 
0898 r_ps:
0899     /* Write MCK ID to retrieve the settings. */
0900     str tmp1, [pmc, #AT91_PMC_MCR_V2]
0901     ldr tmp3, [pmc, #AT91_PMC_MCR_V2]
0902 
0903     /* We need to restore CSS and DIV. */
0904     bic tmp3, tmp3, #AT91_PMC_MCR_V2_CSS
0905     bic tmp3, tmp3, #AT91_PMC_MCR_V2_DIV
0906     orr tmp3, tmp3, tmp2
0907     bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MSK
0908     orr tmp3, tmp3, tmp1
0909     orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD
0910     str tmp2, [pmc, #AT91_PMC_MCR_V2]
0911 
0912     wait_mckrdy tmp1
0913 
0914     add tmp1, tmp1, #1
0915     b   r_loop
0916 r_done:
0917 #endif
0918 .endm
0919 
0920 .macro at91_ulp_mode
0921     at91_mckx_ps_enable
0922 
0923     ldr pmc, .pmc_base
0924     ldr tmp2, .mckr_offset
0925     ldr tmp3, .pm_mode
0926 
0927     /* Save Master clock setting */
0928     ldr tmp1, [pmc, tmp2]
0929     str tmp1, .saved_mckr
0930 
0931     /*
0932      * Set master clock source to:
0933      * - MAINCK if using ULP0 fast variant
0934      * - slow clock, otherwise
0935      */
0936     bic tmp1, tmp1, #AT91_PMC_CSS
0937     cmp tmp3, #AT91_PM_ULP0_FAST
0938     bne save_mck
0939     orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
0940 save_mck:
0941     str tmp1, [pmc, tmp2]
0942 
0943     mov tmp3, #0
0944     wait_mckrdy tmp3
0945 
0946     at91_plla_disable
0947 
0948     /* Enable low power mode for 2.5V regulator. */
0949     at91_2_5V_reg_set_low_power 1
0950 
0951     ldr tmp3, .pm_mode
0952     cmp tmp3, #AT91_PM_ULP1
0953     beq ulp1_mode
0954 
0955     at91_pm_ulp0_mode
0956     b   ulp_exit
0957 
0958 ulp1_mode:
0959     at91_pm_ulp1_mode
0960     b   ulp_exit
0961 
0962 ulp_exit:
0963     /* Disable low power mode for 2.5V regulator. */
0964     at91_2_5V_reg_set_low_power 0
0965 
0966     ldr pmc, .pmc_base
0967 
0968     at91_plla_enable
0969 
0970     /*
0971      * Restore master clock setting
0972      */
0973     ldr tmp1, .mckr_offset
0974     ldr tmp2, .saved_mckr
0975     str tmp2, [pmc, tmp1]
0976 
0977     mov tmp3, #0
0978     wait_mckrdy tmp3
0979 
0980     at91_mckx_ps_restore
0981 .endm
0982 
0983 .macro at91_backup_mode
0984     /* Switch the master clock source to slow clock. */
0985     ldr pmc, .pmc_base
0986     ldr tmp2, .mckr_offset
0987     ldr tmp1, [pmc, tmp2]
0988     bic tmp1, tmp1, #AT91_PMC_CSS
0989     str tmp1, [pmc, tmp2]
0990 
0991     mov tmp3, #0
0992     wait_mckrdy tmp3
0993 
0994     /*BUMEN*/
0995     ldr r0, .sfrbu
0996     mov tmp1, #0x1
0997     str tmp1, [r0, #0x10]
0998 
0999     /* Wait for it. */
1000 1:  ldr tmp1, [r0, #0x10]
1001     tst tmp1, #0x1
1002     beq 1b
1003 
1004     /* Shutdown */
1005     ldr r0, .shdwc
1006     mov tmp1, #0xA5000000
1007     add tmp1, tmp1, #0x1
1008     at91_backup_set_lpm tmp1
1009     str tmp1, [r0, #0]
1010 .endm
1011 
1012 /*
1013  * void at91_suspend_sram_fn(struct at91_pm_data*)
1014  * @input param:
1015  *  @r0: base address of struct at91_pm_data
1016  */
1017 /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
1018     .align 3
1019 ENTRY(at91_pm_suspend_in_sram)
1020     /* Save registers on stack */
1021     stmfd   sp!, {r4 - r12, lr}
1022 
1023     /* Drain write buffer */
1024     mov tmp1, #0
1025     mcr p15, 0, tmp1, c7, c10, 4
1026 
1027     /* Flush tlb. */
1028     mov r4, #0
1029     mcr p15, 0, r4, c8, c7, 0
1030 
1031     ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
1032     str tmp1, .mckr_offset
1033     ldr tmp1, [r0, #PM_DATA_PMC_VERSION]
1034     str tmp1, .pmc_version
1035     ldr tmp1, [r0, #PM_DATA_MEMCTRL]
1036     str tmp1, .memtype
1037     ldr tmp1, [r0, #PM_DATA_MODE]
1038     str tmp1, .pm_mode
1039 
1040     /*
1041      * ldrne below are here to preload their address in the TLB as access
1042      * to RAM may be limited while in self-refresh.
1043      */
1044     ldr tmp1, [r0, #PM_DATA_PMC]
1045     str tmp1, .pmc_base
1046     cmp tmp1, #0
1047     ldrne   tmp2, [tmp1, #0]
1048 
1049     ldr tmp1, [r0, #PM_DATA_RAMC0]
1050     str tmp1, .sramc_base
1051     cmp tmp1, #0
1052     ldrne   tmp2, [tmp1, #0]
1053 
1054     ldr tmp1, [r0, #PM_DATA_RAMC1]
1055     str tmp1, .sramc1_base
1056     cmp tmp1, #0
1057     ldrne   tmp2, [tmp1, #0]
1058 
1059 #ifndef CONFIG_SOC_SAM_V4_V5
1060     /* ldrne below are here to preload their address in the TLB */
1061     ldr tmp1, [r0, #PM_DATA_RAMC_PHY]
1062     str tmp1, .sramc_phy_base
1063     cmp tmp1, #0
1064     ldrne   tmp2, [tmp1, #0]
1065 
1066     ldr tmp1, [r0, #PM_DATA_SHDWC]
1067     str tmp1, .shdwc
1068     cmp tmp1, #0
1069     ldrne   tmp2, [tmp1, #0]
1070 
1071     ldr tmp1, [r0, #PM_DATA_SFRBU]
1072     str tmp1, .sfrbu
1073     cmp tmp1, #0
1074     ldrne   tmp2, [tmp1, #0x10]
1075 #endif
1076 
1077     /* Active the self-refresh mode */
1078     at91_sramc_self_refresh_ena
1079 
1080     ldr r0, .pm_mode
1081     cmp r0, #AT91_PM_STANDBY
1082     beq standby
1083     cmp r0, #AT91_PM_BACKUP
1084     beq backup_mode
1085 
1086     at91_ulp_mode
1087     b   exit_suspend
1088 
1089 standby:
1090     /* Wait for interrupt */
1091     ldr pmc, .pmc_base
1092     at91_cpu_idle
1093     b   exit_suspend
1094 
1095 backup_mode:
1096     at91_backup_mode
1097 
1098 exit_suspend:
1099     /* Exit the self-refresh mode */
1100     at91_sramc_self_refresh_dis
1101 
1102     /* Restore registers, and return */
1103     ldmfd   sp!, {r4 - r12, pc}
1104 ENDPROC(at91_pm_suspend_in_sram)
1105 
1106 .pmc_base:
1107     .word 0
1108 .sramc_base:
1109     .word 0
1110 .sramc1_base:
1111     .word 0
1112 .sramc_phy_base:
1113     .word 0
1114 .shdwc:
1115     .word 0
1116 .sfrbu:
1117     .word 0
1118 .memtype:
1119     .word 0
1120 .pm_mode:
1121     .word 0
1122 .mckr_offset:
1123     .word 0
1124 .pmc_version:
1125     .word 0
1126 .saved_mckr:
1127     .word 0
1128 .saved_pllar:
1129     .word 0
1130 .saved_sam9_lpr:
1131     .word 0
1132 .saved_sam9_lpr1:
1133     .word 0
1134 .saved_sam9_mdr:
1135     .word 0
1136 .saved_sam9_mdr1:
1137     .word 0
1138 .saved_osc_status:
1139     .word 0
1140 #ifdef CONFIG_SOC_SAMA7
1141 .saved_mck1:
1142     .word 0
1143 .saved_mck2:
1144     .word 0
1145 .saved_mck3:
1146     .word 0
1147 .saved_mck4:
1148     .word 0
1149 #endif
1150 
1151 ENTRY(at91_pm_suspend_in_sram_sz)
1152     .word .-at91_pm_suspend_in_sram