diff options
author | Dave Gerlach <d-gerlach@ti.com> | 2019-04-02 18:57:42 +0200 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2019-04-09 17:31:51 +0200 |
commit | 6c110561eb2d4d1496961c13a92f96f29eea7c72 (patch) | |
tree | 8c1237a3dbc0f2bafb8df589b2f9c1dbf8c04a69 /drivers/memory/ti-emif-sram-pm.S | |
parent | Linux 5.1-rc1 (diff) | |
download | linux-6c110561eb2d4d1496961c13a92f96f29eea7c72.tar.xz linux-6c110561eb2d4d1496961c13a92f96f29eea7c72.zip |
memory: ti-emif-sram: Add ti_emif_run_hw_leveling for DDR3 hardware leveling
In certain situations, such as when returning from low power modes, the
EMIF must re-run hardware leveling to properly restore DDR3 access.
This is accomplished by introducing a new ti-emif-sram-pm call,
ti_emif_run_hw_leveling, to check if DDR3 is in use and if so, trigger
the full write and read leveling processes.
Suggested-by: Brad Griffis <bgriffis@ti.com>
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Acked-by: Santosh Shilimkar <ssantosh@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'drivers/memory/ti-emif-sram-pm.S')
-rw-r--r-- | drivers/memory/ti-emif-sram-pm.S | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/memory/ti-emif-sram-pm.S b/drivers/memory/ti-emif-sram-pm.S index a5369181e5c2..d75ae18efa7d 100644 --- a/drivers/memory/ti-emif-sram-pm.S +++ b/drivers/memory/ti-emif-sram-pm.S @@ -27,6 +27,7 @@ #define EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 0x0700 #define EMIF_SDCFG_TYPE_DDR2 0x2 << SDRAM_TYPE_SHIFT +#define EMIF_SDCFG_TYPE_DDR3 0x3 << SDRAM_TYPE_SHIFT #define EMIF_STATUS_READY 0x4 #define AM43XX_EMIF_PHY_CTRL_REG_COUNT 0x120 @@ -245,6 +246,46 @@ emif_skip_restore_extra_regs: ENDPROC(ti_emif_restore_context) /* + * void ti_emif_run_hw_leveling(void) + * + * Used during resume to run hardware leveling again and restore the + * configuration of the EMIF PHY, only for DDR3. + */ +ENTRY(ti_emif_run_hw_leveling) + adr r4, ti_emif_pm_sram_data + ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET] + + ldr r3, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL] + orr r3, r3, #RDWRLVLFULL_START + ldr r2, [r0, #EMIF_SDRAM_CONFIG] + and r2, r2, #SDRAM_TYPE_MASK + cmp r2, #EMIF_SDCFG_TYPE_DDR3 + bne skip_hwlvl + + str r3, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL] + + /* + * If EMIF registers are touched during initial stage of HW + * leveling sequence there will be an L3 NOC timeout error issued + * as the EMIF will not respond, which is not fatal, but it is + * avoidable. This small wait loop is enough time for this condition + * to clear, even at worst case of CPU running at max speed of 1Ghz. + */ + mov r2, #0x2000 +1: + subs r2, r2, #0x1 + bne 1b + + /* Bit clears when operation is complete */ +2: ldr r1, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL] + tst r1, #RDWRLVLFULL_START + bne 2b + +skip_hwlvl: + mov pc, lr +ENDPROC(ti_emif_run_hw_leveling) + +/* * void ti_emif_enter_sr(void) * * Programs the EMIF to tell the SDRAM to enter into self-refresh |