Skip to contentSkip to conversation

Extend cache-l2x0 to support the 16-way PL310

PATCH New Jason S. McMullan 2 participants 3 messages Apr 30, 2010 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Extend cache-l2x0 to support the 16-way PL310

Support the PL310 16-way cache controller.

Also adds support for smaller than 8 way PL210 controllers.

Jason S. McMullan (1):
[arm l2x0] Extend cache-l2x0 to support the 16-way PL310

 arch/arm/include/asm/hardware/cache-l2x0.h |    3 ++
 arch/arm/mm/cache-l2x0.c                   |   30 ++++++++++++++++++++++++---
 2 files changed, 29 insertions(+), 4 deletions(-)
#1 lore raw

PATCH 1/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 Assciativity bits in the AUX_CTRL register to determine the number of ways.

---
 arch/arm/include/asm/hardware/cache-l2x0.h |    3 ++
 arch/arm/mm/cache-l2x0.c                   |   30 ++++++++++++++++++++++++---
 2 files changed, 29 insertions(+), 4 deletions(-)
arch/arm/include/asm/hardware/cache-l2x0.h +3 -0
index cdb9022..6bcba48 100644
@@ -21,6 +21,9 @@
 #define __ASM_ARM_HARDWARE_L2X0_H
 
 #define L2X0_CACHE_ID			0x000
+#define   L2X0_CACHE_ID_PART_MASK	(0xf << 6)
+#define   L2X0_CACHE_ID_PART_L210	(1 << 6)
+#define   L2X0_CACHE_ID_PART_L310	(3 << 6)
 #define L2X0_CACHE_TYPE			0x004
 #define L2X0_CTRL			0x100
 #define L2X0_AUX_CTRL			0x104
arch/arm/mm/cache-l2x0.c +26 -4
index 21ad68b..32a70a7 100644
@@ -27,6 +27,7 @@
 
 static void __iomem *l2x0_base;
 static DEFINE_SPINLOCK(l2x0_lock);
+static uint32_t l2x0_way_mask;	/* Bitmask of active ways */
 
 static inline void cache_wait(void __iomem *reg, unsigned long mask)
 {
@@ -106,10 +107,9 @@ static inline void l2x0_inv_all(void)
 {
 	unsigned long flags;
 
-	/* invalidate all ways */
 	spin_lock_irqsave(&l2x0_lock, flags);
-	writel(0xff, l2x0_base + L2X0_INV_WAY);
-	cache_wait(l2x0_base + L2X0_INV_WAY, 0xff);
+	writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+	cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
 	cache_sync();
 	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
@@ -217,10 +217,32 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 	 * accessing the below registers will fault.
 	 */
 	if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
+		int ways;
+		uint32_t cache_id;
 
 		/* l2x0 controller is disabled */
-
+		cache_id = readl(l2x0_base + L2X0_CACHE_ID);
 		aux = readl(l2x0_base + L2X0_AUX_CTRL);
+
+		/* Determine the number of ways */
+		switch (cache_id) {
+		case L2X0_CACHE_ID_PART_L310:
+			if (aux & (1 << 16))
+				ways = 16;
+			else
+				ways = 8;
+			break;
+		case L2X0_CACHE_ID_PART_L210:
+			ways = (aux >> 13) & 0xf;
+			break;
+		default:
+			/* Assume unknown chips have 8 ways */
+			ways = 8;
+			break;
+		}
+
+		l2x0_way_mask = (1 << ways) - 1;
+
 		aux &= aux_mask;
 		aux |= aux_val;
 		writel(aux, l2x0_base + L2X0_AUX_CTRL);
Signature · 1 line
1.7.0.4
#2 lore raw

PATCH 1/1 Extend cache-l2x0 to support the 16-way PL310

Quoted 13 lines · Jason S. McMullan
arch/arm/mm/cache-l2x0.c +5 -1
@@ -217,10 +217,32 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 	 * accessing the below registers will fault.
 	 */
 	if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
+		int ways;
+		uint32_t cache_id;
 
 		/* l2x0 controller is disabled */
-
+		cache_id = readl(l2x0_base + L2X0_CACHE_ID);
 		aux = readl(l2x0_base + L2X0_AUX_CTRL);
+
+		/* Determine the number of ways */

arch/arm/mm/cache-l2x0.c void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) · line 237

Quoted 10 lines
arch/arm/mm/cache-l2x0.c +10 -0
+		switch (cache_id) {
+		case L2X0_CACHE_ID_PART_L310:
+			if (aux & (1 << 16))
+				ways = 16;
+			else
+				ways = 8;
+			break;
+		case L2X0_CACHE_ID_PART_L210:
+			ways = (aux >> 13) & 0xf;
+			break;

One of the things I found myself wishing for with the problems OMAP is currently having is a means by which the "L2X0 cache controller enabled" could be more informative about the L2 cache controller.

Maybe it should be "%s cache controller rel%u enabled". Also note that the L210 and L220 cache controllers have different cache IDs. L210 has a 1 in bits 9:6, and L220 is 2 in bits 9:6.

However, as for the above patch, I don't think the above code will work; you're defining the L2X0_CACHE_ID_PART_L310 / L2X0_CACHE_ID_PART_L210 IDs to refer just to the part number field, but you're not masking off the rest of the fields in cache_id.