/* SPDX-License-Identifier: GPL-2.0-only */1/*2* arch/arm/mach-at91/pm_slow_clock.S3*4* Copyright (C) 2006 Savin Zlobec5*6* AT91SAM9 support:7* Copyright (C) 2007 Anti Sullin <[email protected]>8*/9#include <linux/linkage.h>10#include <linux/clk/at91_pmc.h>11#include "pm.h"12#include "pm_data-offsets.h"1314#ifdef CONFIG_CPU_V715.arch armv7-a16#endif1718#define SRAMC_SELF_FRESH_ACTIVE 0x0119#define SRAMC_SELF_FRESH_EXIT 0x002021pmc .req r022tmp1 .req r423tmp2 .req r524tmp3 .req r62526/*27* Wait until master clock is ready (after switching master clock source)28*29* @r_mckid: register holding master clock identifier30*31* Side effects: overwrites r7, r832*/33.macro wait_mckrdy r_mckid34#ifdef CONFIG_SOC_SAMA735cmp \r_mckid, #036beq 1f37mov r7, #AT91_PMC_MCKXRDY38b 2f39#endif401: mov r7, #AT91_PMC_MCKRDY412: ldr r8, [pmc, #AT91_PMC_SR]42and r8, r743cmp r8, r744bne 2b45.endm4647/*48* Wait until master oscillator has stabilized.49*50* Side effects: overwrites r751*/52.macro wait_moscrdy531: ldr r7, [pmc, #AT91_PMC_SR]54tst r7, #AT91_PMC_MOSCS55beq 1b56.endm5758/*59* Wait for main oscillator selection is done60*61* Side effects: overwrites r762*/63.macro wait_moscsels641: ldr r7, [pmc, #AT91_PMC_SR]65tst r7, #AT91_PMC_MOSCSELS66beq 1b67.endm6869/*70* Put the processor to enter the idle state71*72* Side effects: overwrites r773*/74.macro at91_cpu_idle7576#if defined(CONFIG_CPU_V7)77mov r7, #AT91_PMC_PCK78str r7, [pmc, #AT91_PMC_SCDR]7980dsb8182wfi @ Wait For Interrupt83#else84mcr p15, 0, tmp1, c7, c0, 485#endif8687.endm8889.macro at91_backup_set_lpm reg90#ifdef CONFIG_SOC_SAMA791orr \reg, \reg, #0x20000092#endif93.endm9495.text9697.arm9899#ifdef CONFIG_SOC_SAMA7100/**101* Enable self-refresh102*103* Side effects: overwrites r2, r3, tmp1, tmp2, tmp3, r7104*/105.macro at91_sramc_self_refresh_ena106ldr r2, .sramc_base107ldr r3, .sramc_phy_base108ldr r7, .pm_mode109110dsb111112/* Disable all AXI ports. */113ldr tmp1, [r2, #UDDRC_PCTRL_0]114bic tmp1, tmp1, #0x1115str tmp1, [r2, #UDDRC_PCTRL_0]116117ldr tmp1, [r2, #UDDRC_PCTRL_1]118bic tmp1, tmp1, #0x1119str tmp1, [r2, #UDDRC_PCTRL_1]120121ldr tmp1, [r2, #UDDRC_PCTRL_2]122bic tmp1, tmp1, #0x1123str tmp1, [r2, #UDDRC_PCTRL_2]124125ldr tmp1, [r2, #UDDRC_PCTRL_3]126bic tmp1, tmp1, #0x1127str tmp1, [r2, #UDDRC_PCTRL_3]128129ldr tmp1, [r2, #UDDRC_PCTRL_4]130bic tmp1, tmp1, #0x1131str tmp1, [r2, #UDDRC_PCTRL_4]132133sr_ena_1:134/* Wait for all ports to disable. */135ldr tmp1, [r2, #UDDRC_PSTAT]136ldr tmp2, =UDDRC_PSTAT_ALL_PORTS137tst tmp1, tmp2138bne sr_ena_1139140/* Switch to self-refresh. */141ldr tmp1, [r2, #UDDRC_PWRCTL]142orr tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW143str tmp1, [r2, #UDDRC_PWRCTL]144145sr_ena_2:146/* Wait for self-refresh enter. */147ldr tmp1, [r2, #UDDRC_STAT]148bic tmp1, tmp1, #~UDDRC_STAT_SELFREF_TYPE_MSK149cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW150bne sr_ena_2151152/* Disable DX DLLs for non-backup modes. */153cmp r7, #AT91_PM_BACKUP154beq sr_ena_3155156/* Do not soft reset the AC DLL. */157ldr tmp1, [r3, DDR3PHY_ACDLLCR]158bic tmp1, tmp1, DDR3PHY_ACDLLCR_DLLSRST159str tmp1, [r3, DDR3PHY_ACDLLCR]160161/* Disable DX DLLs. */162ldr tmp1, [r3, #DDR3PHY_DX0DLLCR]163orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS164str tmp1, [r3, #DDR3PHY_DX0DLLCR]165166ldr tmp1, [r3, #DDR3PHY_DX1DLLCR]167orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS168str tmp1, [r3, #DDR3PHY_DX1DLLCR]169170sr_ena_3:171/* Power down DDR PHY data receivers. */172ldr tmp1, [r3, #DDR3PHY_DXCCR]173orr tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR174str tmp1, [r3, #DDR3PHY_DXCCR]175176/* Power down ADDR/CMD IO. */177ldr tmp1, [r3, #DDR3PHY_ACIOCR]178orr tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD179orr tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0180orr tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0181str tmp1, [r3, #DDR3PHY_ACIOCR]182183/* Power down ODT. */184ldr tmp1, [r3, #DDR3PHY_DSGCR]185orr tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0186str tmp1, [r3, #DDR3PHY_DSGCR]187.endm188189/**190* Disable self-refresh191*192* Side effects: overwrites r2, r3, tmp1, tmp2, tmp3193*/194.macro at91_sramc_self_refresh_dis195ldr r2, .sramc_base196ldr r3, .sramc_phy_base197198/* Power up DDR PHY data receivers. */199ldr tmp1, [r3, #DDR3PHY_DXCCR]200bic tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR201str tmp1, [r3, #DDR3PHY_DXCCR]202203/* Power up the output of CK and CS pins. */204ldr tmp1, [r3, #DDR3PHY_ACIOCR]205bic tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD206bic tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0207bic tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0208str tmp1, [r3, #DDR3PHY_ACIOCR]209210/* Power up ODT. */211ldr tmp1, [r3, #DDR3PHY_DSGCR]212bic tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0213str tmp1, [r3, #DDR3PHY_DSGCR]214215/* Enable DX DLLs. */216ldr tmp1, [r3, #DDR3PHY_DX0DLLCR]217bic tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS218str tmp1, [r3, #DDR3PHY_DX0DLLCR]219220ldr tmp1, [r3, #DDR3PHY_DX1DLLCR]221bic tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS222str tmp1, [r3, #DDR3PHY_DX1DLLCR]223224/* Enable quasi-dynamic programming. */225mov tmp1, #0226str tmp1, [r2, #UDDRC_SWCTRL]227228/* De-assert SDRAM initialization. */229ldr tmp1, [r2, #UDDRC_DFIMISC]230bic tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN231str tmp1, [r2, #UDDRC_DFIMISC]232233/* Quasi-dynamic programming done. */234mov tmp1, #UDDRC_SWCTRL_SW_DONE235str tmp1, [r2, #UDDRC_SWCTRL]236237sr_dis_1:238ldr tmp1, [r2, #UDDRC_SWSTAT]239tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK240beq sr_dis_1241242/* DLL soft-reset + DLL lock wait + ITM reset */243mov tmp1, #(DDR3PHY_PIR_INIT | DDR3PHY_PIR_DLLSRST | \244DDR3PHY_PIR_DLLLOCK | DDR3PHY_PIR_ITMSRST)245str tmp1, [r3, #DDR3PHY_PIR]246247sr_dis_4:248/* Wait for it. */249ldr tmp1, [r3, #DDR3PHY_PGSR]250tst tmp1, #DDR3PHY_PGSR_IDONE251beq sr_dis_4252253/* Enable quasi-dynamic programming. */254mov tmp1, #0255str tmp1, [r2, #UDDRC_SWCTRL]256257/* Assert PHY init complete enable signal. */258ldr tmp1, [r2, #UDDRC_DFIMISC]259orr tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN260str tmp1, [r2, #UDDRC_DFIMISC]261262/* Programming is done. Set sw_done. */263mov tmp1, #UDDRC_SWCTRL_SW_DONE264str tmp1, [r2, #UDDRC_SWCTRL]265266sr_dis_5:267/* Wait for it. */268ldr tmp1, [r2, #UDDRC_SWSTAT]269tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK270beq sr_dis_5271272/* Trigger self-refresh exit. */273ldr tmp1, [r2, #UDDRC_PWRCTL]274bic tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW275str tmp1, [r2, #UDDRC_PWRCTL]276277sr_dis_6:278/* Wait for self-refresh exit done. */279ldr tmp1, [r2, #UDDRC_STAT]280bic tmp1, tmp1, #~UDDRC_STAT_OPMODE_MSK281cmp tmp1, #UDDRC_STAT_OPMODE_NORMAL282bne sr_dis_6283284/* Enable all AXI ports. */285ldr tmp1, [r2, #UDDRC_PCTRL_0]286orr tmp1, tmp1, #0x1287str tmp1, [r2, #UDDRC_PCTRL_0]288289ldr tmp1, [r2, #UDDRC_PCTRL_1]290orr tmp1, tmp1, #0x1291str tmp1, [r2, #UDDRC_PCTRL_1]292293ldr tmp1, [r2, #UDDRC_PCTRL_2]294orr tmp1, tmp1, #0x1295str tmp1, [r2, #UDDRC_PCTRL_2]296297ldr tmp1, [r2, #UDDRC_PCTRL_3]298orr tmp1, tmp1, #0x1299str tmp1, [r2, #UDDRC_PCTRL_3]300301ldr tmp1, [r2, #UDDRC_PCTRL_4]302orr tmp1, tmp1, #0x1303str tmp1, [r2, #UDDRC_PCTRL_4]304305dsb306.endm307#else308/**309* Enable self-refresh310*311* register usage:312* @r1: memory type313* @r2: base address of the sram controller314* @r3: temporary315*/316.macro at91_sramc_self_refresh_ena317ldr r1, .memtype318ldr r2, .sramc_base319320cmp r1, #AT91_MEMCTRL_MC321bne sr_ena_ddrc_sf322323/* Active SDRAM self-refresh mode */324mov r3, #1325str r3, [r2, #AT91_MC_SDRAMC_SRR]326b sr_ena_exit327328sr_ena_ddrc_sf:329cmp r1, #AT91_MEMCTRL_DDRSDR330bne sr_ena_sdramc_sf331332/*333* DDR Memory controller334*/335336/* LPDDR1 --> force DDR2 mode during self-refresh */337ldr r3, [r2, #AT91_DDRSDRC_MDR]338str r3, .saved_sam9_mdr339bic r3, r3, #~AT91_DDRSDRC_MD340cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR341ldreq r3, [r2, #AT91_DDRSDRC_MDR]342biceq r3, r3, #AT91_DDRSDRC_MD343orreq r3, r3, #AT91_DDRSDRC_MD_DDR2344streq r3, [r2, #AT91_DDRSDRC_MDR]345346/* Active DDRC self-refresh mode */347ldr r3, [r2, #AT91_DDRSDRC_LPR]348str r3, .saved_sam9_lpr349bic r3, r3, #AT91_DDRSDRC_LPCB350orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH351str r3, [r2, #AT91_DDRSDRC_LPR]352353/* If using the 2nd ddr controller */354ldr r2, .sramc1_base355cmp r2, #0356beq sr_ena_no_2nd_ddrc357358ldr r3, [r2, #AT91_DDRSDRC_MDR]359str r3, .saved_sam9_mdr1360bic r3, r3, #~AT91_DDRSDRC_MD361cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR362ldreq r3, [r2, #AT91_DDRSDRC_MDR]363biceq r3, r3, #AT91_DDRSDRC_MD364orreq r3, r3, #AT91_DDRSDRC_MD_DDR2365streq r3, [r2, #AT91_DDRSDRC_MDR]366367/* Active DDRC self-refresh mode */368ldr r3, [r2, #AT91_DDRSDRC_LPR]369str r3, .saved_sam9_lpr1370bic r3, r3, #AT91_DDRSDRC_LPCB371orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH372str r3, [r2, #AT91_DDRSDRC_LPR]373374sr_ena_no_2nd_ddrc:375b sr_ena_exit376377/*378* SDRAMC Memory controller379*/380sr_ena_sdramc_sf:381/* Active SDRAMC self-refresh mode */382ldr r3, [r2, #AT91_SDRAMC_LPR]383str r3, .saved_sam9_lpr384bic r3, r3, #AT91_SDRAMC_LPCB385orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH386str r3, [r2, #AT91_SDRAMC_LPR]387388ldr r3, .saved_sam9_lpr389str r3, [r2, #AT91_SDRAMC_LPR]390391sr_ena_exit:392.endm393394/**395* Disable self-refresh396*397* register usage:398* @r1: memory type399* @r2: base address of the sram controller400* @r3: temporary401*/402.macro at91_sramc_self_refresh_dis403ldr r1, .memtype404ldr r2, .sramc_base405406cmp r1, #AT91_MEMCTRL_MC407bne sr_dis_ddrc_exit_sf408409/*410* at91rm9200 Memory controller411*/412413/*414* For exiting the self-refresh mode, do nothing,415* automatically exit the self-refresh mode.416*/417b sr_dis_exit418419sr_dis_ddrc_exit_sf:420cmp r1, #AT91_MEMCTRL_DDRSDR421bne sdramc_exit_sf422423/* DDR Memory controller */424425/* Restore MDR in case of LPDDR1 */426ldr r3, .saved_sam9_mdr427str r3, [r2, #AT91_DDRSDRC_MDR]428/* Restore LPR on AT91 with DDRAM */429ldr r3, .saved_sam9_lpr430str r3, [r2, #AT91_DDRSDRC_LPR]431432/* If using the 2nd ddr controller */433ldr r2, .sramc1_base434cmp r2, #0435ldrne r3, .saved_sam9_mdr1436strne r3, [r2, #AT91_DDRSDRC_MDR]437ldrne r3, .saved_sam9_lpr1438strne r3, [r2, #AT91_DDRSDRC_LPR]439440b sr_dis_exit441442sdramc_exit_sf:443/* SDRAMC Memory controller */444ldr r3, .saved_sam9_lpr445str r3, [r2, #AT91_SDRAMC_LPR]446447sr_dis_exit:448.endm449#endif450451.macro at91_pm_ulp0_mode452ldr pmc, .pmc_base453ldr tmp2, .pm_mode454ldr tmp3, .mckr_offset455456/* Check if ULP0 fast variant has been requested. */457cmp tmp2, #AT91_PM_ULP0_FAST458bne 0f459460/* Set highest prescaler for power saving */461ldr tmp1, [pmc, tmp3]462bic tmp1, tmp1, #AT91_PMC_PRES463orr tmp1, tmp1, #AT91_PMC_PRES_64464str tmp1, [pmc, tmp3]465466mov tmp3, #0467wait_mckrdy tmp3468b 1f4694700:471/* Turn off the crystal oscillator */472ldr tmp1, [pmc, #AT91_CKGR_MOR]473bic tmp1, tmp1, #AT91_PMC_MOSCEN474orr tmp1, tmp1, #AT91_PMC_KEY475str tmp1, [pmc, #AT91_CKGR_MOR]476477/* Save RC oscillator state */478ldr tmp1, [pmc, #AT91_PMC_SR]479str tmp1, .saved_osc_status480tst tmp1, #AT91_PMC_MOSCRCS481bne 1f482483/* Turn off RC oscillator */484ldr tmp1, [pmc, #AT91_CKGR_MOR]485bic tmp1, tmp1, #AT91_PMC_MOSCRCEN486bic tmp1, tmp1, #AT91_PMC_KEY_MASK487orr tmp1, tmp1, #AT91_PMC_KEY488str tmp1, [pmc, #AT91_CKGR_MOR]489490/* Wait main RC disabled done */4912: ldr tmp1, [pmc, #AT91_PMC_SR]492tst tmp1, #AT91_PMC_MOSCRCS493bne 2b494495/* Wait for interrupt */4961: at91_cpu_idle497498/* Check if ULP0 fast variant has been requested. */499cmp tmp2, #AT91_PM_ULP0_FAST500bne 5f501502/* Set lowest prescaler for fast resume. */503ldr tmp3, .mckr_offset504ldr tmp1, [pmc, tmp3]505bic tmp1, tmp1, #AT91_PMC_PRES506str tmp1, [pmc, tmp3]507508mov tmp3, #0509wait_mckrdy tmp3510b 6f5115125: /* Restore RC oscillator state */513ldr tmp1, .saved_osc_status514tst tmp1, #AT91_PMC_MOSCRCS515beq 4f516517/* Turn on RC oscillator */518ldr tmp1, [pmc, #AT91_CKGR_MOR]519orr tmp1, tmp1, #AT91_PMC_MOSCRCEN520bic tmp1, tmp1, #AT91_PMC_KEY_MASK521orr tmp1, tmp1, #AT91_PMC_KEY522str tmp1, [pmc, #AT91_CKGR_MOR]523524/* Wait main RC stabilization */5253: ldr tmp1, [pmc, #AT91_PMC_SR]526tst tmp1, #AT91_PMC_MOSCRCS527beq 3b528529/* Turn on the crystal oscillator */5304: ldr tmp1, [pmc, #AT91_CKGR_MOR]531orr tmp1, tmp1, #AT91_PMC_MOSCEN532orr tmp1, tmp1, #AT91_PMC_KEY533str tmp1, [pmc, #AT91_CKGR_MOR]534535wait_moscrdy5366:537.endm538539/**540* Note: This procedure only applies on the platform which uses541* the external crystal oscillator as a main clock source.542*/543.macro at91_pm_ulp1_mode544ldr pmc, .pmc_base545ldr tmp2, .mckr_offset546mov tmp3, #0547548/* Save RC oscillator state and check if it is enabled. */549ldr tmp1, [pmc, #AT91_PMC_SR]550str tmp1, .saved_osc_status551tst tmp1, #AT91_PMC_MOSCRCS552bne 2f553554/* Enable RC oscillator */555ldr tmp1, [pmc, #AT91_CKGR_MOR]556orr tmp1, tmp1, #AT91_PMC_MOSCRCEN557bic tmp1, tmp1, #AT91_PMC_KEY_MASK558orr tmp1, tmp1, #AT91_PMC_KEY559str tmp1, [pmc, #AT91_CKGR_MOR]560561/* Wait main RC stabilization */5621: ldr tmp1, [pmc, #AT91_PMC_SR]563tst tmp1, #AT91_PMC_MOSCRCS564beq 1b565566/* Switch the main clock source to 12-MHz RC oscillator */5672: ldr tmp1, [pmc, #AT91_CKGR_MOR]568bic tmp1, tmp1, #AT91_PMC_MOSCSEL569bic tmp1, tmp1, #AT91_PMC_KEY_MASK570orr tmp1, tmp1, #AT91_PMC_KEY571str tmp1, [pmc, #AT91_CKGR_MOR]572573wait_moscsels574575/* Disable the crystal oscillator */576ldr tmp1, [pmc, #AT91_CKGR_MOR]577bic tmp1, tmp1, #AT91_PMC_MOSCEN578bic tmp1, tmp1, #AT91_PMC_KEY_MASK579orr tmp1, tmp1, #AT91_PMC_KEY580str tmp1, [pmc, #AT91_CKGR_MOR]581582/* Switch the master clock source to main clock */583ldr tmp1, [pmc, tmp2]584bic tmp1, tmp1, #AT91_PMC_CSS585orr tmp1, tmp1, #AT91_PMC_CSS_MAIN586str tmp1, [pmc, tmp2]587588wait_mckrdy tmp3589590/* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */591ldr tmp1, [pmc, #AT91_CKGR_MOR]592orr tmp1, tmp1, #AT91_PMC_WAITMODE593bic tmp1, tmp1, #AT91_PMC_KEY_MASK594orr tmp1, tmp1, #AT91_PMC_KEY595str tmp1, [pmc, #AT91_CKGR_MOR]596597/* Quirk for SAM9X60's PMC */598nop599nop600601wait_mckrdy tmp3602603/* Enable the crystal oscillator */604ldr tmp1, [pmc, #AT91_CKGR_MOR]605orr tmp1, tmp1, #AT91_PMC_MOSCEN606bic tmp1, tmp1, #AT91_PMC_KEY_MASK607orr tmp1, tmp1, #AT91_PMC_KEY608str tmp1, [pmc, #AT91_CKGR_MOR]609610wait_moscrdy611612/* Switch the master clock source to slow clock */613ldr tmp1, [pmc, tmp2]614bic tmp1, tmp1, #AT91_PMC_CSS615str tmp1, [pmc, tmp2]616617wait_mckrdy tmp3618619/* Switch main clock source to crystal oscillator */620ldr tmp1, [pmc, #AT91_CKGR_MOR]621orr tmp1, tmp1, #AT91_PMC_MOSCSEL622bic tmp1, tmp1, #AT91_PMC_KEY_MASK623orr tmp1, tmp1, #AT91_PMC_KEY624str tmp1, [pmc, #AT91_CKGR_MOR]625626wait_moscsels627628/* Switch the master clock source to main clock */629ldr tmp1, [pmc, tmp2]630bic tmp1, tmp1, #AT91_PMC_CSS631orr tmp1, tmp1, #AT91_PMC_CSS_MAIN632str tmp1, [pmc, tmp2]633634wait_mckrdy tmp3635636/* Restore RC oscillator state */637ldr tmp1, .saved_osc_status638tst tmp1, #AT91_PMC_MOSCRCS639bne 3f640641/* Disable RC oscillator */642ldr tmp1, [pmc, #AT91_CKGR_MOR]643bic tmp1, tmp1, #AT91_PMC_MOSCRCEN644bic tmp1, tmp1, #AT91_PMC_KEY_MASK645orr tmp1, tmp1, #AT91_PMC_KEY646str tmp1, [pmc, #AT91_CKGR_MOR]647648/* Wait RC oscillator disable done */6494: ldr tmp1, [pmc, #AT91_PMC_SR]650tst tmp1, #AT91_PMC_MOSCRCS651bne 4b6526533:654.endm655656.macro at91_plla_disable657/* Save PLLA setting and disable it */658ldr tmp1, .pmc_version659cmp tmp1, #AT91_PMC_V1660beq 1f661662#ifdef CONFIG_HAVE_AT91_SAM9X60_PLL663/* Save PLLA settings. */664ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT]665bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID666str tmp2, [pmc, #AT91_PMC_PLL_UPDT]667668/* save acr */669ldr tmp2, [pmc, #AT91_PMC_PLL_ACR]670str tmp2, .saved_acr671672/* save div. */673mov tmp1, #0674ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0]675bic tmp2, tmp2, #0xffffff00676orr tmp1, tmp1, tmp2677678/* save mul. */679ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1]680bic tmp2, tmp2, #0xffffff681orr tmp1, tmp1, tmp2682str tmp1, .saved_pllar683684/* step 2. */685ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]686bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE687bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID688str tmp1, [pmc, #AT91_PMC_PLL_UPDT]689690/* step 3. */691ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]692bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK693orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL694str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]695696/* step 4. */697ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]698orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE699bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID700str tmp1, [pmc, #AT91_PMC_PLL_UPDT]701702/* step 5. */703ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]704bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL705str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]706707/* step 7. */708ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]709orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE710bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID711str tmp1, [pmc, #AT91_PMC_PLL_UPDT]712713b 2f714#endif7157161: /* Save PLLA setting and disable it */717ldr tmp1, [pmc, #AT91_CKGR_PLLAR]718str tmp1, .saved_pllar719720/* Disable PLLA. */721mov tmp1, #AT91_PMC_PLLCOUNT722orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */723str tmp1, [pmc, #AT91_CKGR_PLLAR]7242:725.endm726727.macro at91_plla_enable728ldr tmp2, .saved_pllar729ldr tmp3, .pmc_version730cmp tmp3, #AT91_PMC_V1731beq 4f732733#ifdef CONFIG_HAVE_AT91_SAM9X60_PLL734/* step 1. */735ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]736bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID737bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE738str tmp1, [pmc, #AT91_PMC_PLL_UPDT]739740/* step 2. */741ldr tmp1, .saved_acr742str tmp1, [pmc, #AT91_PMC_PLL_ACR]743744/* step 3. */745ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1]746mov tmp3, tmp2747bic tmp3, tmp3, #0xffffff748orr tmp1, tmp1, tmp3749str tmp1, [pmc, #AT91_PMC_PLL_CTRL1]750751/* step 8. */752ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]753bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID754orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE755str tmp1, [pmc, #AT91_PMC_PLL_UPDT]756757/* step 9. */758ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]759orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK760orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL761orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK762bic tmp1, tmp1, #0xff763mov tmp3, tmp2764bic tmp3, tmp3, #0xffffff00765orr tmp1, tmp1, tmp3766str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]767768/* step 10. */769ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]770orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE771bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID772str tmp1, [pmc, #AT91_PMC_PLL_UPDT]773774/* step 11. */7753: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0]776tst tmp1, #0x1777beq 3b778b 2f779#endif780781/* Restore PLLA setting */7824: str tmp2, [pmc, #AT91_CKGR_PLLAR]783784/* Enable PLLA. */785tst tmp2, #(AT91_PMC_MUL & 0xff0000)786bne 1f787tst tmp2, #(AT91_PMC_MUL & ~0xff0000)788beq 2f7897901: ldr tmp1, [pmc, #AT91_PMC_SR]791tst tmp1, #AT91_PMC_LOCKA792beq 1b7932:794.endm795796/**797* at91_mckx_ps_enable: save MCK settings and switch it to main clock798*799* Side effects: overwrites tmp1, tmp2, tmp3800*/801.macro at91_mckx_ps_enable802#ifdef CONFIG_SOC_SAMA7803ldr pmc, .pmc_base804ldr tmp3, .mcks805806/* Start at MCK1 and go until MCKs */807mov tmp1, #1808e_loop:809cmp tmp1, tmp3810bgt e_done811812/* Write MCK ID to retrieve the settings. */813str tmp1, [pmc, #AT91_PMC_MCR_V2]814ldr tmp2, [pmc, #AT91_PMC_MCR_V2]815816e_save_mck1:817cmp tmp1, #1818bne e_save_mck2819str tmp2, .saved_mck1820b e_ps821822e_save_mck2:823cmp tmp1, #2824bne e_save_mck3825str tmp2, .saved_mck2826b e_ps827828e_save_mck3:829cmp tmp1, #3830bne e_save_mck4831str tmp2, .saved_mck3832b e_ps833834e_save_mck4:835cmp tmp1, #4836bne e_save_mck5837str tmp2, .saved_mck4838b e_ps839840e_save_mck5:841cmp tmp1, #5842bne e_save_mck6843str tmp2, .saved_mck5844b e_ps845846e_save_mck6:847cmp tmp1, #6848bne e_save_mck7849str tmp2, .saved_mck6850b e_ps851852e_save_mck7:853cmp tmp1, #7854bne e_save_mck8855str tmp2, .saved_mck7856b e_ps857858e_save_mck8:859cmp tmp1, #8860bne e_save_mck9861str tmp2, .saved_mck8862b e_ps863864e_save_mck9:865str tmp2, .saved_mck9866867e_ps:868/* Use CSS=MAINCK and DIV=1. */869bic tmp2, tmp2, #AT91_PMC_MCR_V2_CSS870bic tmp2, tmp2, #AT91_PMC_MCR_V2_DIV871orr tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MAINCK872orr tmp2, tmp2, #AT91_PMC_MCR_V2_DIV1873str tmp2, [pmc, #AT91_PMC_MCR_V2]874875wait_mckrdy tmp1876877add tmp1, tmp1, #1878b e_loop879880e_done:881#endif882.endm883884/**885* at91_mckx_ps_restore: restore MCKx settings886*887* Side effects: overwrites tmp1, tmp2 and tmp3888*/889.macro at91_mckx_ps_restore890#ifdef CONFIG_SOC_SAMA7891ldr pmc, .pmc_base892ldr tmp2, .mcks893894/* Start from MCK1 and go up to MCKs */895mov tmp1, #1896r_loop:897cmp tmp1, tmp2898bgt r_done899900r_save_mck1:901cmp tmp1, #1902bne r_save_mck2903ldr tmp2, .saved_mck1904b r_ps905906r_save_mck2:907cmp tmp1, #2908bne r_save_mck3909ldr tmp2, .saved_mck2910b r_ps911912r_save_mck3:913cmp tmp1, #3914bne r_save_mck4915ldr tmp2, .saved_mck3916b r_ps917918r_save_mck4:919cmp tmp1, #4920bne r_save_mck5921ldr tmp2, .saved_mck4922b r_ps923924r_save_mck5:925cmp tmp1, #5926bne r_save_mck6927ldr tmp2, .saved_mck5928b r_ps929930r_save_mck6:931cmp tmp1, #6932bne r_save_mck7933ldr tmp2, .saved_mck6934b r_ps935936r_save_mck7:937cmp tmp1, #7938bne r_save_mck8939ldr tmp2, .saved_mck7940b r_ps941942r_save_mck8:943cmp tmp1, #8944bne r_save_mck9945ldr tmp2, .saved_mck8946b r_ps947948r_save_mck9:949ldr tmp2, .saved_mck9950951r_ps:952/* Write MCK ID to retrieve the settings. */953str tmp1, [pmc, #AT91_PMC_MCR_V2]954ldr tmp3, [pmc, #AT91_PMC_MCR_V2]955956/* We need to restore CSS and DIV. */957bic tmp3, tmp3, #AT91_PMC_MCR_V2_CSS958bic tmp3, tmp3, #AT91_PMC_MCR_V2_DIV959orr tmp3, tmp3, tmp2960bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MSK961orr tmp3, tmp3, tmp1962orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD963str tmp3, [pmc, #AT91_PMC_MCR_V2]964965wait_mckrdy tmp1966967add tmp1, tmp1, #1968ldr tmp2, .mcks969b r_loop970r_done:971#endif972.endm973974.macro at91_ulp_mode975at91_mckx_ps_enable976977ldr pmc, .pmc_base978ldr tmp2, .mckr_offset979ldr tmp3, .pm_mode980981/* Save Master clock setting */982ldr tmp1, [pmc, tmp2]983str tmp1, .saved_mckr984985/*986* Set master clock source to:987* - MAINCK if using ULP0 fast variant988* - slow clock, otherwise989*/990bic tmp1, tmp1, #AT91_PMC_CSS991cmp tmp3, #AT91_PM_ULP0_FAST992bne save_mck993orr tmp1, tmp1, #AT91_PMC_CSS_MAIN994save_mck:995str tmp1, [pmc, tmp2]996997mov tmp3, #0998wait_mckrdy tmp39991000at91_plla_disable10011002ldr tmp3, .pm_mode1003cmp tmp3, #AT91_PM_ULP11004beq ulp1_mode10051006at91_pm_ulp0_mode1007b ulp_exit10081009ulp1_mode:1010at91_pm_ulp1_mode1011b ulp_exit10121013ulp_exit:1014ldr pmc, .pmc_base10151016at91_plla_enable10171018/*1019* Restore master clock setting1020*/1021ldr tmp1, .mckr_offset1022ldr tmp2, .saved_mckr1023str tmp2, [pmc, tmp1]10241025mov tmp3, #01026wait_mckrdy tmp310271028at91_mckx_ps_restore1029.endm10301031.macro at91_backup_mode1032/* Switch the master clock source to slow clock. */1033ldr pmc, .pmc_base1034ldr tmp2, .mckr_offset1035ldr tmp1, [pmc, tmp2]1036bic tmp1, tmp1, #AT91_PMC_CSS1037str tmp1, [pmc, tmp2]10381039mov tmp3, #01040wait_mckrdy tmp310411042/*BUMEN*/1043ldr r0, .sfrbu1044mov tmp1, #0x11045str tmp1, [r0, #0x10]10461047/* Wait for it. */10481: ldr tmp1, [r0, #0x10]1049tst tmp1, #0x11050beq 1b10511052/* Shutdown */1053ldr r0, .shdwc1054mov tmp1, #0xA50000001055add tmp1, tmp1, #0x11056at91_backup_set_lpm tmp11057str tmp1, [r0, #0]1058.endm10591060/*1061* void at91_suspend_sram_fn(struct at91_pm_data*)1062* @input param:1063* @r0: base address of struct at91_pm_data1064*/1065/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */1066.align 31067ENTRY(at91_pm_suspend_in_sram)1068/* Save registers on stack */1069stmfd sp!, {r4 - r12, lr}10701071/* Drain write buffer */1072mov tmp1, #01073mcr p15, 0, tmp1, c7, c10, 410741075/* Flush tlb. */1076mov r4, #01077mcr p15, 0, r4, c8, c7, 010781079ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]1080str tmp1, .mckr_offset1081ldr tmp1, [r0, #PM_DATA_PMC_VERSION]1082str tmp1, .pmc_version1083ldr tmp1, [r0, #PM_DATA_MEMCTRL]1084str tmp1, .memtype1085ldr tmp1, [r0, #PM_DATA_MODE]1086str tmp1, .pm_mode1087#ifdef CONFIG_SOC_SAMA71088ldr tmp1, [r0, #PM_DATA_PMC_MCKS]1089str tmp1, .mcks1090#endif10911092/*1093* ldrne below are here to preload their address in the TLB as access1094* to RAM may be limited while in self-refresh.1095*/1096ldr tmp1, [r0, #PM_DATA_PMC]1097str tmp1, .pmc_base1098cmp tmp1, #01099ldrne tmp2, [tmp1, #0]11001101ldr tmp1, [r0, #PM_DATA_RAMC0]1102str tmp1, .sramc_base1103cmp tmp1, #01104ldrne tmp2, [tmp1, #0]11051106ldr tmp1, [r0, #PM_DATA_RAMC1]1107str tmp1, .sramc1_base1108cmp tmp1, #01109ldrne tmp2, [tmp1, #0]11101111#ifndef CONFIG_SOC_SAM_V4_V51112/* ldrne below are here to preload their address in the TLB */1113ldr tmp1, [r0, #PM_DATA_RAMC_PHY]1114str tmp1, .sramc_phy_base1115cmp tmp1, #01116ldrne tmp2, [tmp1, #0]11171118ldr tmp1, [r0, #PM_DATA_SHDWC]1119str tmp1, .shdwc1120cmp tmp1, #01121ldrne tmp2, [tmp1, #0]11221123ldr tmp1, [r0, #PM_DATA_SFRBU]1124str tmp1, .sfrbu1125cmp tmp1, #01126ldrne tmp2, [tmp1, #0x10]1127#endif11281129/* Active the self-refresh mode */1130at91_sramc_self_refresh_ena11311132ldr r0, .pm_mode1133cmp r0, #AT91_PM_STANDBY1134beq standby1135cmp r0, #AT91_PM_BACKUP1136beq backup_mode11371138at91_ulp_mode1139b exit_suspend11401141standby:1142/* Wait for interrupt */1143ldr pmc, .pmc_base1144at91_cpu_idle1145b exit_suspend11461147backup_mode:1148at91_backup_mode11491150exit_suspend:1151/* Exit the self-refresh mode */1152at91_sramc_self_refresh_dis11531154/* Restore registers, and return */1155ldmfd sp!, {r4 - r12, pc}1156ENDPROC(at91_pm_suspend_in_sram)11571158.pmc_base:1159.word 01160.sramc_base:1161.word 01162.sramc1_base:1163.word 01164.sramc_phy_base:1165.word 01166.shdwc:1167.word 01168.sfrbu:1169.word 01170.memtype:1171.word 01172.pm_mode:1173.word 01174.mckr_offset:1175.word 01176.pmc_version:1177.word 01178#ifdef CONFIG_SOC_SAMA71179.mcks:1180.word 01181#endif1182.saved_mckr:1183.word 01184.saved_acr:1185.word 01186.saved_pllar:1187.word 01188.saved_sam9_lpr:1189.word 01190.saved_sam9_lpr1:1191.word 01192.saved_sam9_mdr:1193.word 01194.saved_sam9_mdr1:1195.word 01196.saved_osc_status:1197.word 01198#ifdef CONFIG_SOC_SAMA71199.saved_mck1:1200.word 01201.saved_mck2:1202.word 01203.saved_mck3:1204.word 01205.saved_mck4:1206.word 01207.saved_mck5:1208.word 01209.saved_mck6:1210.word 01211.saved_mck7:1212.word 01213.saved_mck8:1214.word 01215.saved_mck9:1216.word 01217#endif12181219ENTRY(at91_pm_suspend_in_sram_sz)1220.word .-at91_pm_suspend_in_sram122112221223