141d37e61SDave Gerlach/* SPDX-License-Identifier: GPL-2.0 */ 241d37e61SDave Gerlach/* 341d37e61SDave Gerlach * Low level suspend code for AM43XX SoCs 441d37e61SDave Gerlach * 583bf6db0SAlexander A. Klimov * Copyright (C) 2013-2018 Texas Instruments Incorporated - https://www.ti.com/ 641d37e61SDave Gerlach * Dave Gerlach, Vaibhav Bedia 741d37e61SDave Gerlach */ 841d37e61SDave Gerlach 941d37e61SDave Gerlach#include <linux/linkage.h> 1041d37e61SDave Gerlach#include <linux/ti-emif-sram.h> 1174655749SDave Gerlach#include <linux/platform_data/pm33xx.h> 1241d37e61SDave Gerlach#include <asm/assembler.h> 1341d37e61SDave Gerlach#include <asm/hardware/cache-l2x0.h> 14*a9ff6961SLinus Walleij#include <asm/page.h> 1541d37e61SDave Gerlach 1641d37e61SDave Gerlach#include "cm33xx.h" 1741d37e61SDave Gerlach#include "common.h" 1841d37e61SDave Gerlach#include "iomap.h" 1941d37e61SDave Gerlach#include "omap-secure.h" 2041d37e61SDave Gerlach#include "omap44xx.h" 21ccf4975dSMasahiro Yamada#include "pm-asm-offsets.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 593fe1ee40SStefan Agner .arch armv7-a 603fe1ee40SStefan Agner .arch_extension sec 6141d37e61SDave Gerlach .align 3 6241d37e61SDave Gerlach 6341d37e61SDave GerlachENTRY(am43xx_do_wfi) 6441d37e61SDave Gerlach stmfd sp!, {r4 - r11, lr} @ save registers on stack 6541d37e61SDave Gerlach 6674655749SDave Gerlach /* Save wfi_flags arg to data space */ 6774655749SDave Gerlach mov r4, r0 6874655749SDave Gerlach adr r3, am43xx_pm_ro_sram_data 6974655749SDave Gerlach ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] 7074655749SDave Gerlach str r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET] 7174655749SDave Gerlach 7203de3727SArnd Bergmann#ifdef CONFIG_CACHE_L2X0 7341d37e61SDave Gerlach /* Retrieve l2 cache virt address BEFORE we shut off EMIF */ 7441d37e61SDave Gerlach ldr r1, get_l2cache_base 7541d37e61SDave Gerlach blx r1 7641d37e61SDave Gerlach mov r8, r0 7703de3727SArnd Bergmann#endif 7841d37e61SDave Gerlach 7974655749SDave Gerlach /* Only flush cache is we know we are losing MPU context */ 8074655749SDave Gerlach tst r4, #WFI_FLAG_FLUSH_CACHE 8174655749SDave Gerlach beq cache_skip_flush 8274655749SDave Gerlach 8341d37e61SDave Gerlach /* 8441d37e61SDave Gerlach * Flush all data from the L1 and L2 data cache before disabling 8541d37e61SDave Gerlach * SCTLR.C bit. 8641d37e61SDave Gerlach */ 8741d37e61SDave Gerlach ldr r1, kernel_flush 8841d37e61SDave Gerlach blx r1 8941d37e61SDave Gerlach 9041d37e61SDave Gerlach /* 9141d37e61SDave Gerlach * Clear the SCTLR.C bit to prevent further data cache 9241d37e61SDave Gerlach * allocation. Clearing SCTLR.C would make all the data accesses 9341d37e61SDave Gerlach * strongly ordered and would not hit the cache. 9441d37e61SDave Gerlach */ 9541d37e61SDave Gerlach mrc p15, 0, r0, c1, c0, 0 9641d37e61SDave Gerlach bic r0, r0, #(1 << 2) @ Disable the C bit 9741d37e61SDave Gerlach mcr p15, 0, r0, c1, c0, 0 9841d37e61SDave Gerlach isb 9941d37e61SDave Gerlach dsb 10041d37e61SDave Gerlach 10141d37e61SDave Gerlach /* 10241d37e61SDave Gerlach * Invalidate L1 and L2 data cache. 10341d37e61SDave Gerlach */ 10441d37e61SDave Gerlach ldr r1, kernel_flush 10541d37e61SDave Gerlach blx r1 10641d37e61SDave Gerlach 10741d37e61SDave Gerlach#ifdef CONFIG_CACHE_L2X0 10841d37e61SDave Gerlach /* 10941d37e61SDave Gerlach * Clean and invalidate the L2 cache. 11041d37e61SDave Gerlach */ 11141d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915 11241d37e61SDave Gerlach mov r0, #0x03 11341d37e61SDave Gerlach mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX 11441d37e61SDave Gerlach dsb 11541d37e61SDave Gerlach smc #0 11641d37e61SDave Gerlach dsb 11741d37e61SDave Gerlach#endif 11841d37e61SDave Gerlach mov r0, r8 11941d37e61SDave Gerlach adr r4, am43xx_pm_ro_sram_data 12041d37e61SDave Gerlach ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] 12141d37e61SDave Gerlach 12241d37e61SDave Gerlach mov r2, r0 12341d37e61SDave Gerlach ldr r0, [r2, #L2X0_AUX_CTRL] 12441d37e61SDave Gerlach str r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET] 12541d37e61SDave Gerlach ldr r0, [r2, #L310_PREFETCH_CTRL] 12641d37e61SDave Gerlach str r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET] 12741d37e61SDave Gerlach 12841d37e61SDave Gerlach ldr r0, l2_val 12941d37e61SDave Gerlach str r0, [r2, #L2X0_CLEAN_INV_WAY] 13041d37e61SDave Gerlachwait: 13141d37e61SDave Gerlach ldr r0, [r2, #L2X0_CLEAN_INV_WAY] 13241d37e61SDave Gerlach ldr r1, l2_val 13341d37e61SDave Gerlach ands r0, r0, r1 13441d37e61SDave Gerlach bne wait 13541d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915 13641d37e61SDave Gerlach mov r0, #0x00 13741d37e61SDave Gerlach mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX 13841d37e61SDave Gerlach dsb 13941d37e61SDave Gerlach smc #0 14041d37e61SDave Gerlach dsb 14141d37e61SDave Gerlach#endif 14241d37e61SDave Gerlachl2x_sync: 14341d37e61SDave Gerlach mov r0, r8 14441d37e61SDave Gerlach mov r2, r0 14541d37e61SDave Gerlach mov r0, #0x0 14641d37e61SDave Gerlach str r0, [r2, #L2X0_CACHE_SYNC] 14741d37e61SDave Gerlachsync: 14841d37e61SDave Gerlach ldr r0, [r2, #L2X0_CACHE_SYNC] 14941d37e61SDave Gerlach ands r0, r0, #0x1 15041d37e61SDave Gerlach bne sync 15141d37e61SDave Gerlach#endif 15241d37e61SDave Gerlach 15374655749SDave Gerlach /* Restore wfi_flags */ 15474655749SDave Gerlach adr r3, am43xx_pm_ro_sram_data 15574655749SDave Gerlach ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] 15674655749SDave Gerlach ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET] 15774655749SDave Gerlach 15874655749SDave Gerlachcache_skip_flush: 1598c5a916fSKeerthy /* 1608c5a916fSKeerthy * If we are trying to enter RTC+DDR mode we must perform 1618c5a916fSKeerthy * a read from the rtc address space to ensure translation 1628c5a916fSKeerthy * presence in the TLB to avoid page table walk after DDR 1638c5a916fSKeerthy * is unavailable. 1648c5a916fSKeerthy */ 1658c5a916fSKeerthy tst r4, #WFI_FLAG_RTC_ONLY 1668c5a916fSKeerthy beq skip_rtc_va_refresh 1678c5a916fSKeerthy 1688c5a916fSKeerthy adr r3, am43xx_pm_ro_sram_data 1698c5a916fSKeerthy ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET] 1708c5a916fSKeerthy ldr r0, [r1] 1718c5a916fSKeerthy 1728c5a916fSKeerthyskip_rtc_va_refresh: 17374655749SDave Gerlach /* Check if we want self refresh */ 17474655749SDave Gerlach tst r4, #WFI_FLAG_SELF_REFRESH 17574655749SDave Gerlach beq emif_skip_enter_sr 17674655749SDave Gerlach 17741d37e61SDave Gerlach adr r9, am43xx_emif_sram_table 17841d37e61SDave Gerlach 17941d37e61SDave Gerlach ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET] 18041d37e61SDave Gerlach blx r3 18141d37e61SDave Gerlach 18274655749SDave Gerlachemif_skip_enter_sr: 18374655749SDave Gerlach /* Only necessary if PER is losing context */ 18474655749SDave Gerlach tst r4, #WFI_FLAG_SAVE_EMIF 18574655749SDave Gerlach beq emif_skip_save 18674655749SDave Gerlach 18741d37e61SDave Gerlach ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET] 18841d37e61SDave Gerlach blx r3 18941d37e61SDave Gerlach 19074655749SDave Gerlachemif_skip_save: 19174655749SDave Gerlach /* Only can disable EMIF if we have entered self refresh */ 19274655749SDave Gerlach tst r4, #WFI_FLAG_SELF_REFRESH 19374655749SDave Gerlach beq emif_skip_disable 19474655749SDave Gerlach 19541d37e61SDave Gerlach /* Disable EMIF */ 19641d37e61SDave Gerlach ldr r1, am43xx_virt_emif_clkctrl 19741d37e61SDave Gerlach ldr r2, [r1] 19841d37e61SDave Gerlach bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 19941d37e61SDave Gerlach str r2, [r1] 20041d37e61SDave Gerlach 20141d37e61SDave Gerlachwait_emif_disable: 20241d37e61SDave Gerlach ldr r2, [r1] 20341d37e61SDave Gerlach mov r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 20441d37e61SDave Gerlach cmp r2, r3 20541d37e61SDave Gerlach bne wait_emif_disable 20641d37e61SDave Gerlach 20774655749SDave Gerlachemif_skip_disable: 2088c5a916fSKeerthy tst r4, #WFI_FLAG_RTC_ONLY 2098c5a916fSKeerthy beq skip_rtc_only 2108c5a916fSKeerthy 2118c5a916fSKeerthy adr r3, am43xx_pm_ro_sram_data 2128c5a916fSKeerthy ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET] 2138c5a916fSKeerthy 2148c5a916fSKeerthy ldr r0, [r1, #RTC_PMIC_REG] 2158c5a916fSKeerthy orr r0, r0, #RTC_PMIC_POWER_EN 2168c5a916fSKeerthy orr r0, r0, #RTC_PMIC_EXT_WAKEUP_STS 2178c5a916fSKeerthy orr r0, r0, #RTC_PMIC_EXT_WAKEUP_EN 2188c5a916fSKeerthy orr r0, r0, #RTC_PMIC_EXT_WAKEUP_POL 2198c5a916fSKeerthy str r0, [r1, #RTC_PMIC_REG] 2208c5a916fSKeerthy ldr r0, [r1, #RTC_PMIC_REG] 2218c5a916fSKeerthy /* Wait for 2 seconds to lose power */ 2228c5a916fSKeerthy mov r3, #2 2238c5a916fSKeerthy ldr r2, [r1, #RTC_SECONDS_REG] 2248c5a916fSKeerthyrtc_loop: 2258c5a916fSKeerthy ldr r0, [r1, #RTC_SECONDS_REG] 2268c5a916fSKeerthy cmp r0, r2 2278c5a916fSKeerthy beq rtc_loop 2288c5a916fSKeerthy mov r2, r0 2298c5a916fSKeerthy subs r3, r3, #1 2308c5a916fSKeerthy bne rtc_loop 2318c5a916fSKeerthy 2328c5a916fSKeerthy b re_enable_emif 2338c5a916fSKeerthy 2348c5a916fSKeerthyskip_rtc_only: 2358c5a916fSKeerthy 23674655749SDave Gerlach tst r4, #WFI_FLAG_WAKE_M3 23774655749SDave Gerlach beq wkup_m3_skip 23874655749SDave Gerlach 23941d37e61SDave Gerlach /* 24041d37e61SDave Gerlach * For the MPU WFI to be registered as an interrupt 24141d37e61SDave Gerlach * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set 24241d37e61SDave Gerlach * to DISABLED 24341d37e61SDave Gerlach */ 24441d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkctrl 24541d37e61SDave Gerlach ldr r2, [r1] 24641d37e61SDave Gerlach bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 24741d37e61SDave Gerlach str r2, [r1] 24841d37e61SDave Gerlach 24941d37e61SDave Gerlach /* 25041d37e61SDave Gerlach * Put MPU CLKDM to SW_SLEEP 25141d37e61SDave Gerlach */ 25241d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkstctrl 25341d37e61SDave Gerlach mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP 25441d37e61SDave Gerlach str r2, [r1] 25541d37e61SDave Gerlach 25674655749SDave Gerlachwkup_m3_skip: 25741d37e61SDave Gerlach /* 25841d37e61SDave Gerlach * Execute a barrier instruction to ensure that all cache, 25941d37e61SDave Gerlach * TLB and branch predictor maintenance operations issued 26041d37e61SDave Gerlach * have completed. 26141d37e61SDave Gerlach */ 26241d37e61SDave Gerlach dsb 26341d37e61SDave Gerlach dmb 26441d37e61SDave Gerlach 26541d37e61SDave Gerlach /* 26641d37e61SDave Gerlach * Execute a WFI instruction and wait until the 26741d37e61SDave Gerlach * STANDBYWFI output is asserted to indicate that the 26841d37e61SDave Gerlach * CPU is in idle and low power state. CPU can specualatively 26941d37e61SDave Gerlach * prefetch the instructions so add NOPs after WFI. Sixteen 27041d37e61SDave Gerlach * NOPs as per Cortex-A9 pipeline. 27141d37e61SDave Gerlach */ 27241d37e61SDave Gerlach wfi 27341d37e61SDave Gerlach 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 nop 28941d37e61SDave Gerlach nop 29041d37e61SDave Gerlach 29141d37e61SDave Gerlach /* We come here in case of an abort due to a late interrupt */ 29241d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkstctrl 29341d37e61SDave Gerlach mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO 29441d37e61SDave Gerlach str r2, [r1] 29541d37e61SDave Gerlach 29641d37e61SDave Gerlach /* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */ 29741d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkctrl 29841d37e61SDave Gerlach mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 29941d37e61SDave Gerlach str r2, [r1] 30041d37e61SDave Gerlach 3018c5a916fSKeerthyre_enable_emif: 30241d37e61SDave Gerlach /* Re-enable EMIF */ 30341d37e61SDave Gerlach ldr r1, am43xx_virt_emif_clkctrl 30441d37e61SDave Gerlach mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 30541d37e61SDave Gerlach str r2, [r1] 30641d37e61SDave Gerlachwait_emif_enable: 30741d37e61SDave Gerlach ldr r3, [r1] 30841d37e61SDave Gerlach cmp r2, r3 30941d37e61SDave Gerlach bne wait_emif_enable 31041d37e61SDave Gerlach 31174655749SDave Gerlach tst r4, #WFI_FLAG_FLUSH_CACHE 31274655749SDave Gerlach beq cache_skip_restore 31374655749SDave Gerlach 31441d37e61SDave Gerlach /* 31541d37e61SDave Gerlach * Set SCTLR.C bit to allow data cache allocation 31641d37e61SDave Gerlach */ 31741d37e61SDave Gerlach mrc p15, 0, r0, c1, c0, 0 31841d37e61SDave Gerlach orr r0, r0, #(1 << 2) @ Enable the C bit 31941d37e61SDave Gerlach mcr p15, 0, r0, c1, c0, 0 32041d37e61SDave Gerlach isb 32141d37e61SDave Gerlach 32274655749SDave Gerlachcache_skip_restore: 32374655749SDave Gerlach /* Only necessary if PER is losing context */ 32474655749SDave Gerlach tst r4, #WFI_FLAG_SELF_REFRESH 32574655749SDave Gerlach beq emif_skip_exit_sr_abt 32674655749SDave Gerlach 32774655749SDave Gerlach adr r9, am43xx_emif_sram_table 32841d37e61SDave Gerlach ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET] 32941d37e61SDave Gerlach blx r1 33041d37e61SDave Gerlach 33174655749SDave Gerlachemif_skip_exit_sr_abt: 33241d37e61SDave Gerlach /* Let the suspend code know about the abort */ 33341d37e61SDave Gerlach mov r0, #1 33441d37e61SDave Gerlach ldmfd sp!, {r4 - r11, pc} @ restore regs and return 33541d37e61SDave GerlachENDPROC(am43xx_do_wfi) 33641d37e61SDave Gerlach 33741d37e61SDave Gerlach .align 33841d37e61SDave GerlachENTRY(am43xx_resume_offset) 33941d37e61SDave Gerlach .word . - am43xx_do_wfi 34041d37e61SDave Gerlach 34141d37e61SDave GerlachENTRY(am43xx_resume_from_deep_sleep) 34241d37e61SDave Gerlach /* Set MPU CLKSTCTRL to HW AUTO so that CPUidle works properly */ 34341d37e61SDave Gerlach ldr r1, am43xx_virt_mpu_clkstctrl 34441d37e61SDave Gerlach mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO 34541d37e61SDave Gerlach str r2, [r1] 34641d37e61SDave Gerlach 34741d37e61SDave Gerlach /* For AM43xx, use EMIF power down until context is restored */ 34841d37e61SDave Gerlach ldr r2, am43xx_phys_emif_poweroff 34941d37e61SDave Gerlach mov r1, #AM43XX_EMIF_POWEROFF_ENABLE 35041d37e61SDave Gerlach str r1, [r2, #0x0] 35141d37e61SDave Gerlach 35241d37e61SDave Gerlach /* Re-enable EMIF */ 35341d37e61SDave Gerlach ldr r1, am43xx_phys_emif_clkctrl 35441d37e61SDave Gerlach mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 35541d37e61SDave Gerlach str r2, [r1] 35641d37e61SDave Gerlachwait_emif_enable1: 35741d37e61SDave Gerlach ldr r3, [r1] 35841d37e61SDave Gerlach cmp r2, r3 35941d37e61SDave Gerlach bne wait_emif_enable1 36041d37e61SDave Gerlach 36141d37e61SDave Gerlach adr r9, am43xx_emif_sram_table 36241d37e61SDave Gerlach 36341d37e61SDave Gerlach ldr r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET] 36441d37e61SDave Gerlach blx r1 36541d37e61SDave Gerlach 36641d37e61SDave Gerlach ldr r1, [r9, #EMIF_PM_EXIT_SR_OFFSET] 36741d37e61SDave Gerlach blx r1 36841d37e61SDave Gerlach 36941d37e61SDave Gerlach ldr r2, am43xx_phys_emif_poweroff 37041d37e61SDave Gerlach mov r1, #AM43XX_EMIF_POWEROFF_DISABLE 37141d37e61SDave Gerlach str r1, [r2, #0x0] 37241d37e61SDave Gerlach 37311140cc4SDave Gerlach ldr r1, [r9, #EMIF_PM_RUN_HW_LEVELING] 37411140cc4SDave Gerlach blx r1 37511140cc4SDave Gerlach 37641d37e61SDave Gerlach#ifdef CONFIG_CACHE_L2X0 37741d37e61SDave Gerlach ldr r2, l2_cache_base 37841d37e61SDave Gerlach ldr r0, [r2, #L2X0_CTRL] 37941d37e61SDave Gerlach and r0, #0x0f 38041d37e61SDave Gerlach cmp r0, #1 38141d37e61SDave Gerlach beq skip_l2en @ Skip if already enabled 38241d37e61SDave Gerlach 38341d37e61SDave Gerlach adr r4, am43xx_pm_ro_sram_data 38441d37e61SDave Gerlach ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET] 38541d37e61SDave Gerlach ldr r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET] 38641d37e61SDave Gerlach 38741d37e61SDave Gerlach ldr r12, l2_smc1 38841d37e61SDave Gerlach dsb 38941d37e61SDave Gerlach smc #0 39041d37e61SDave Gerlach dsb 39141d37e61SDave Gerlachset_aux_ctrl: 39241d37e61SDave Gerlach ldr r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET] 39341d37e61SDave Gerlach ldr r12, l2_smc2 39441d37e61SDave Gerlach dsb 39541d37e61SDave Gerlach smc #0 39641d37e61SDave Gerlach dsb 39741d37e61SDave Gerlach 39841d37e61SDave Gerlach /* L2 invalidate on resume */ 39941d37e61SDave Gerlach ldr r0, l2_val 40041d37e61SDave Gerlach ldr r2, l2_cache_base 40141d37e61SDave Gerlach str r0, [r2, #L2X0_INV_WAY] 40241d37e61SDave Gerlachwait2: 40341d37e61SDave Gerlach ldr r0, [r2, #L2X0_INV_WAY] 40441d37e61SDave Gerlach ldr r1, l2_val 40541d37e61SDave Gerlach ands r0, r0, r1 40641d37e61SDave Gerlach bne wait2 40741d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915 40841d37e61SDave Gerlach mov r0, #0x00 40941d37e61SDave Gerlach mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX 41041d37e61SDave Gerlach dsb 41141d37e61SDave Gerlach smc #0 41241d37e61SDave Gerlach dsb 41341d37e61SDave Gerlach#endif 41441d37e61SDave Gerlachl2x_sync2: 41541d37e61SDave Gerlach ldr r2, l2_cache_base 41641d37e61SDave Gerlach mov r0, #0x0 41741d37e61SDave Gerlach str r0, [r2, #L2X0_CACHE_SYNC] 41841d37e61SDave Gerlachsync2: 41941d37e61SDave Gerlach ldr r0, [r2, #L2X0_CACHE_SYNC] 42041d37e61SDave Gerlach ands r0, r0, #0x1 42141d37e61SDave Gerlach bne sync2 42241d37e61SDave Gerlach 42341d37e61SDave Gerlach mov r0, #0x1 42441d37e61SDave Gerlach ldr r12, l2_smc3 42541d37e61SDave Gerlach dsb 42641d37e61SDave Gerlach smc #0 42741d37e61SDave Gerlach dsb 42841d37e61SDave Gerlach#endif 42941d37e61SDave Gerlachskip_l2en: 43041d37e61SDave Gerlach /* We are back. Branch to the common CPU resume routine */ 43141d37e61SDave Gerlach mov r0, #0 43241d37e61SDave Gerlach ldr pc, resume_addr 43341d37e61SDave GerlachENDPROC(am43xx_resume_from_deep_sleep) 43441d37e61SDave Gerlach 43541d37e61SDave Gerlach/* 43641d37e61SDave Gerlach * Local variables 43741d37e61SDave Gerlach */ 43841d37e61SDave Gerlach .align 43941d37e61SDave Gerlachkernel_flush: 44041d37e61SDave Gerlach .word v7_flush_dcache_all 44141d37e61SDave Gerlachddr_start: 44241d37e61SDave Gerlach .word PAGE_OFFSET 44341d37e61SDave Gerlach 44441d37e61SDave Gerlacham43xx_phys_emif_poweroff: 44541d37e61SDave Gerlach .word (AM43XX_CM_BASE + AM43XX_PRM_DEVICE_INST + \ 44641d37e61SDave Gerlach AM43XX_PRM_EMIF_CTRL_OFFSET) 44741d37e61SDave Gerlacham43xx_virt_mpu_clkstctrl: 44841d37e61SDave Gerlach .word (AM43XX_CM_MPU_CLKSTCTRL) 44941d37e61SDave Gerlacham43xx_virt_mpu_clkctrl: 45041d37e61SDave Gerlach .word (AM43XX_CM_MPU_MPU_CLKCTRL) 45141d37e61SDave Gerlacham43xx_virt_emif_clkctrl: 45241d37e61SDave Gerlach .word (AM43XX_CM_PER_EMIF_CLKCTRL) 45341d37e61SDave Gerlacham43xx_phys_emif_clkctrl: 45441d37e61SDave Gerlach .word (AM43XX_CM_BASE + AM43XX_CM_PER_INST + \ 45541d37e61SDave Gerlach AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET) 45641d37e61SDave Gerlach 45703de3727SArnd Bergmann#ifdef CONFIG_CACHE_L2X0 45841d37e61SDave Gerlach/* L2 cache related defines for AM437x */ 45903de3727SArnd Bergmannget_l2cache_base: 46003de3727SArnd Bergmann .word omap4_get_l2cache_base 46141d37e61SDave Gerlachl2_cache_base: 46241d37e61SDave Gerlach .word OMAP44XX_L2CACHE_BASE 46341d37e61SDave Gerlachl2_smc1: 46441d37e61SDave Gerlach .word OMAP4_MON_L2X0_PREFETCH_INDEX 46541d37e61SDave Gerlachl2_smc2: 46641d37e61SDave Gerlach .word OMAP4_MON_L2X0_AUXCTRL_INDEX 46741d37e61SDave Gerlachl2_smc3: 46841d37e61SDave Gerlach .word OMAP4_MON_L2X0_CTRL_INDEX 46941d37e61SDave Gerlachl2_val: 47041d37e61SDave Gerlach .word 0xffff 47103de3727SArnd Bergmann#endif 47241d37e61SDave Gerlach 47341d37e61SDave Gerlach.align 3 47441d37e61SDave Gerlach/* DDR related defines */ 47541d37e61SDave GerlachENTRY(am43xx_emif_sram_table) 47641d37e61SDave Gerlach .space EMIF_PM_FUNCTIONS_SIZE 47741d37e61SDave Gerlach 47841d37e61SDave GerlachENTRY(am43xx_pm_sram) 47941d37e61SDave Gerlach .word am43xx_do_wfi 48041d37e61SDave Gerlach .word am43xx_do_wfi_sz 48141d37e61SDave Gerlach .word am43xx_resume_offset 48241d37e61SDave Gerlach .word am43xx_emif_sram_table 48341d37e61SDave Gerlach .word am43xx_pm_ro_sram_data 48441d37e61SDave Gerlach 4858c5a916fSKeerthyresume_addr: 4868c5a916fSKeerthy .word cpu_resume - PAGE_OFFSET + 0x80000000 48741d37e61SDave Gerlach.align 3 48841d37e61SDave Gerlach 48941d37e61SDave GerlachENTRY(am43xx_pm_ro_sram_data) 49041d37e61SDave Gerlach .space AMX3_PM_RO_SRAM_DATA_SIZE 49141d37e61SDave Gerlach 49241d37e61SDave GerlachENTRY(am43xx_do_wfi_sz) 49341d37e61SDave Gerlach .word . - am43xx_do_wfi 494