diff options
Diffstat (limited to 'arch/arm/mach-ux500')
-rw-r--r-- | arch/arm/mach-ux500/cpu.c | 25 |
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 | ||
102 | static int ux500_l2x0_init(void) | 102 | static 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 | |||
122 | static 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 | ||