diff options
author | Dave Gerlach <d-gerlach@ti.com> | 2018-07-09 10:33:16 +0300 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2018-07-10 09:01:34 +0300 |
commit | 74655749a58405e259eaaba66bfc391fdbe1e34e (patch) | |
tree | 236b3f2e858af9d8649d1794dd37321f37153547 /arch/arm/mach-omap2/sleep43xx.S | |
parent | eb07fe9f9f28d4ce441c5b51653d421725b0c998 (diff) | |
download | linux-74655749a58405e259eaaba66bfc391fdbe1e34e.tar.xz |
ARM: OMAP2+: sleep33/43xx: Make sleep actions configurable
Add an argument to the sleep33xx and sleep43xx code to allow us to set
flags to determine which portions of the code get called in order to use
the same code for multiple power saving modes. This patch allows us to
decide whether or not we flush and disable caches, save EMIF context,
put the memory into self refresh and disable the EMIF, and/or invoke
the wkup_m3 when entering into WFI.
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/sleep43xx.S')
-rw-r--r-- | arch/arm/mach-omap2/sleep43xx.S | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/sleep43xx.S b/arch/arm/mach-omap2/sleep43xx.S index 8903814a6677..cd7e95f48a73 100644 --- a/arch/arm/mach-omap2/sleep43xx.S +++ b/arch/arm/mach-omap2/sleep43xx.S @@ -9,7 +9,7 @@ #include <generated/ti-pm-asm-offsets.h> #include <linux/linkage.h> #include <linux/ti-emif-sram.h> - +#include <linux/platform_data/pm33xx.h> #include <asm/assembler.h> #include <asm/hardware/cache-l2x0.h> #include <asm/memory.h> @@ -22,6 +22,9 @@ #include "prm33xx.h" #include "prcm43xx.h" +/* replicated define because linux/bitops.h cannot be included in assembly */ +#define BIT(nr) (1 << (nr)) + #define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x00030000 #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003 #define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002 @@ -51,6 +54,12 @@ ENTRY(am43xx_do_wfi) stmfd sp!, {r4 - r11, lr} @ save registers on stack + /* Save wfi_flags arg to data space */ + mov r4, r0 + adr r3, am43xx_pm_ro_sram_data + ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] + str r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET] + #ifdef CONFIG_CACHE_L2X0 /* Retrieve l2 cache virt address BEFORE we shut off EMIF */ ldr r1, get_l2cache_base @@ -58,6 +67,10 @@ ENTRY(am43xx_do_wfi) mov r8, r0 #endif + /* Only flush cache is we know we are losing MPU context */ + tst r4, #WFI_FLAG_FLUSH_CACHE + beq cache_skip_flush + /* * Flush all data from the L1 and L2 data cache before disabling * SCTLR.C bit. @@ -128,13 +141,33 @@ sync: bne sync #endif + /* Restore wfi_flags */ + adr r3, am43xx_pm_ro_sram_data + ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] + ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET] + +cache_skip_flush: + /* Check if we want self refresh */ + tst r4, #WFI_FLAG_SELF_REFRESH + beq emif_skip_enter_sr + adr r9, am43xx_emif_sram_table ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET] blx r3 +emif_skip_enter_sr: + /* Only necessary if PER is losing context */ + tst r4, #WFI_FLAG_SAVE_EMIF + beq emif_skip_save + ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET] - blx r3 + blx r3 + +emif_skip_save: + /* Only can disable EMIF if we have entered self refresh */ + tst r4, #WFI_FLAG_SELF_REFRESH + beq emif_skip_disable /* Disable EMIF */ ldr r1, am43xx_virt_emif_clkctrl @@ -148,6 +181,10 @@ wait_emif_disable: cmp r2, r3 bne wait_emif_disable +emif_skip_disable: + tst r4, #WFI_FLAG_WAKE_M3 + beq wkup_m3_skip + /* * For the MPU WFI to be registered as an interrupt * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set @@ -165,6 +202,7 @@ wait_emif_disable: mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP str r2, [r1] +wkup_m3_skip: /* * Execute a barrier instruction to ensure that all cache, * TLB and branch predictor maintenance operations issued @@ -218,6 +256,9 @@ wait_emif_enable: cmp r2, r3 bne wait_emif_enable + tst r4, #WFI_FLAG_FLUSH_CACHE + beq cache_skip_restore + /* * Set SCTLR.C bit to allow data cache allocation */ @@ -226,9 +267,16 @@ wait_emif_enable: mcr p15, 0, r0, c1, c0, 0 isb - ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET] - blx r1 +cache_skip_restore: + /* Only necessary if PER is losing context */ + tst r4, #WFI_FLAG_SELF_REFRESH + beq emif_skip_exit_sr_abt + + adr r9, am43xx_emif_sram_table + ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET] + blx r1 +emif_skip_exit_sr_abt: /* Let the suspend code know about the abort */ mov r0, #1 ldmfd sp!, {r4 - r11, pc} @ restore regs and return |