141d37e61SDave Gerlach/* SPDX-License-Identifier: GPL-2.0 */ 241d37e61SDave Gerlach/* 341d37e61SDave Gerlach * Low level suspend code for AM43XX SoCs 441d37e61SDave Gerlach * 541d37e61SDave Gerlach * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/ 641d37e61SDave Gerlach * Dave Gerlach, Vaibhav Bedia 741d37e61SDave Gerlach */ 841d37e61SDave Gerlach 941d9d44dSDave Gerlach#include <generated/ti-pm-asm-offsets.h> 1041d37e61SDave Gerlach#include <linux/linkage.h> 1141d37e61SDave Gerlach#include <linux/ti-emif-sram.h> 1274655749SDave Gerlach#include <linux/platform_data/pm33xx.h> 1341d37e61SDave Gerlach#include <asm/assembler.h> 1441d37e61SDave Gerlach#include <asm/hardware/cache-l2x0.h> 1541d37e61SDave Gerlach#include <asm/memory.h> 1641d37e61SDave Gerlach 1741d37e61SDave Gerlach#include "cm33xx.h" 1841d37e61SDave Gerlach#include "common.h" 1941d37e61SDave Gerlach#include "iomap.h" 2041d37e61SDave Gerlach#include "omap-secure.h" 2141d37e61SDave Gerlach#include "omap44xx.h" 2241d37e61SDave Gerlach#include "prm33xx.h" 2341d37e61SDave Gerlach#include "prcm43xx.h" 2441d37e61SDave Gerlach 2574655749SDave Gerlach/* replicated define because linux/bitops.h cannot be included in assembly */ 2674655749SDave Gerlach#define BIT(nr) (1 << (nr)) 2774655749SDave Gerlach 2841d37e61SDave Gerlach#define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x00030000 2941d37e61SDave Gerlach#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003 3041d37e61SDave Gerlach#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002 3141d37e61SDave Gerlach 3241d37e61SDave Gerlach#define AM43XX_EMIF_POWEROFF_ENABLE 0x1 3341d37e61SDave Gerlach#define AM43XX_EMIF_POWEROFF_DISABLE 0x0 3441d37e61SDave Gerlach 3541d37e61SDave Gerlach#define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP 0x1 3641d37e61SDave Gerlach#define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO 0x3 3741d37e61SDave Gerlach 3841d37e61SDave Gerlach#define AM43XX_CM_BASE 0x44DF0000 3941d37e61SDave Gerlach 4041d37e61SDave Gerlach#define AM43XX_CM_REGADDR(inst, reg) \ 4141d37e61SDave Gerlach AM33XX_L4_WK_IO_ADDRESS(AM43XX_CM_BASE + (inst) + (reg)) 4241d37e61SDave Gerlach 4341d37e61SDave Gerlach#define AM43XX_CM_MPU_CLKSTCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \ 4441d37e61SDave Gerlach AM43XX_CM_MPU_MPU_CDOFFS) 4541d37e61SDave Gerlach#define AM43XX_CM_MPU_MPU_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \ 4641d37e61SDave Gerlach AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET) 4741d37e61SDave Gerlach#define AM43XX_CM_PER_EMIF_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_PER_INST, \ 4841d37e61SDave Gerlach AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET) 4941d37e61SDave Gerlach#define AM43XX_PRM_EMIF_CTRL_OFFSET 0x0030 5041d37e61SDave Gerlach 518c5a916fSKeerthy#define RTC_SECONDS_REG 0x0 528c5a916fSKeerthy#define RTC_PMIC_REG 0x98 538c5a916fSKeerthy#define RTC_PMIC_POWER_EN BIT(16) 548c5a916fSKeerthy#define RTC_PMIC_EXT_WAKEUP_STS BIT(12) 558c5a916fSKeerthy#define RTC_PMIC_EXT_WAKEUP_POL BIT(4) 568c5a916fSKeerthy#define RTC_PMIC_EXT_WAKEUP_EN BIT(0) 578c5a916fSKeerthy 5841d37e61SDave Gerlach .arm 5941d37e61SDave Gerlach .align 3 6041d37e61SDave Gerlach 6141d37e61SDave GerlachENTRY(am43xx_do_wfi) 6241d37e61SDave Gerlach stmfd sp!, {r4 - r11, lr} @ save registers on stack 6341d37e61SDave Gerlach 6474655749SDave Gerlach /* Save wfi_flags arg to data space */ 6574655749SDave Gerlach mov r4, r0 6674655749SDave Gerlach adr r3, am43xx_pm_ro_sram_data 6774655749SDave Gerlach ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] 6874655749SDave Gerlach str r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET] 6974655749SDave Gerlach 7003de3727SArnd Bergmann#ifdef CONFIG_CACHE_L2X0 7141d37e61SDave Gerlach /* Retrieve l2 cache virt address BEFORE we shut off EMIF */ 7241d37e61SDave Gerlach ldr r1, get_l2cache_base 7341d37e61SDave Gerlach blx r1 7441d37e61SDave Gerlach mov r8, r0 7503de3727SArnd Bergmann#endif 7641d37e61SDave Gerlach 7774655749SDave Gerlach /* Only flush cache is we know we are losing MPU context */ 7874655749SDave Gerlach tst r4, #WFI_FLAG_FLUSH_CACHE 7974655749SDave Gerlach beq cache_skip_flush 8074655749SDave Gerlach 8141d37e61SDave Gerlach /* 8241d37e61SDave Gerlach * Flush all data from the L1 and L2 data cache before disabling 8341d37e61SDave Gerlach * SCTLR.C bit. 8441d37e61SDave Gerlach */ 8541d37e61SDave Gerlach ldr r1, kernel_flush 8641d37e61SDave Gerlach blx r1 8741d37e61SDave Gerlach 8841d37e61SDave Gerlach /* 8941d37e61SDave Gerlach * Clear the SCTLR.C bit to prevent further data cache 9041d37e61SDave Gerlach * allocation. Clearing SCTLR.C would make all the data accesses 9141d37e61SDave Gerlach * strongly ordered and would not hit the cache. 9241d37e61SDave Gerlach */ 9341d37e61SDave Gerlach mrc p15, 0, r0, c1, c0, 0 9441d37e61SDave Gerlach bic r0, r0, #(1 << 2) @ Disable the C bit 9541d37e61SDave Gerlach mcr p15, 0, r0, c1, c0, 0 9641d37e61SDave Gerlach isb 9741d37e61SDave Gerlach dsb 9841d37e61SDave Gerlach 9941d37e61SDave Gerlach /* 10041d37e61SDave Gerlach * Invalidate L1 and L2 data cache. 10141d37e61SDave Gerlach */ 10241d37e61SDave Gerlach ldr r1, kernel_flush 10341d37e61SDave Gerlach blx r1 10441d37e61SDave Gerlach 10541d37e61SDave Gerlach#ifdef CONFIG_CACHE_L2X0 10641d37e61SDave Gerlach /* 10741d37e61SDave Gerlach * Clean and invalidate the L2 cache. 10841d37e61SDave Gerlach */ 10941d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915 11041d37e61SDave Gerlach mov r0, #0x03 11141d37e61SDave Gerlach mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX 11241d37e61SDave Gerlach dsb 11341d37e61SDave Gerlach smc #0 11441d37e61SDave Gerlach dsb 11541d37e61SDave Gerlach#endif 11641d37e61SDave Gerlach mov r0, r8 11741d37e61SDave Gerlach adr r4, am43xx_pm_ro_sram_data 11841d37e61SDave Gerlach ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] 11941d37e61SDave Gerlach 12041d37e61SDave Gerlach mov r2, r0 12141d37e61SDave Gerlach ldr r0, [r2, #L2X0_AUX_CTRL] 12241d37e61SDave Gerlach str r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET] 12341d37e61SDave Gerlach ldr r0, [r2, #L310_PREFETCH_CTRL] 12441d37e61SDave Gerlach str r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET] 12541d37e61SDave Gerlach 12641d37e61SDave Gerlach ldr r0, l2_val 12741d37e61SDave Gerlach str r0, [r2, #L2X0_CLEAN_INV_WAY] 12841d37e61SDave Gerlachwait: 12941d37e61SDave Gerlach ldr r0, [r2, #L2X0_CLEAN_INV_WAY] 13041d37e61SDave Gerlach ldr r1, l2_val 13141d37e61SDave Gerlach ands r0, r0, r1 13241d37e61SDave Gerlach bne wait 13341d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915 13441d37e61SDave Gerlach mov r0, #0x00 13541d37e61SDave Gerlach mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX 13641d37e61SDave Gerlach dsb 13741d37e61SDave Gerlach smc #0 13841d37e61SDave Gerlach dsb 13941d37e61SDave Gerlach#endif 14041d37e61SDave Gerlachl2x_sync: 14141d37e61SDave Gerlach mov r0, r8 14241d37e61SDave Gerlach mov r2, r0 14341d37e61SDave Gerlach mov r0, #0x0 14441d37e61SDave Gerlach str r0, [r2, #L2X0_CACHE_SYNC] 14541d37e61SDave Gerlachsync: 14641d37e61SDave Gerlach ldr r0, [r2, #L2X0_CACHE_SYNC] 14741d37e61SDave Gerlach ands r0, r0, #0x1 14841d37e61SDave Gerlach bne sync 14941d37e61SDave Gerlach#endif 15041d37e61SDave Gerlach 15174655749SDave Gerlach /* Restore wfi_flags */ 15274655749SDave Gerlach adr r3, am43xx_pm_ro_sram_data 15374655749SDave Gerlach ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] 15474655749SDave Gerlach ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET] 15574655749SDave Gerlach 15674655749SDave Gerlachcache_skip_flush: 1578c5a916fSKeerthy /* 1588c5a916fSKeerthy * If we are trying to enter RTC+DDR mode we must perform 1598c5a916fSKeerthy * a read from the rtc address space to ensure translation 1608c5a916fSKeerthy * presence in the TLB to avoid page table walk after DDR 1618c5a916fSKeerthy * is unavailable. 1628c5a916fSKeerthy */ 1638c5a916fSKeerthy tst r4, #WFI_FLAG_RTC_ONLY 1648c5a916fSKeerthy beq skip_rtc_va_refresh 1658c5a916fSKeerthy 1668c5a916fSKeerthy adr r3, am43xx_pm_ro_sram_data 1678c5a916fSKeerthy ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET] 1688c5a916fSKeerthy ldr r0, [r1] 1698c5a916fSKeerthy 1708c5a916fSKeerthyskip_rtc_va_refresh: 17174655749SDave Gerlach /* Check if we want self refresh */ 17274655749SDave Gerlach tst r4, #WFI_FLAG_SELF_REFRESH 17374655749SDave Gerlach beq emif_skip_enter_sr 17474655749SDave Gerlach 17541d37e61SDave Gerlach adr r9, am43xx_emif_sram_table 17641d37e61SDave Gerlach 17741d37e61SDave Gerlach ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET] 17841d37e61SDave Gerlach blx r3 17941d37e61SDave Gerlach 18074655749SDave Gerlachemif_skip_enter_sr: 18174655749SDave Gerlach /* Only necessary if PER is losing context */ 18274655749SDave Gerlach tst r4, #WFI_FLAG_SAVE_EMIF 18374655749SDave Gerlach beq emif_skip_save 18474655749SDave Gerlach 18541d37e61SDave Gerlach ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET] 18641d37e61SDave Gerlach blx r3 18741d37e61SDave Gerlach 18874655749SDave Gerlachemif_skip_save: 18974655749SDave Gerlach /* Only can disable EMIF if we have entered self refresh */ 19074655749SDave Gerlach tst r4, #WFI_FLAG_SELF_REFRESH 19174655749SDave Gerlach beq emif_skip_disable 19274655749SDave Gerlach 19341d37e61SDave Gerlach /* Disable EMIF */ 19441d37e61SDave Gerlach ldr r1, am43xx_virt_emif_clkctrl 19541d37e61SDave Gerlach ldr r2, [r1] 19641d37e61SDave Gerlach bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 19741d37e61SDave Gerlach str r2, [r1] 19841d37e61SDave Gerlach 19941d37e61SDave Gerlachwait_emif_disable: 20041d37e61SDave Gerlach ldr r2, [r1] 20141d37e61SDave Gerlach mov r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 20241d37e61SDave Gerlach cmp r2, r3 20341d37e61SDave Gerlach bne wait_emif_disable 20441d37e61SDave Gerlach 20574655749SDave Gerlachemif_skip_disable: 2068c5a916fSKeerthy tst r4, #WFI_FLAG_RTC_ONLY 2078c5a916fSKeerthy beq skip_rtc_only 2088c5a916fSKeerthy 2098c5a916fSKeerthy adr r3, am43xx_pm_ro_sram_data 2108c5a916fSKeerthy ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET] 2118c5a916fSKeerthy 2128c5a916fSKeerthy ldr r0, [r1, #RTC_PMIC_REG] 2138c5a916fSKeerthy orr r0, r0, #RTC_PMIC_POWER_EN 2148c5a916fSKeerthy orr r0, r0, #RTC_PMIC_EXT_WAKEUP_STS 2158c5a916fSKeerthy orr r0, r0, #RTC_PMIC_EXT_WAKEUP_EN 2168c5a916fSKeerthy orr r0, r0, #RTC_PMIC_EXT_WAKEUP_POL 2178c5a916fSKeerthy str r0, [r1, #RTC_PMIC_REG] 2188c5a916fSKeerthy ldr r0, [r1, #RTC_PMIC_REG] 2198c5a916fSKeerthy /* Wait for 2 seconds to lose power */ 2208c5a916fSKeerthy mov r3, #2 2218c5a916fSKeerthy ldr r2, [r1, #RTC_SECONDS_REG] 2228c5a916fSKeerthyrtc_loop: 2238c5a916fSKeerthy ldr r0, [r1, #RTC_SECONDS_REG] 2248c5a916fSKeerthy cmp r0, r2 2258c5a916fSKeerthy beq rtc_loop 2268c5a916fSKeerthy mov r2, r0 2278c5a916fSKeerthy subs r3, r3, #1 2288c5a916fSKeerthy bne rtc_loop 2298c5a916fSKeerthy 2308c5a916fSKeerthy b re_enable_emif 2318c5a916fSKeerthy 2328c5a916fSKeerthyskip_rtc_only: 2338c5a916fSKeerthy 23474655749SDave Gerlach tst r4, #WFI_FLAG_WAKE_M3 23574655749SDave Gerlach beq wkup_m3_skip 23674655749SDave Gerlach 23741d37e61SDave Gerlach /* 23841d37e61SDave Gerlach * For the MPU WFI to be registered as an interrupt 23941d37e61SDave Gerlach * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set 24041d37e61SDave Gerlach * to DISABLED 24141d37e61SDave Gerlach */ 24241d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkctrl 24341d37e61SDave Gerlach ldr r2, [r1] 24441d37e61SDave Gerlach bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 24541d37e61SDave Gerlach str r2, [r1] 24641d37e61SDave Gerlach 24741d37e61SDave Gerlach /* 24841d37e61SDave Gerlach * Put MPU CLKDM to SW_SLEEP 24941d37e61SDave Gerlach */ 25041d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkstctrl 25141d37e61SDave Gerlach mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP 25241d37e61SDave Gerlach str r2, [r1] 25341d37e61SDave Gerlach 25474655749SDave Gerlachwkup_m3_skip: 25541d37e61SDave Gerlach /* 25641d37e61SDave Gerlach * Execute a barrier instruction to ensure that all cache, 25741d37e61SDave Gerlach * TLB and branch predictor maintenance operations issued 25841d37e61SDave Gerlach * have completed. 25941d37e61SDave Gerlach */ 26041d37e61SDave Gerlach dsb 26141d37e61SDave Gerlach dmb 26241d37e61SDave Gerlach 26341d37e61SDave Gerlach /* 26441d37e61SDave Gerlach * Execute a WFI instruction and wait until the 26541d37e61SDave Gerlach * STANDBYWFI output is asserted to indicate that the 26641d37e61SDave Gerlach * CPU is in idle and low power state. CPU can specualatively 26741d37e61SDave Gerlach * prefetch the instructions so add NOPs after WFI. Sixteen 26841d37e61SDave Gerlach * NOPs as per Cortex-A9 pipeline. 26941d37e61SDave Gerlach */ 27041d37e61SDave Gerlach wfi 27141d37e61SDave Gerlach 27241d37e61SDave Gerlach nop 27341d37e61SDave Gerlach nop 27441d37e61SDave Gerlach nop 27541d37e61SDave Gerlach nop 27641d37e61SDave Gerlach nop 27741d37e61SDave Gerlach nop 27841d37e61SDave Gerlach nop 27941d37e61SDave Gerlach nop 28041d37e61SDave Gerlach nop 28141d37e61SDave Gerlach nop 28241d37e61SDave Gerlach nop 28341d37e61SDave Gerlach nop 28441d37e61SDave Gerlach nop 28541d37e61SDave Gerlach nop 28641d37e61SDave Gerlach nop 28741d37e61SDave Gerlach nop 28841d37e61SDave Gerlach 28941d37e61SDave Gerlach /* We come here in case of an abort due to a late interrupt */ 29041d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkstctrl 29141d37e61SDave Gerlach mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO 29241d37e61SDave Gerlach str r2, [r1] 29341d37e61SDave Gerlach 29441d37e61SDave Gerlach /* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */ 29541d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkctrl 29641d37e61SDave Gerlach mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 29741d37e61SDave Gerlach str r2, [r1] 29841d37e61SDave Gerlach 2998c5a916fSKeerthyre_enable_emif: 30041d37e61SDave Gerlach /* Re-enable EMIF */ 30141d37e61SDave Gerlach ldr r1, am43xx_virt_emif_clkctrl 30241d37e61SDave Gerlach mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 30341d37e61SDave Gerlach str r2, [r1] 30441d37e61SDave Gerlachwait_emif_enable: 30541d37e61SDave Gerlach ldr r3, [r1] 30641d37e61SDave Gerlach cmp r2, r3 30741d37e61SDave Gerlach bne wait_emif_enable 30841d37e61SDave Gerlach 30974655749SDave Gerlach tst r4, #WFI_FLAG_FLUSH_CACHE 31074655749SDave Gerlach beq cache_skip_restore 31174655749SDave Gerlach 31241d37e61SDave Gerlach /* 31341d37e61SDave Gerlach * Set SCTLR.C bit to allow data cache allocation 31441d37e61SDave Gerlach */ 31541d37e61SDave Gerlach mrc p15, 0, r0, c1, c0, 0 31641d37e61SDave Gerlach orr r0, r0, #(1 << 2) @ Enable the C bit 31741d37e61SDave Gerlach mcr p15, 0, r0, c1, c0, 0 31841d37e61SDave Gerlach isb 31941d37e61SDave Gerlach 32074655749SDave Gerlachcache_skip_restore: 32174655749SDave Gerlach /* Only necessary if PER is losing context */ 32274655749SDave Gerlach tst r4, #WFI_FLAG_SELF_REFRESH 32374655749SDave Gerlach beq emif_skip_exit_sr_abt 32474655749SDave Gerlach 32574655749SDave Gerlach adr r9, am43xx_emif_sram_table 32641d37e61SDave Gerlach ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET] 32741d37e61SDave Gerlach blx r1 32841d37e61SDave Gerlach 32974655749SDave Gerlachemif_skip_exit_sr_abt: 33041d37e61SDave Gerlach /* Let the suspend code know about the abort */ 33141d37e61SDave Gerlach mov r0, #1 33241d37e61SDave Gerlach ldmfd sp!, {r4 - r11, pc} @ restore regs and return 33341d37e61SDave GerlachENDPROC(am43xx_do_wfi) 33441d37e61SDave Gerlach 33541d37e61SDave Gerlach .align 33641d37e61SDave GerlachENTRY(am43xx_resume_offset) 33741d37e61SDave Gerlach .word . - am43xx_do_wfi 33841d37e61SDave Gerlach 33941d37e61SDave GerlachENTRY(am43xx_resume_from_deep_sleep) 34041d37e61SDave Gerlach /* Set MPU CLKSTCTRL to HW AUTO so that CPUidle works properly */ 34141d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkstctrl 34241d37e61SDave Gerlach mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO 34341d37e61SDave Gerlach str r2, [r1] 34441d37e61SDave Gerlach 34541d37e61SDave Gerlach /* For AM43xx, use EMIF power down until context is restored */ 34641d37e61SDave Gerlach ldr r2, am43xx_phys_emif_poweroff 34741d37e61SDave Gerlach mov r1, #AM43XX_EMIF_POWEROFF_ENABLE 34841d37e61SDave Gerlach str r1, [r2, #0x0] 34941d37e61SDave Gerlach 35041d37e61SDave Gerlach /* Re-enable EMIF */ 35141d37e61SDave Gerlach ldr r1, am43xx_phys_emif_clkctrl 35241d37e61SDave Gerlach mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 35341d37e61SDave Gerlach str r2, [r1] 35441d37e61SDave Gerlachwait_emif_enable1: 35541d37e61SDave Gerlach ldr r3, [r1] 35641d37e61SDave Gerlach cmp r2, r3 35741d37e61SDave Gerlach bne wait_emif_enable1 35841d37e61SDave Gerlach 35941d37e61SDave Gerlach adr r9, am43xx_emif_sram_table 36041d37e61SDave Gerlach 36141d37e61SDave Gerlach ldr r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET] 36241d37e61SDave Gerlach blx r1 36341d37e61SDave Gerlach 36441d37e61SDave Gerlach ldr r1, [r9, #EMIF_PM_EXIT_SR_OFFSET] 36541d37e61SDave Gerlach blx r1 36641d37e61SDave Gerlach 36741d37e61SDave Gerlach ldr r2, am43xx_phys_emif_poweroff 36841d37e61SDave Gerlach mov r1, #AM43XX_EMIF_POWEROFF_DISABLE 36941d37e61SDave Gerlach str r1, [r2, #0x0] 37041d37e61SDave Gerlach 371*11140cc4SDave Gerlach ldr r1, [r9, #EMIF_PM_RUN_HW_LEVELING] 372*11140cc4SDave Gerlach blx r1 373*11140cc4SDave Gerlach 37441d37e61SDave Gerlach#ifdef CONFIG_CACHE_L2X0 37541d37e61SDave Gerlach ldr r2, l2_cache_base 37641d37e61SDave Gerlach ldr r0, [r2, #L2X0_CTRL] 37741d37e61SDave Gerlach and r0, #0x0f 37841d37e61SDave Gerlach cmp r0, #1 37941d37e61SDave Gerlach beq skip_l2en @ Skip if already enabled 38041d37e61SDave Gerlach 38141d37e61SDave Gerlach adr r4, am43xx_pm_ro_sram_data 38241d37e61SDave Gerlach ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET] 38341d37e61SDave Gerlach ldr r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET] 38441d37e61SDave Gerlach 38541d37e61SDave Gerlach ldr r12, l2_smc1 38641d37e61SDave Gerlach dsb 38741d37e61SDave Gerlach smc #0 38841d37e61SDave Gerlach dsb 38941d37e61SDave Gerlachset_aux_ctrl: 39041d37e61SDave Gerlach ldr r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET] 39141d37e61SDave Gerlach ldr r12, l2_smc2 39241d37e61SDave Gerlach dsb 39341d37e61SDave Gerlach smc #0 39441d37e61SDave Gerlach dsb 39541d37e61SDave Gerlach 39641d37e61SDave Gerlach /* L2 invalidate on resume */ 39741d37e61SDave Gerlach ldr r0, l2_val 39841d37e61SDave Gerlach ldr r2, l2_cache_base 39941d37e61SDave Gerlach str r0, [r2, #L2X0_INV_WAY] 40041d37e61SDave Gerlachwait2: 40141d37e61SDave Gerlach ldr r0, [r2, #L2X0_INV_WAY] 40241d37e61SDave Gerlach ldr r1, l2_val 40341d37e61SDave Gerlach ands r0, r0, r1 40441d37e61SDave Gerlach bne wait2 40541d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915 40641d37e61SDave Gerlach mov r0, #0x00 40741d37e61SDave Gerlach mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX 40841d37e61SDave Gerlach dsb 40941d37e61SDave Gerlach smc #0 41041d37e61SDave Gerlach dsb 41141d37e61SDave Gerlach#endif 41241d37e61SDave Gerlachl2x_sync2: 41341d37e61SDave Gerlach ldr r2, l2_cache_base 41441d37e61SDave Gerlach mov r0, #0x0 41541d37e61SDave Gerlach str r0, [r2, #L2X0_CACHE_SYNC] 41641d37e61SDave Gerlachsync2: 41741d37e61SDave Gerlach ldr r0, [r2, #L2X0_CACHE_SYNC] 41841d37e61SDave Gerlach ands r0, r0, #0x1 41941d37e61SDave Gerlach bne sync2 42041d37e61SDave Gerlach 42141d37e61SDave Gerlach mov r0, #0x1 42241d37e61SDave Gerlach ldr r12, l2_smc3 42341d37e61SDave Gerlach dsb 42441d37e61SDave Gerlach smc #0 42541d37e61SDave Gerlach dsb 42641d37e61SDave Gerlach#endif 42741d37e61SDave Gerlachskip_l2en: 42841d37e61SDave Gerlach /* We are back. Branch to the common CPU resume routine */ 42941d37e61SDave Gerlach mov r0, #0 43041d37e61SDave Gerlach ldr pc, resume_addr 43141d37e61SDave GerlachENDPROC(am43xx_resume_from_deep_sleep) 43241d37e61SDave Gerlach 43341d37e61SDave Gerlach/* 43441d37e61SDave Gerlach * Local variables 43541d37e61SDave Gerlach */ 43641d37e61SDave Gerlach .align 43741d37e61SDave Gerlachkernel_flush: 43841d37e61SDave Gerlach .word v7_flush_dcache_all 43941d37e61SDave Gerlachddr_start: 44041d37e61SDave Gerlach .word PAGE_OFFSET 44141d37e61SDave Gerlach 44241d37e61SDave Gerlacham43xx_phys_emif_poweroff: 44341d37e61SDave Gerlach .word (AM43XX_CM_BASE + AM43XX_PRM_DEVICE_INST + \ 44441d37e61SDave Gerlach AM43XX_PRM_EMIF_CTRL_OFFSET) 44541d37e61SDave Gerlacham43xx_virt_mpu_clkstctrl: 44641d37e61SDave Gerlach .word (AM43XX_CM_MPU_CLKSTCTRL) 44741d37e61SDave Gerlacham43xx_virt_mpu_clkctrl: 44841d37e61SDave Gerlach .word (AM43XX_CM_MPU_MPU_CLKCTRL) 44941d37e61SDave Gerlacham43xx_virt_emif_clkctrl: 45041d37e61SDave Gerlach .word (AM43XX_CM_PER_EMIF_CLKCTRL) 45141d37e61SDave Gerlacham43xx_phys_emif_clkctrl: 45241d37e61SDave Gerlach .word (AM43XX_CM_BASE + AM43XX_CM_PER_INST + \ 45341d37e61SDave Gerlach AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET) 45441d37e61SDave Gerlach 45503de3727SArnd Bergmann#ifdef CONFIG_CACHE_L2X0 45641d37e61SDave Gerlach/* L2 cache related defines for AM437x */ 45703de3727SArnd Bergmannget_l2cache_base: 45803de3727SArnd Bergmann .word omap4_get_l2cache_base 45941d37e61SDave Gerlachl2_cache_base: 46041d37e61SDave Gerlach .word OMAP44XX_L2CACHE_BASE 46141d37e61SDave Gerlachl2_smc1: 46241d37e61SDave Gerlach .word OMAP4_MON_L2X0_PREFETCH_INDEX 46341d37e61SDave Gerlachl2_smc2: 46441d37e61SDave Gerlach .word OMAP4_MON_L2X0_AUXCTRL_INDEX 46541d37e61SDave Gerlachl2_smc3: 46641d37e61SDave Gerlach .word OMAP4_MON_L2X0_CTRL_INDEX 46741d37e61SDave Gerlachl2_val: 46841d37e61SDave Gerlach .word 0xffff 46903de3727SArnd Bergmann#endif 47041d37e61SDave Gerlach 47141d37e61SDave Gerlach.align 3 47241d37e61SDave Gerlach/* DDR related defines */ 47341d37e61SDave GerlachENTRY(am43xx_emif_sram_table) 47441d37e61SDave Gerlach .space EMIF_PM_FUNCTIONS_SIZE 47541d37e61SDave Gerlach 47641d37e61SDave GerlachENTRY(am43xx_pm_sram) 47741d37e61SDave Gerlach .word am43xx_do_wfi 47841d37e61SDave Gerlach .word am43xx_do_wfi_sz 47941d37e61SDave Gerlach .word am43xx_resume_offset 48041d37e61SDave Gerlach .word am43xx_emif_sram_table 48141d37e61SDave Gerlach .word am43xx_pm_ro_sram_data 48241d37e61SDave Gerlach 4838c5a916fSKeerthyresume_addr: 4848c5a916fSKeerthy .word cpu_resume - PAGE_OFFSET + 0x80000000 48541d37e61SDave Gerlach.align 3 48641d37e61SDave Gerlach 48741d37e61SDave GerlachENTRY(am43xx_pm_ro_sram_data) 48841d37e61SDave Gerlach .space AMX3_PM_RO_SRAM_DATA_SIZE 48941d37e61SDave Gerlach 49041d37e61SDave GerlachENTRY(am43xx_do_wfi_sz) 49141d37e61SDave Gerlach .word . - am43xx_do_wfi 492