aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ux500
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2011-08-12 07:54:42 -0400
committerLinus Walleij <linus.walleij@linaro.org>2011-09-22 08:07:34 -0400
commit1bf6d2c1bb23533af6930581cc39b74685bc29de (patch)
tree08e7bdcd7389fba9b17f01e6d6951b7b32fd6d6b /arch/arm/mach-ux500
parente0628d25ce9cea371e07cba5ee470af63e602a41 (diff)
ARM: mach-ux500: unlock I&D l2x0 caches before init
Apparently U8500 U-Boot versions may leave the l2x0 locked down before executing the kernel. Make sure we unlock it before we initialize the l2x0. This fixes a performance problem reported by Jan Rinze. The l2x0 core has been modified to unlock the l2x0 by default, but it will not touch the locking registers if the l2x0 was already enabled, as on the ux500, so we need this quirk to make sure it is properly turned off. Cc: stable@kernel.org Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> Cc: Rabin Vincent <rabin.vincent@stericsson.com> Cc: Adrian Bunk <adrian.bunk@movial.com> Reported-by: Jan Rinze <janrinze@gmail.com> Tested-by: Robert Marklund <robert.marklund@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch/arm/mach-ux500')
-rw-r--r--arch/arm/mach-ux500/cpu.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 1da23bb87c16..8aa104a4711a 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -99,7 +99,27 @@ static void ux500_l2x0_inv_all(void)
99 ux500_cache_sync(); 99 ux500_cache_sync();
100} 100}
101 101
102static int ux500_l2x0_init(void) 102static int __init ux500_l2x0_unlock(void)
103{
104 int i;
105
106 /*
107 * Unlock Data and Instruction Lock if locked. Ux500 U-Boot versions
108 * apparently locks both caches before jumping to the kernel. The
109 * l2x0 core will not touch the unlock registers if the l2x0 is
110 * already enabled, so we do it right here instead. The PL310 has
111 * 8 sets of registers, one per possible CPU.
112 */
113 for (i = 0; i < 8; i++) {
114 writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
115 i * L2X0_LOCKDOWN_STRIDE);
116 writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
117 i * L2X0_LOCKDOWN_STRIDE);
118 }
119 return 0;
120}
121
122static int __init ux500_l2x0_init(void)
103{ 123{
104 if (cpu_is_u5500()) 124 if (cpu_is_u5500())
105 l2x0_base = __io_address(U5500_L2CC_BASE); 125 l2x0_base = __io_address(U5500_L2CC_BASE);
@@ -108,6 +128,9 @@ static int ux500_l2x0_init(void)
108 else 128 else
109 ux500_unknown_soc(); 129 ux500_unknown_soc();
110 130
131 /* Unlock before init */
132 ux500_l2x0_unlock();
133
111 /* 64KB way size, 8 way associativity, force WA */ 134 /* 64KB way size, 8 way associativity, force WA */
112 l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); 135 l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
113 136