aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason McMullan <jason.mcmullan@gmail.com>2010-05-05 13:59:37 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-05-15 10:03:50 -0400
commit64039be8226b9f6c80c704d94ac9891eee4a274c (patch)
tree60a675fdc5e5734a8f73b5c1081f4b966fea59e8
parenta2227120eead4ea7d2ea04d8ce0947f1dd23dedf (diff)
ARM: 6094/1: Extend cache-l2x0 to support the 16-way PL310
The L310 cache controller's interface is almost identical to the L210. One major difference is that the PL310 can have up to 16 ways. This change uses the cache's part ID and the Associativity bits in the AUX_CTRL register to determine the number of ways. Also, this version prints out the CACHE_ID and AUX_CTRL registers. Acked-by: Will Deacon <will.deacon@arm.com> Acked-by: Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Jason S. McMullan <jason.mcmullan@netronome.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h3
-rw-r--r--arch/arm/mm/cache-l2x0.c39
2 files changed, 37 insertions, 5 deletions
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index cdb9022716fd..6bcba48800fe 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -21,6 +21,9 @@
21#define __ASM_ARM_HARDWARE_L2X0_H 21#define __ASM_ARM_HARDWARE_L2X0_H
22 22
23#define L2X0_CACHE_ID 0x000 23#define L2X0_CACHE_ID 0x000
24#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
25#define L2X0_CACHE_ID_PART_L210 (1 << 6)
26#define L2X0_CACHE_ID_PART_L310 (3 << 6)
24#define L2X0_CACHE_TYPE 0x004 27#define L2X0_CACHE_TYPE 0x004
25#define L2X0_CTRL 0x100 28#define L2X0_CTRL 0x100
26#define L2X0_AUX_CTRL 0x104 29#define L2X0_AUX_CTRL 0x104
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 07334632d3e2..78f0fc8595e2 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{
@@ -99,8 +100,8 @@ static inline void l2x0_inv_all(void)
99 100
100 /* invalidate all ways */ 101 /* invalidate all ways */
101 spin_lock_irqsave(&l2x0_lock, flags); 102 spin_lock_irqsave(&l2x0_lock, flags);
102 writel(0xff, l2x0_base + L2X0_INV_WAY); 103 writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
103 cache_wait(l2x0_base + L2X0_INV_WAY, 0xff); 104 cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
104 cache_sync(); 105 cache_sync();
105 spin_unlock_irqrestore(&l2x0_lock, flags); 106 spin_unlock_irqrestore(&l2x0_lock, flags);
106} 107}
@@ -199,9 +200,37 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
199void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) 200void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
200{ 201{
201 __u32 aux; 202 __u32 aux;
203 __u32 cache_id;
204 int ways;
205 const char *type;
202 206
203 l2x0_base = base; 207 l2x0_base = base;
204 208
209 cache_id = readl(l2x0_base + L2X0_CACHE_ID);
210 aux = readl(l2x0_base + L2X0_AUX_CTRL);
211
212 /* Determine the number of ways */
213 switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
214 case L2X0_CACHE_ID_PART_L310:
215 if (aux & (1 << 16))
216 ways = 16;
217 else
218 ways = 8;
219 type = "L310";
220 break;
221 case L2X0_CACHE_ID_PART_L210:
222 ways = (aux >> 13) & 0xf;
223 type = "L210";
224 break;
225 default:
226 /* Assume unknown chips have 8 ways */
227 ways = 8;
228 type = "L2x0 series";
229 break;
230 }
231
232 l2x0_way_mask = (1 << ways) - 1;
233
205 /* 234 /*
206 * Check if l2x0 controller is already enabled. 235 * Check if l2x0 controller is already enabled.
207 * If you are booting from non-secure mode 236 * If you are booting from non-secure mode
@@ -210,8 +239,6 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
210 if (!(readl(l2x0_base + L2X0_CTRL) & 1)) { 239 if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
211 240
212 /* l2x0 controller is disabled */ 241 /* l2x0 controller is disabled */
213
214 aux = readl(l2x0_base + L2X0_AUX_CTRL);
215 aux &= aux_mask; 242 aux &= aux_mask;
216 aux |= aux_val; 243 aux |= aux_val;
217 writel(aux, l2x0_base + L2X0_AUX_CTRL); 244 writel(aux, l2x0_base + L2X0_AUX_CTRL);
@@ -226,5 +253,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
226 outer_cache.clean_range = l2x0_clean_range; 253 outer_cache.clean_range = l2x0_clean_range;
227 outer_cache.flush_range = l2x0_flush_range; 254 outer_cache.flush_range = l2x0_flush_range;
228 255
229 printk(KERN_INFO "L2X0 cache controller enabled\n"); 256 printk(KERN_INFO "%s cache controller enabled\n", type);
257 printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
258 ways, cache_id, aux);
230} 259}