aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/cache-l2x0.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/cache-l2x0.c')
-rw-r--r--arch/arm/mm/cache-l2x0.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 21ad68ba22ba..9819869d2bc9 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -27,6 +27,7 @@
27 27
28static void __iomem *l2x0_base; 28static void __iomem *l2x0_base;
29static DEFINE_SPINLOCK(l2x0_lock); 29static DEFINE_SPINLOCK(l2x0_lock);
30static uint32_t l2x0_way_mask; /* Bitmask of active ways */
30 31
31static inline void cache_wait(void __iomem *reg, unsigned long mask) 32static inline void cache_wait(void __iomem *reg, unsigned long mask)
32{ 33{
@@ -108,8 +109,8 @@ static inline void l2x0_inv_all(void)
108 109
109 /* invalidate all ways */ 110 /* invalidate all ways */
110 spin_lock_irqsave(&l2x0_lock, flags); 111 spin_lock_irqsave(&l2x0_lock, flags);
111 writel(0xff, l2x0_base + L2X0_INV_WAY); 112 writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
112 cache_wait(l2x0_base + L2X0_INV_WAY, 0xff); 113 cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
113 cache_sync(); 114 cache_sync();
114 spin_unlock_irqrestore(&l2x0_lock, flags); 115 spin_unlock_irqrestore(&l2x0_lock, flags);
115} 116}
@@ -208,9 +209,37 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
208void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) 209void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
209{ 210{
210 __u32 aux; 211 __u32 aux;
212 __u32 cache_id;
213 int ways;
214 const char *type;
211 215
212 l2x0_base = base; 216 l2x0_base = base;
213 217
218 cache_id = readl(l2x0_base + L2X0_CACHE_ID);
219 aux = readl(l2x0_base + L2X0_AUX_CTRL);
220
221 /* Determine the number of ways */
222 switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
223 case L2X0_CACHE_ID_PART_L310:
224 if (aux & (1 << 16))
225 ways = 16;
226 else
227 ways = 8;
228 type = "L310";
229 break;
230 case L2X0_CACHE_ID_PART_L210:
231 ways = (aux >> 13) & 0xf;
232 type = "L210";
233 break;
234 default:
235 /* Assume unknown chips have 8 ways */
236 ways = 8;
237 type = "L2x0 series";
238 break;
239 }
240
241 l2x0_way_mask = (1 << ways) - 1;
242
214 /* 243 /*
215 * Check if l2x0 controller is already enabled. 244 * Check if l2x0 controller is already enabled.
216 * If you are booting from non-secure mode 245 * If you are booting from non-secure mode
@@ -219,8 +248,6 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
219 if (!(readl(l2x0_base + L2X0_CTRL) & 1)) { 248 if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
220 249
221 /* l2x0 controller is disabled */ 250 /* l2x0 controller is disabled */
222
223 aux = readl(l2x0_base + L2X0_AUX_CTRL);
224 aux &= aux_mask; 251 aux &= aux_mask;
225 aux |= aux_val; 252 aux |= aux_val;
226 writel(aux, l2x0_base + L2X0_AUX_CTRL); 253 writel(aux, l2x0_base + L2X0_AUX_CTRL);
@@ -236,5 +263,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
236 outer_cache.flush_range = l2x0_flush_range; 263 outer_cache.flush_range = l2x0_flush_range;
237 outer_cache.sync = l2x0_cache_sync; 264 outer_cache.sync = l2x0_cache_sync;
238 265
239 printk(KERN_INFO "L2X0 cache controller enabled\n"); 266 printk(KERN_INFO "%s cache controller enabled\n", type);
267 printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
268 ways, cache_id, aux);
240} 269}