cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ti-emif-sram-pm.S (11309B)


      1/*
      2 * Low level PM code for TI EMIF
      3 *
      4 * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/
      5 *	Dave Gerlach
      6 *
      7 * This program is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU General Public License as
      9 * published by the Free Software Foundation version 2.
     10 *
     11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
     12 * kind, whether express or implied; without even the implied warranty
     13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 */
     16
     17#include <linux/linkage.h>
     18#include <asm/assembler.h>
     19#include <asm/memory.h>
     20
     21#include "emif.h"
     22#include "ti-emif-asm-offsets.h"
     23
     24#define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES	0x00a0
     25#define EMIF_POWER_MGMT_SR_TIMER_MASK			0x00f0
     26#define EMIF_POWER_MGMT_SELF_REFRESH_MODE		0x0200
     27#define EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK		0x0700
     28
     29#define EMIF_SDCFG_TYPE_DDR2				0x2 << SDRAM_TYPE_SHIFT
     30#define EMIF_SDCFG_TYPE_DDR3				0x3 << SDRAM_TYPE_SHIFT
     31#define EMIF_STATUS_READY				0x4
     32
     33#define AM43XX_EMIF_PHY_CTRL_REG_COUNT                  0x120
     34
     35#define EMIF_AM437X_REGISTERS				0x1
     36
     37	.arm
     38	.align 3
     39
     40ENTRY(ti_emif_sram)
     41
     42/*
     43 * void ti_emif_save_context(void)
     44 *
     45 * Used during suspend to save the context of all required EMIF registers
     46 * to local memory if the EMIF is going to lose context during the sleep
     47 * transition. Operates on the VIRTUAL address of the EMIF.
     48 */
     49ENTRY(ti_emif_save_context)
     50	stmfd   sp!, {r4 - r11, lr}     @ save registers on stack
     51
     52	adr	r4, ti_emif_pm_sram_data
     53	ldr	r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
     54	ldr	r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
     55
     56	/* Save EMIF configuration */
     57	ldr	r1, [r0, #EMIF_SDRAM_CONFIG]
     58	str	r1, [r2, #EMIF_SDCFG_VAL_OFFSET]
     59
     60	ldr	r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL]
     61	str	r1, [r2, #EMIF_REF_CTRL_VAL_OFFSET]
     62
     63	ldr	r1, [r0, #EMIF_SDRAM_TIMING_1]
     64	str     r1, [r2, #EMIF_TIMING1_VAL_OFFSET]
     65
     66	ldr	r1, [r0, #EMIF_SDRAM_TIMING_2]
     67	str     r1, [r2, #EMIF_TIMING2_VAL_OFFSET]
     68
     69	ldr	r1, [r0, #EMIF_SDRAM_TIMING_3]
     70	str     r1, [r2, #EMIF_TIMING3_VAL_OFFSET]
     71
     72	ldr	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
     73	str     r1, [r2, #EMIF_PMCR_VAL_OFFSET]
     74
     75	ldr	r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
     76	str     r1, [r2, #EMIF_PMCR_SHDW_VAL_OFFSET]
     77
     78	ldr	r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
     79	str     r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
     80
     81	ldr	r1, [r0, #EMIF_DDR_PHY_CTRL_1]
     82	str     r1, [r2, #EMIF_DDR_PHY_CTLR_1_OFFSET]
     83
     84	ldr	r1, [r0, #EMIF_COS_CONFIG]
     85	str     r1, [r2, #EMIF_COS_CONFIG_OFFSET]
     86
     87	ldr	r1, [r0, #EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING]
     88	str     r1, [r2, #EMIF_PRIORITY_TO_COS_MAPPING_OFFSET]
     89
     90	ldr	r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING]
     91	str     r1, [r2, #EMIF_CONNECT_ID_SERV_1_MAP_OFFSET]
     92
     93	ldr	r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING]
     94	str     r1, [r2, #EMIF_CONNECT_ID_SERV_2_MAP_OFFSET]
     95
     96	ldr	r1, [r0, #EMIF_OCP_CONFIG]
     97	str     r1, [r2, #EMIF_OCP_CONFIG_VAL_OFFSET]
     98
     99	ldr	r5, [r4, #EMIF_PM_CONFIG_OFFSET]
    100	cmp	r5, #EMIF_SRAM_AM43_REG_LAYOUT
    101	bne	emif_skip_save_extra_regs
    102
    103	ldr	r1, [r0, #EMIF_READ_WRITE_LEVELING_RAMP_CONTROL]
    104	str     r1, [r2, #EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET]
    105
    106	ldr	r1, [r0, #EMIF_READ_WRITE_EXECUTION_THRESHOLD]
    107	str     r1, [r2, #EMIF_RD_WR_EXEC_THRESH_OFFSET]
    108
    109	ldr	r1, [r0, #EMIF_LPDDR2_NVM_TIMING]
    110	str     r1, [r2, #EMIF_LPDDR2_NVM_TIM_OFFSET]
    111
    112	ldr	r1, [r0, #EMIF_LPDDR2_NVM_TIMING_SHDW]
    113	str     r1, [r2, #EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET]
    114
    115	ldr	r1, [r0, #EMIF_DLL_CALIB_CTRL]
    116	str     r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_OFFSET]
    117
    118	ldr	r1, [r0, #EMIF_DLL_CALIB_CTRL_SHDW]
    119	str     r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET]
    120
    121	/* Loop and save entire block of emif phy regs */
    122	mov	r5, #0x0
    123	add	r4, r2, #EMIF_EXT_PHY_CTRL_VALS_OFFSET
    124	add	r3, r0, #EMIF_EXT_PHY_CTRL_1
    125ddr_phy_ctrl_save:
    126	ldr	r1, [r3, r5]
    127	str	r1, [r4, r5]
    128	add	r5, r5, #0x4
    129	cmp	r5, #AM43XX_EMIF_PHY_CTRL_REG_COUNT
    130	bne	ddr_phy_ctrl_save
    131
    132emif_skip_save_extra_regs:
    133	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
    134ENDPROC(ti_emif_save_context)
    135
    136/*
    137 * void ti_emif_restore_context(void)
    138 *
    139 * Used during resume to restore the context of all required EMIF registers
    140 * from local memory after the EMIF has lost context during a sleep transition.
    141 * Operates on the PHYSICAL address of the EMIF.
    142 */
    143ENTRY(ti_emif_restore_context)
    144	adr	r4, ti_emif_pm_sram_data
    145	ldr	r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET]
    146	ldr	r2, [r4, #EMIF_PM_REGS_PHYS_OFFSET]
    147
    148	/* Config EMIF Timings */
    149	ldr     r1, [r2, #EMIF_DDR_PHY_CTLR_1_OFFSET]
    150	str	r1, [r0, #EMIF_DDR_PHY_CTRL_1]
    151	str	r1, [r0, #EMIF_DDR_PHY_CTRL_1_SHDW]
    152
    153	ldr     r1, [r2, #EMIF_TIMING1_VAL_OFFSET]
    154	str	r1, [r0, #EMIF_SDRAM_TIMING_1]
    155	str	r1, [r0, #EMIF_SDRAM_TIMING_1_SHDW]
    156
    157	ldr     r1, [r2, #EMIF_TIMING2_VAL_OFFSET]
    158	str	r1, [r0, #EMIF_SDRAM_TIMING_2]
    159	str	r1, [r0, #EMIF_SDRAM_TIMING_2_SHDW]
    160
    161	ldr     r1, [r2, #EMIF_TIMING3_VAL_OFFSET]
    162	str	r1, [r0, #EMIF_SDRAM_TIMING_3]
    163	str	r1, [r0, #EMIF_SDRAM_TIMING_3_SHDW]
    164
    165	ldr     r1, [r2, #EMIF_REF_CTRL_VAL_OFFSET]
    166	str	r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL]
    167	str	r1, [r0, #EMIF_SDRAM_REFRESH_CTRL_SHDW]
    168
    169	ldr     r1, [r2, #EMIF_PMCR_VAL_OFFSET]
    170	str	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
    171
    172	ldr     r1, [r2, #EMIF_PMCR_SHDW_VAL_OFFSET]
    173	str	r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
    174
    175	ldr     r1, [r2, #EMIF_COS_CONFIG_OFFSET]
    176	str	r1, [r0, #EMIF_COS_CONFIG]
    177
    178	ldr     r1, [r2, #EMIF_PRIORITY_TO_COS_MAPPING_OFFSET]
    179	str	r1, [r0, #EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING]
    180
    181	ldr	r1, [r2, #EMIF_CONNECT_ID_SERV_1_MAP_OFFSET]
    182	str	r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING]
    183
    184	ldr     r1, [r2, #EMIF_CONNECT_ID_SERV_2_MAP_OFFSET]
    185	str	r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING]
    186
    187	ldr     r1, [r2, #EMIF_OCP_CONFIG_VAL_OFFSET]
    188	str	r1, [r0, #EMIF_OCP_CONFIG]
    189
    190	ldr	r5, [r4, #EMIF_PM_CONFIG_OFFSET]
    191	cmp	r5, #EMIF_SRAM_AM43_REG_LAYOUT
    192	bne	emif_skip_restore_extra_regs
    193
    194	ldr     r1, [r2, #EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET]
    195	str	r1, [r0, #EMIF_READ_WRITE_LEVELING_RAMP_CONTROL]
    196
    197	ldr     r1, [r2, #EMIF_RD_WR_EXEC_THRESH_OFFSET]
    198	str	r1, [r0, #EMIF_READ_WRITE_EXECUTION_THRESHOLD]
    199
    200	ldr     r1, [r2, #EMIF_LPDDR2_NVM_TIM_OFFSET]
    201	str	r1, [r0, #EMIF_LPDDR2_NVM_TIMING]
    202
    203	ldr     r1, [r2, #EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET]
    204	str	r1, [r0, #EMIF_LPDDR2_NVM_TIMING_SHDW]
    205
    206	ldr     r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_OFFSET]
    207	str	r1, [r0, #EMIF_DLL_CALIB_CTRL]
    208
    209	ldr     r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET]
    210	str	r1, [r0, #EMIF_DLL_CALIB_CTRL_SHDW]
    211
    212	ldr     r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
    213	str	r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
    214
    215	/* Loop and restore entire block of emif phy regs */
    216	mov	r5, #0x0
    217	/* Load ti_emif_regs_amx3 + EMIF_EXT_PHY_CTRL_VALS_OFFSET for address
    218	 * to phy register save space
    219	 */
    220	add	r3, r2, #EMIF_EXT_PHY_CTRL_VALS_OFFSET
    221	add	r4, r0, #EMIF_EXT_PHY_CTRL_1
    222ddr_phy_ctrl_restore:
    223	ldr	r1, [r3, r5]
    224	str	r1, [r4, r5]
    225	add	r5, r5, #0x4
    226	cmp	r5, #AM43XX_EMIF_PHY_CTRL_REG_COUNT
    227	bne	ddr_phy_ctrl_restore
    228
    229emif_skip_restore_extra_regs:
    230	/*
    231	 * Output impedence calib needed only for DDR3
    232	 * but since the initial state of this will be
    233	 * disabled for DDR2 no harm in restoring the
    234	 * old configuration
    235	 */
    236	ldr     r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
    237	str	r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
    238
    239	/* Write to sdcfg last for DDR2 only */
    240	ldr	r1, [r2, #EMIF_SDCFG_VAL_OFFSET]
    241	and	r2, r1, #SDRAM_TYPE_MASK
    242	cmp	r2, #EMIF_SDCFG_TYPE_DDR2
    243	streq	r1, [r0, #EMIF_SDRAM_CONFIG]
    244
    245	mov	pc, lr
    246ENDPROC(ti_emif_restore_context)
    247
    248/*
    249 * void ti_emif_run_hw_leveling(void)
    250 *
    251 * Used during resume to run hardware leveling again and restore the
    252 * configuration of the EMIF PHY, only for DDR3.
    253 */
    254ENTRY(ti_emif_run_hw_leveling)
    255	adr	r4, ti_emif_pm_sram_data
    256	ldr	r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET]
    257
    258	ldr	r3, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL]
    259	orr	r3, r3, #RDWRLVLFULL_START
    260	ldr	r2, [r0, #EMIF_SDRAM_CONFIG]
    261	and	r2, r2, #SDRAM_TYPE_MASK
    262	cmp	r2, #EMIF_SDCFG_TYPE_DDR3
    263	bne	skip_hwlvl
    264
    265	str	r3, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL]
    266
    267	/*
    268	 * If EMIF registers are touched during initial stage of HW
    269	 * leveling sequence there will be an L3 NOC timeout error issued
    270	 * as the EMIF will not respond, which is not fatal, but it is
    271	 * avoidable. This small wait loop is enough time for this condition
    272	 * to clear, even at worst case of CPU running at max speed of 1Ghz.
    273	 */
    274	mov	r2, #0x2000
    2751:
    276	subs	r2, r2, #0x1
    277	bne	1b
    278
    279	/* Bit clears when operation is complete */
    2802:	ldr     r1, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL]
    281	tst     r1, #RDWRLVLFULL_START
    282	bne     2b
    283
    284skip_hwlvl:
    285	mov	pc, lr
    286ENDPROC(ti_emif_run_hw_leveling)
    287
    288/*
    289 * void ti_emif_enter_sr(void)
    290 *
    291 * Programs the EMIF to tell the SDRAM to enter into self-refresh
    292 * mode during a sleep transition. Operates on the VIRTUAL address
    293 * of the EMIF.
    294 */
    295ENTRY(ti_emif_enter_sr)
    296	stmfd   sp!, {r4 - r11, lr}     @ save registers on stack
    297
    298	adr	r4, ti_emif_pm_sram_data
    299	ldr	r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
    300	ldr	r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
    301
    302	ldr	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
    303	bic	r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
    304	orr	r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE
    305	str	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
    306
    307	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
    308ENDPROC(ti_emif_enter_sr)
    309
    310/*
    311 * void ti_emif_exit_sr(void)
    312 *
    313 * Programs the EMIF to tell the SDRAM to exit self-refresh mode
    314 * after a sleep transition. Operates on the PHYSICAL address of
    315 * the EMIF.
    316 */
    317ENTRY(ti_emif_exit_sr)
    318	adr	r4, ti_emif_pm_sram_data
    319	ldr	r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET]
    320	ldr	r2, [r4, #EMIF_PM_REGS_PHYS_OFFSET]
    321
    322	/*
    323	 * Toggle EMIF to exit refresh mode:
    324	 * if EMIF lost context, PWR_MGT_CTRL is currently 0, writing disable
    325	 *   (0x0), wont do diddly squat! so do a toggle from SR(0x2) to disable
    326	 *   (0x0) here.
    327	 * *If* EMIF did not lose context, nothing broken as we write the same
    328	 *   value(0x2) to reg before we write a disable (0x0).
    329	 */
    330	ldr	r1, [r2, #EMIF_PMCR_VAL_OFFSET]
    331	bic	r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
    332	orr	r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE
    333	str	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
    334	bic	r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
    335	str	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
    336
    337        /* Wait for EMIF to become ready */
    3381:	ldr     r1, [r0, #EMIF_STATUS]
    339	tst     r1, #EMIF_STATUS_READY
    340	beq     1b
    341
    342	mov	pc, lr
    343ENDPROC(ti_emif_exit_sr)
    344
    345/*
    346 * void ti_emif_abort_sr(void)
    347 *
    348 * Disables self-refresh after a failed transition to a low-power
    349 * state so the kernel can jump back to DDR and follow abort path.
    350 * Operates on the VIRTUAL address of the EMIF.
    351 */
    352ENTRY(ti_emif_abort_sr)
    353	stmfd   sp!, {r4 - r11, lr}     @ save registers on stack
    354
    355	adr	r4, ti_emif_pm_sram_data
    356	ldr	r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
    357	ldr	r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
    358
    359	ldr	r1, [r2, #EMIF_PMCR_VAL_OFFSET]
    360	bic	r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
    361	str	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
    362
    363	/* Wait for EMIF to become ready */
    3641:	ldr     r1, [r0, #EMIF_STATUS]
    365	tst     r1, #EMIF_STATUS_READY
    366	beq     1b
    367
    368	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
    369ENDPROC(ti_emif_abort_sr)
    370
    371	.align 3
    372ENTRY(ti_emif_pm_sram_data)
    373	.space EMIF_PM_DATA_SIZE
    374ENTRY(ti_emif_sram_sz)
    375        .word   . - ti_emif_save_context