diff options
-rw-r--r-- | arch/arm/include/asm/hardware/cache-l2x0.h | 3 | ||||
-rw-r--r-- | arch/arm/mm/cache-l2x0.c | 39 |
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 | ||
28 | static void __iomem *l2x0_base; | 28 | static void __iomem *l2x0_base; |
29 | static DEFINE_SPINLOCK(l2x0_lock); | 29 | static DEFINE_SPINLOCK(l2x0_lock); |
30 | static uint32_t l2x0_way_mask; /* Bitmask of active ways */ | ||
30 | 31 | ||
31 | static inline void cache_wait(void __iomem *reg, unsigned long mask) | 32 | static 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) | |||
199 | void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) | 200 | void __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 | } |