[PATCH v3 6/7] ARM: EXYNOS: Add support for non-secure L2X0 resume
Tomasz Figa
t.figa at samsung.com
Thu Jul 17 09:39:01 PDT 2014
On Exynos SoCs it is necessary to resume operation of L2C early in
assembly code, because otherwise certain systems will crash. This patch
adds necessary code to non-secure resume handler.
Signed-off-by: Tomasz Figa <t.figa at samsung.com>
---
arch/arm/mach-exynos/common.h | 1 +
arch/arm/mach-exynos/firmware.c | 2 ++
arch/arm/mach-exynos/sleep.S | 41 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 44 insertions(+)
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index a3f3061..2540827 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -113,6 +113,7 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
extern u32 cp15_save_diag;
extern u32 cp15_save_power;
+extern unsigned long l2x0_regs_phys;
extern void __iomem *sysram_ns_base_addr;
extern void __iomem *sysram_base_addr;
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 554b350..09131d3 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -103,6 +103,8 @@ static int exynos_suspend(void)
writel(virt_to_phys(exynos_cpu_resume_ns),
sysram_ns_base_addr + EXYNOS_BOOT_ADDR);
+ l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
+
return cpu_suspend(0, exynos_cpu_suspend);
}
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S
index e3c3730..b8ce8f0 100644
--- a/arch/arm/mach-exynos/sleep.S
+++ b/arch/arm/mach-exynos/sleep.S
@@ -16,6 +16,8 @@
*/
#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
#include "smc.h"
#define CPU_MASK 0xff0ffff0
@@ -74,6 +76,40 @@ ENTRY(exynos_cpu_resume_ns)
mov r0, #SMC_CMD_C15RESUME
dsb
smc #0
+#ifdef CONFIG_CACHE_L2X0
+ adr r0, l2x0_regs_phys
+ ldr r0, [r0]
+ cmp r0, #0
+ beq skip_l2x0
+
+ ldr r1, [r0, #L2X0_R_PHY_BASE]
+ ldr r2, [r1, #L2X0_CTRL]
+ tst r2, #0x1
+ bne skip_l2x0
+
+ ldr r1, [r0, #L2X0_R_TAG_LATENCY]
+ ldr r2, [r0, #L2X0_R_DATA_LATENCY]
+ ldr r3, [r0, #L2X0_R_PREFETCH_CTRL]
+ mov r0, #SMC_CMD_L2X0SETUP1
+ smc #0
+
+ /* Reload saved regs pointer because smc corrupts registers. */
+ adr r0, l2x0_regs_phys
+ ldr r0, [r0]
+
+ ldr r1, [r0, #L2X0_R_PWR_CTRL]
+ ldr r2, [r0, #L2X0_R_AUX_CTRL]
+ mov r0, #SMC_CMD_L2X0SETUP2
+ smc #0
+
+ mov r0, #SMC_CMD_L2X0INVALL
+ smc #0
+
+ mov r1, #1
+ mov r0, #SMC_CMD_L2X0CTRL
+ smc #0
+skip_l2x0:
+#endif /* CONFIG_CACHE_L2X0 */
skip_cp15:
b cpu_resume
ENDPROC(exynos_cpu_resume_ns)
@@ -83,3 +119,8 @@ cp15_save_diag:
.globl cp15_save_power
cp15_save_power:
.long 0 @ cp15 power control
+#ifdef CONFIG_CACHE_L2X0
+ .globl l2x0_regs_phys
+l2x0_regs_phys:
+ .long 0 @ phys address of l2x0 save struct
+#endif /* CONFIG_CACHE_L2X0 */
--
1.9.3
More information about the linux-arm-kernel
mailing list