From 9caa7be09f1c7641ded024fa1fa6ee45b8b7d87f Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Fri, 11 Nov 2011 13:11:32 +0530 Subject: ARM: exynos4: add L2 early resume code This patch adds code to save L2 register configuration at boot, and to resume L2 before MMU is enabled in suspend and cpuidle resume paths. Signed-off-by: Lorenzo Pieralisi Signed-off-by: Amit Daniel Kachhap --- arch/arm/mach-exynos4/cpu.c | 36 ++++++++++++++++++++++++++++-------- arch/arm/mach-exynos4/sleep.S | 26 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 746d6fc6d39..979fb5d4367 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -31,6 +32,7 @@ #include #include +#include extern int combiner_init(unsigned int combiner_nr, void __iomem *base, unsigned int irq_start); @@ -221,16 +223,34 @@ core_initcall(exynos4_core_init); #ifdef CONFIG_CACHE_L2X0 static int __init exynos4_l2x0_cache_init(void) { - /* TAG, Data Latency Control: 2cycle */ - __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); - __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); + if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) { - /* L2X0 Prefetch Control */ - __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); + l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC; + /* TAG, Data Latency Control: 2 cycles */ + l2x0_saved_regs.tag_latency = 0x110; + l2x0_saved_regs.data_latency = 0x110; + l2x0_saved_regs.prefetch_ctrl = 0x30000007; + l2x0_saved_regs.pwr_ctrl = + (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN); - /* L2X0 Power Control */ - __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, - S5P_VA_L2CC + L2X0_POWER_CTRL); + l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs); + + __raw_writel(l2x0_saved_regs.tag_latency, + S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); + __raw_writel(l2x0_saved_regs.data_latency, + S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); + + /* L2X0 Prefetch Control */ + __raw_writel(l2x0_saved_regs.prefetch_ctrl, + S5P_VA_L2CC + L2X0_PREFETCH_CTRL); + + /* L2X0 Power Control */ + __raw_writel(l2x0_saved_regs.pwr_ctrl, + S5P_VA_L2CC + L2X0_POWER_CTRL); + + clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long)); + clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs)); + } l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos4/sleep.S index c19527bf301..3284213a1a3 100644 --- a/arch/arm/mach-exynos4/sleep.S +++ b/arch/arm/mach-exynos4/sleep.S @@ -27,6 +27,8 @@ */ #include +#include +#include .text @@ -47,7 +49,31 @@ * other way of restoring the stack pointer after sleep, and we * must not write to the code segment (code is read-only) */ + .align + .data ENTRY(s3c_cpu_resume) + adr r0, l2x0_regs_phys + ldr r0, [r0] + ldr r1, [r0, #L2X0_R_PHY_BASE] + ldr r2, [r1, #L2X0_CTRL] + tst r2, #0x1 + bne resume_l2on + ldr r2, [r0, #L2X0_R_AUX_CTRL] + str r2, [r1, #L2X0_AUX_CTRL] + ldr r2, [r0, #L2X0_R_TAG_LATENCY] + str r2, [r1, #L2X0_TAG_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_DATA_LATENCY] + str r2, [r1, #L2X0_DATA_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_PREFETCH_CTRL] + str r2, [r1, #L2X0_PREFETCH_CTRL] + ldr r2, [r0, #L2X0_R_PWR_CTRL] + str r2, [r1, #L2X0_POWER_CTRL] + mov r2, #1 + str r2, [r1, #L2X0_CTRL] +resume_l2on: b cpu_resume ENDPROC(s3c_cpu_resume) + .globl l2x0_regs_phys +l2x0_regs_phys: + .long 0 -- cgit v1.2.3