12aec85b2SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 28428e5adSDave Gerlach/* 38428e5adSDave Gerlach * Low level PM code for TI EMIF 48428e5adSDave Gerlach * 58428e5adSDave Gerlach * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/ 68428e5adSDave Gerlach * Dave Gerlach 78428e5adSDave Gerlach */ 88428e5adSDave Gerlach 98428e5adSDave Gerlach#include <linux/linkage.h> 108428e5adSDave Gerlach#include <asm/assembler.h> 11*a9ff6961SLinus Walleij#include <asm/page.h> 128428e5adSDave Gerlach 138428e5adSDave Gerlach#include "emif.h" 14eef58fddSMasahiro Yamada#include "ti-emif-asm-offsets.h" 158428e5adSDave Gerlach 168428e5adSDave Gerlach#define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES 0x00a0 178428e5adSDave Gerlach#define EMIF_POWER_MGMT_SR_TIMER_MASK 0x00f0 188428e5adSDave Gerlach#define EMIF_POWER_MGMT_SELF_REFRESH_MODE 0x0200 198428e5adSDave Gerlach#define EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 0x0700 208428e5adSDave Gerlach 218428e5adSDave Gerlach#define EMIF_SDCFG_TYPE_DDR2 0x2 << SDRAM_TYPE_SHIFT 226c110561SDave Gerlach#define EMIF_SDCFG_TYPE_DDR3 0x3 << SDRAM_TYPE_SHIFT 238428e5adSDave Gerlach#define EMIF_STATUS_READY 0x4 248428e5adSDave Gerlach 258428e5adSDave Gerlach#define AM43XX_EMIF_PHY_CTRL_REG_COUNT 0x120 268428e5adSDave Gerlach 278428e5adSDave Gerlach#define EMIF_AM437X_REGISTERS 0x1 288428e5adSDave Gerlach 298428e5adSDave Gerlach .arm 308428e5adSDave Gerlach .align 3 31a2faac39SNick Desaulniers .arch armv7-a 328428e5adSDave Gerlach 338428e5adSDave GerlachENTRY(ti_emif_sram) 348428e5adSDave Gerlach 358428e5adSDave Gerlach/* 368428e5adSDave Gerlach * void ti_emif_save_context(void) 378428e5adSDave Gerlach * 388428e5adSDave Gerlach * Used during suspend to save the context of all required EMIF registers 398428e5adSDave Gerlach * to local memory if the EMIF is going to lose context during the sleep 408428e5adSDave Gerlach * transition. Operates on the VIRTUAL address of the EMIF. 418428e5adSDave Gerlach */ 428428e5adSDave GerlachENTRY(ti_emif_save_context) 438428e5adSDave Gerlach stmfd sp!, {r4 - r11, lr} @ save registers on stack 448428e5adSDave Gerlach 458428e5adSDave Gerlach adr r4, ti_emif_pm_sram_data 468428e5adSDave Gerlach ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET] 478428e5adSDave Gerlach ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET] 488428e5adSDave Gerlach 498428e5adSDave Gerlach /* Save EMIF configuration */ 508428e5adSDave Gerlach ldr r1, [r0, #EMIF_SDRAM_CONFIG] 518428e5adSDave Gerlach str r1, [r2, #EMIF_SDCFG_VAL_OFFSET] 528428e5adSDave Gerlach 538428e5adSDave Gerlach ldr r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL] 548428e5adSDave Gerlach str r1, [r2, #EMIF_REF_CTRL_VAL_OFFSET] 558428e5adSDave Gerlach 568428e5adSDave Gerlach ldr r1, [r0, #EMIF_SDRAM_TIMING_1] 578428e5adSDave Gerlach str r1, [r2, #EMIF_TIMING1_VAL_OFFSET] 588428e5adSDave Gerlach 598428e5adSDave Gerlach ldr r1, [r0, #EMIF_SDRAM_TIMING_2] 608428e5adSDave Gerlach str r1, [r2, #EMIF_TIMING2_VAL_OFFSET] 618428e5adSDave Gerlach 628428e5adSDave Gerlach ldr r1, [r0, #EMIF_SDRAM_TIMING_3] 638428e5adSDave Gerlach str r1, [r2, #EMIF_TIMING3_VAL_OFFSET] 648428e5adSDave Gerlach 658428e5adSDave Gerlach ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] 668428e5adSDave Gerlach str r1, [r2, #EMIF_PMCR_VAL_OFFSET] 678428e5adSDave Gerlach 688428e5adSDave Gerlach ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW] 698428e5adSDave Gerlach str r1, [r2, #EMIF_PMCR_SHDW_VAL_OFFSET] 708428e5adSDave Gerlach 718428e5adSDave Gerlach ldr r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG] 728428e5adSDave Gerlach str r1, [r2, #EMIF_ZQCFG_VAL_OFFSET] 738428e5adSDave Gerlach 748428e5adSDave Gerlach ldr r1, [r0, #EMIF_DDR_PHY_CTRL_1] 758428e5adSDave Gerlach str r1, [r2, #EMIF_DDR_PHY_CTLR_1_OFFSET] 768428e5adSDave Gerlach 778428e5adSDave Gerlach ldr r1, [r0, #EMIF_COS_CONFIG] 788428e5adSDave Gerlach str r1, [r2, #EMIF_COS_CONFIG_OFFSET] 798428e5adSDave Gerlach 808428e5adSDave Gerlach ldr r1, [r0, #EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING] 818428e5adSDave Gerlach str r1, [r2, #EMIF_PRIORITY_TO_COS_MAPPING_OFFSET] 828428e5adSDave Gerlach 838428e5adSDave Gerlach ldr r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING] 848428e5adSDave Gerlach str r1, [r2, #EMIF_CONNECT_ID_SERV_1_MAP_OFFSET] 858428e5adSDave Gerlach 868428e5adSDave Gerlach ldr r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING] 878428e5adSDave Gerlach str r1, [r2, #EMIF_CONNECT_ID_SERV_2_MAP_OFFSET] 888428e5adSDave Gerlach 898428e5adSDave Gerlach ldr r1, [r0, #EMIF_OCP_CONFIG] 908428e5adSDave Gerlach str r1, [r2, #EMIF_OCP_CONFIG_VAL_OFFSET] 918428e5adSDave Gerlach 928428e5adSDave Gerlach ldr r5, [r4, #EMIF_PM_CONFIG_OFFSET] 938428e5adSDave Gerlach cmp r5, #EMIF_SRAM_AM43_REG_LAYOUT 948428e5adSDave Gerlach bne emif_skip_save_extra_regs 958428e5adSDave Gerlach 968428e5adSDave Gerlach ldr r1, [r0, #EMIF_READ_WRITE_LEVELING_RAMP_CONTROL] 978428e5adSDave Gerlach str r1, [r2, #EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET] 988428e5adSDave Gerlach 998428e5adSDave Gerlach ldr r1, [r0, #EMIF_READ_WRITE_EXECUTION_THRESHOLD] 1008428e5adSDave Gerlach str r1, [r2, #EMIF_RD_WR_EXEC_THRESH_OFFSET] 1018428e5adSDave Gerlach 1028428e5adSDave Gerlach ldr r1, [r0, #EMIF_LPDDR2_NVM_TIMING] 1038428e5adSDave Gerlach str r1, [r2, #EMIF_LPDDR2_NVM_TIM_OFFSET] 1048428e5adSDave Gerlach 1058428e5adSDave Gerlach ldr r1, [r0, #EMIF_LPDDR2_NVM_TIMING_SHDW] 1068428e5adSDave Gerlach str r1, [r2, #EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET] 1078428e5adSDave Gerlach 1088428e5adSDave Gerlach ldr r1, [r0, #EMIF_DLL_CALIB_CTRL] 1098428e5adSDave Gerlach str r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_OFFSET] 1108428e5adSDave Gerlach 1118428e5adSDave Gerlach ldr r1, [r0, #EMIF_DLL_CALIB_CTRL_SHDW] 1128428e5adSDave Gerlach str r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET] 1138428e5adSDave Gerlach 1148428e5adSDave Gerlach /* Loop and save entire block of emif phy regs */ 1158428e5adSDave Gerlach mov r5, #0x0 1168428e5adSDave Gerlach add r4, r2, #EMIF_EXT_PHY_CTRL_VALS_OFFSET 1178428e5adSDave Gerlach add r3, r0, #EMIF_EXT_PHY_CTRL_1 1188428e5adSDave Gerlachddr_phy_ctrl_save: 1198428e5adSDave Gerlach ldr r1, [r3, r5] 1208428e5adSDave Gerlach str r1, [r4, r5] 1218428e5adSDave Gerlach add r5, r5, #0x4 1228428e5adSDave Gerlach cmp r5, #AM43XX_EMIF_PHY_CTRL_REG_COUNT 1238428e5adSDave Gerlach bne ddr_phy_ctrl_save 1248428e5adSDave Gerlach 1258428e5adSDave Gerlachemif_skip_save_extra_regs: 1268428e5adSDave Gerlach ldmfd sp!, {r4 - r11, pc} @ restore regs and return 1278428e5adSDave GerlachENDPROC(ti_emif_save_context) 1288428e5adSDave Gerlach 1298428e5adSDave Gerlach/* 1308428e5adSDave Gerlach * void ti_emif_restore_context(void) 1318428e5adSDave Gerlach * 1328428e5adSDave Gerlach * Used during resume to restore the context of all required EMIF registers 1338428e5adSDave Gerlach * from local memory after the EMIF has lost context during a sleep transition. 1348428e5adSDave Gerlach * Operates on the PHYSICAL address of the EMIF. 1358428e5adSDave Gerlach */ 1368428e5adSDave GerlachENTRY(ti_emif_restore_context) 1378428e5adSDave Gerlach adr r4, ti_emif_pm_sram_data 1388428e5adSDave Gerlach ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET] 1398428e5adSDave Gerlach ldr r2, [r4, #EMIF_PM_REGS_PHYS_OFFSET] 1408428e5adSDave Gerlach 1418428e5adSDave Gerlach /* Config EMIF Timings */ 1428428e5adSDave Gerlach ldr r1, [r2, #EMIF_DDR_PHY_CTLR_1_OFFSET] 1438428e5adSDave Gerlach str r1, [r0, #EMIF_DDR_PHY_CTRL_1] 1448428e5adSDave Gerlach str r1, [r0, #EMIF_DDR_PHY_CTRL_1_SHDW] 1458428e5adSDave Gerlach 1468428e5adSDave Gerlach ldr r1, [r2, #EMIF_TIMING1_VAL_OFFSET] 1478428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_TIMING_1] 1488428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_TIMING_1_SHDW] 1498428e5adSDave Gerlach 1508428e5adSDave Gerlach ldr r1, [r2, #EMIF_TIMING2_VAL_OFFSET] 1518428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_TIMING_2] 1528428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_TIMING_2_SHDW] 1538428e5adSDave Gerlach 1548428e5adSDave Gerlach ldr r1, [r2, #EMIF_TIMING3_VAL_OFFSET] 1558428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_TIMING_3] 1568428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_TIMING_3_SHDW] 1578428e5adSDave Gerlach 1588428e5adSDave Gerlach ldr r1, [r2, #EMIF_REF_CTRL_VAL_OFFSET] 1598428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL] 1608428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_REFRESH_CTRL_SHDW] 1618428e5adSDave Gerlach 1628428e5adSDave Gerlach ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET] 1638428e5adSDave Gerlach str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] 1648428e5adSDave Gerlach 1658428e5adSDave Gerlach ldr r1, [r2, #EMIF_PMCR_SHDW_VAL_OFFSET] 1668428e5adSDave Gerlach str r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW] 1678428e5adSDave Gerlach 1688428e5adSDave Gerlach ldr r1, [r2, #EMIF_COS_CONFIG_OFFSET] 1698428e5adSDave Gerlach str r1, [r0, #EMIF_COS_CONFIG] 1708428e5adSDave Gerlach 1718428e5adSDave Gerlach ldr r1, [r2, #EMIF_PRIORITY_TO_COS_MAPPING_OFFSET] 1728428e5adSDave Gerlach str r1, [r0, #EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING] 1738428e5adSDave Gerlach 1748428e5adSDave Gerlach ldr r1, [r2, #EMIF_CONNECT_ID_SERV_1_MAP_OFFSET] 1758428e5adSDave Gerlach str r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING] 1768428e5adSDave Gerlach 1778428e5adSDave Gerlach ldr r1, [r2, #EMIF_CONNECT_ID_SERV_2_MAP_OFFSET] 1788428e5adSDave Gerlach str r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING] 1798428e5adSDave Gerlach 1808428e5adSDave Gerlach ldr r1, [r2, #EMIF_OCP_CONFIG_VAL_OFFSET] 1818428e5adSDave Gerlach str r1, [r0, #EMIF_OCP_CONFIG] 1828428e5adSDave Gerlach 1838428e5adSDave Gerlach ldr r5, [r4, #EMIF_PM_CONFIG_OFFSET] 1848428e5adSDave Gerlach cmp r5, #EMIF_SRAM_AM43_REG_LAYOUT 1858428e5adSDave Gerlach bne emif_skip_restore_extra_regs 1868428e5adSDave Gerlach 1878428e5adSDave Gerlach ldr r1, [r2, #EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET] 1888428e5adSDave Gerlach str r1, [r0, #EMIF_READ_WRITE_LEVELING_RAMP_CONTROL] 1898428e5adSDave Gerlach 1908428e5adSDave Gerlach ldr r1, [r2, #EMIF_RD_WR_EXEC_THRESH_OFFSET] 1918428e5adSDave Gerlach str r1, [r0, #EMIF_READ_WRITE_EXECUTION_THRESHOLD] 1928428e5adSDave Gerlach 1938428e5adSDave Gerlach ldr r1, [r2, #EMIF_LPDDR2_NVM_TIM_OFFSET] 1948428e5adSDave Gerlach str r1, [r0, #EMIF_LPDDR2_NVM_TIMING] 1958428e5adSDave Gerlach 1968428e5adSDave Gerlach ldr r1, [r2, #EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET] 1978428e5adSDave Gerlach str r1, [r0, #EMIF_LPDDR2_NVM_TIMING_SHDW] 1988428e5adSDave Gerlach 1998428e5adSDave Gerlach ldr r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_OFFSET] 2008428e5adSDave Gerlach str r1, [r0, #EMIF_DLL_CALIB_CTRL] 2018428e5adSDave Gerlach 2028428e5adSDave Gerlach ldr r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET] 2038428e5adSDave Gerlach str r1, [r0, #EMIF_DLL_CALIB_CTRL_SHDW] 2048428e5adSDave Gerlach 2058428e5adSDave Gerlach ldr r1, [r2, #EMIF_ZQCFG_VAL_OFFSET] 2068428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG] 2078428e5adSDave Gerlach 2088428e5adSDave Gerlach /* Loop and restore entire block of emif phy regs */ 2098428e5adSDave Gerlach mov r5, #0x0 2108428e5adSDave Gerlach /* Load ti_emif_regs_amx3 + EMIF_EXT_PHY_CTRL_VALS_OFFSET for address 2118428e5adSDave Gerlach * to phy register save space 2128428e5adSDave Gerlach */ 2138428e5adSDave Gerlach add r3, r2, #EMIF_EXT_PHY_CTRL_VALS_OFFSET 2148428e5adSDave Gerlach add r4, r0, #EMIF_EXT_PHY_CTRL_1 2158428e5adSDave Gerlachddr_phy_ctrl_restore: 2168428e5adSDave Gerlach ldr r1, [r3, r5] 2178428e5adSDave Gerlach str r1, [r4, r5] 2188428e5adSDave Gerlach add r5, r5, #0x4 2198428e5adSDave Gerlach cmp r5, #AM43XX_EMIF_PHY_CTRL_REG_COUNT 2208428e5adSDave Gerlach bne ddr_phy_ctrl_restore 2218428e5adSDave Gerlach 2228428e5adSDave Gerlachemif_skip_restore_extra_regs: 2238428e5adSDave Gerlach /* 2248428e5adSDave Gerlach * Output impedence calib needed only for DDR3 2258428e5adSDave Gerlach * but since the initial state of this will be 2268428e5adSDave Gerlach * disabled for DDR2 no harm in restoring the 2278428e5adSDave Gerlach * old configuration 2288428e5adSDave Gerlach */ 2298428e5adSDave Gerlach ldr r1, [r2, #EMIF_ZQCFG_VAL_OFFSET] 2308428e5adSDave Gerlach str r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG] 2318428e5adSDave Gerlach 2328428e5adSDave Gerlach /* Write to sdcfg last for DDR2 only */ 2338428e5adSDave Gerlach ldr r1, [r2, #EMIF_SDCFG_VAL_OFFSET] 2348428e5adSDave Gerlach and r2, r1, #SDRAM_TYPE_MASK 2358428e5adSDave Gerlach cmp r2, #EMIF_SDCFG_TYPE_DDR2 2368428e5adSDave Gerlach streq r1, [r0, #EMIF_SDRAM_CONFIG] 2378428e5adSDave Gerlach 2388428e5adSDave Gerlach mov pc, lr 2398428e5adSDave GerlachENDPROC(ti_emif_restore_context) 2408428e5adSDave Gerlach 2418428e5adSDave Gerlach/* 2426c110561SDave Gerlach * void ti_emif_run_hw_leveling(void) 2436c110561SDave Gerlach * 2446c110561SDave Gerlach * Used during resume to run hardware leveling again and restore the 2456c110561SDave Gerlach * configuration of the EMIF PHY, only for DDR3. 2466c110561SDave Gerlach */ 2476c110561SDave GerlachENTRY(ti_emif_run_hw_leveling) 2486c110561SDave Gerlach adr r4, ti_emif_pm_sram_data 2496c110561SDave Gerlach ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET] 2506c110561SDave Gerlach 2516c110561SDave Gerlach ldr r3, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL] 2526c110561SDave Gerlach orr r3, r3, #RDWRLVLFULL_START 2536c110561SDave Gerlach ldr r2, [r0, #EMIF_SDRAM_CONFIG] 2546c110561SDave Gerlach and r2, r2, #SDRAM_TYPE_MASK 2556c110561SDave Gerlach cmp r2, #EMIF_SDCFG_TYPE_DDR3 2566c110561SDave Gerlach bne skip_hwlvl 2576c110561SDave Gerlach 2586c110561SDave Gerlach str r3, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL] 2596c110561SDave Gerlach 2606c110561SDave Gerlach /* 2616c110561SDave Gerlach * If EMIF registers are touched during initial stage of HW 2626c110561SDave Gerlach * leveling sequence there will be an L3 NOC timeout error issued 2636c110561SDave Gerlach * as the EMIF will not respond, which is not fatal, but it is 2646c110561SDave Gerlach * avoidable. This small wait loop is enough time for this condition 2656c110561SDave Gerlach * to clear, even at worst case of CPU running at max speed of 1Ghz. 2666c110561SDave Gerlach */ 2676c110561SDave Gerlach mov r2, #0x2000 2686c110561SDave Gerlach1: 2696c110561SDave Gerlach subs r2, r2, #0x1 2706c110561SDave Gerlach bne 1b 2716c110561SDave Gerlach 2726c110561SDave Gerlach /* Bit clears when operation is complete */ 2736c110561SDave Gerlach2: ldr r1, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL] 2746c110561SDave Gerlach tst r1, #RDWRLVLFULL_START 2756c110561SDave Gerlach bne 2b 2766c110561SDave Gerlach 2776c110561SDave Gerlachskip_hwlvl: 2786c110561SDave Gerlach mov pc, lr 2796c110561SDave GerlachENDPROC(ti_emif_run_hw_leveling) 2806c110561SDave Gerlach 2816c110561SDave Gerlach/* 2828428e5adSDave Gerlach * void ti_emif_enter_sr(void) 2838428e5adSDave Gerlach * 2848428e5adSDave Gerlach * Programs the EMIF to tell the SDRAM to enter into self-refresh 2858428e5adSDave Gerlach * mode during a sleep transition. Operates on the VIRTUAL address 2868428e5adSDave Gerlach * of the EMIF. 2878428e5adSDave Gerlach */ 2888428e5adSDave GerlachENTRY(ti_emif_enter_sr) 2898428e5adSDave Gerlach stmfd sp!, {r4 - r11, lr} @ save registers on stack 2908428e5adSDave Gerlach 2918428e5adSDave Gerlach adr r4, ti_emif_pm_sram_data 2928428e5adSDave Gerlach ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET] 2938428e5adSDave Gerlach ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET] 2948428e5adSDave Gerlach 2958428e5adSDave Gerlach ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] 2968428e5adSDave Gerlach bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 2978428e5adSDave Gerlach orr r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE 2988428e5adSDave Gerlach str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] 2998428e5adSDave Gerlach 3008428e5adSDave Gerlach ldmfd sp!, {r4 - r11, pc} @ restore regs and return 3018428e5adSDave GerlachENDPROC(ti_emif_enter_sr) 3028428e5adSDave Gerlach 3038428e5adSDave Gerlach/* 3048428e5adSDave Gerlach * void ti_emif_exit_sr(void) 3058428e5adSDave Gerlach * 3068428e5adSDave Gerlach * Programs the EMIF to tell the SDRAM to exit self-refresh mode 3078428e5adSDave Gerlach * after a sleep transition. Operates on the PHYSICAL address of 3088428e5adSDave Gerlach * the EMIF. 3098428e5adSDave Gerlach */ 3108428e5adSDave GerlachENTRY(ti_emif_exit_sr) 3118428e5adSDave Gerlach adr r4, ti_emif_pm_sram_data 3128428e5adSDave Gerlach ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET] 3138428e5adSDave Gerlach ldr r2, [r4, #EMIF_PM_REGS_PHYS_OFFSET] 3148428e5adSDave Gerlach 3158428e5adSDave Gerlach /* 3168428e5adSDave Gerlach * Toggle EMIF to exit refresh mode: 3178428e5adSDave Gerlach * if EMIF lost context, PWR_MGT_CTRL is currently 0, writing disable 3188428e5adSDave Gerlach * (0x0), wont do diddly squat! so do a toggle from SR(0x2) to disable 3198428e5adSDave Gerlach * (0x0) here. 3208428e5adSDave Gerlach * *If* EMIF did not lose context, nothing broken as we write the same 3218428e5adSDave Gerlach * value(0x2) to reg before we write a disable (0x0). 3228428e5adSDave Gerlach */ 3238428e5adSDave Gerlach ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET] 3248428e5adSDave Gerlach bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 3258428e5adSDave Gerlach orr r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE 3268428e5adSDave Gerlach str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] 3278428e5adSDave Gerlach bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 3288428e5adSDave Gerlach str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] 3298428e5adSDave Gerlach 3308428e5adSDave Gerlach /* Wait for EMIF to become ready */ 3318428e5adSDave Gerlach1: ldr r1, [r0, #EMIF_STATUS] 3328428e5adSDave Gerlach tst r1, #EMIF_STATUS_READY 3338428e5adSDave Gerlach beq 1b 3348428e5adSDave Gerlach 3358428e5adSDave Gerlach mov pc, lr 3368428e5adSDave GerlachENDPROC(ti_emif_exit_sr) 3378428e5adSDave Gerlach 3388428e5adSDave Gerlach/* 3398428e5adSDave Gerlach * void ti_emif_abort_sr(void) 3408428e5adSDave Gerlach * 3418428e5adSDave Gerlach * Disables self-refresh after a failed transition to a low-power 3428428e5adSDave Gerlach * state so the kernel can jump back to DDR and follow abort path. 3438428e5adSDave Gerlach * Operates on the VIRTUAL address of the EMIF. 3448428e5adSDave Gerlach */ 3458428e5adSDave GerlachENTRY(ti_emif_abort_sr) 3468428e5adSDave Gerlach stmfd sp!, {r4 - r11, lr} @ save registers on stack 3478428e5adSDave Gerlach 3488428e5adSDave Gerlach adr r4, ti_emif_pm_sram_data 3498428e5adSDave Gerlach ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET] 3508428e5adSDave Gerlach ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET] 3518428e5adSDave Gerlach 3528428e5adSDave Gerlach ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET] 3538428e5adSDave Gerlach bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 3548428e5adSDave Gerlach str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] 3558428e5adSDave Gerlach 3568428e5adSDave Gerlach /* Wait for EMIF to become ready */ 3578428e5adSDave Gerlach1: ldr r1, [r0, #EMIF_STATUS] 3588428e5adSDave Gerlach tst r1, #EMIF_STATUS_READY 3598428e5adSDave Gerlach beq 1b 3608428e5adSDave Gerlach 3618428e5adSDave Gerlach ldmfd sp!, {r4 - r11, pc} @ restore regs and return 3628428e5adSDave GerlachENDPROC(ti_emif_abort_sr) 3638428e5adSDave Gerlach 3648428e5adSDave Gerlach .align 3 3658428e5adSDave GerlachENTRY(ti_emif_pm_sram_data) 3668428e5adSDave Gerlach .space EMIF_PM_DATA_SIZE 3678428e5adSDave GerlachENTRY(ti_emif_sram_sz) 3688428e5adSDave Gerlach .word . - ti_emif_save_context 369