[PATCH 1/4] ARM: cache-l2x0: Manage the errata at run time

srinidhi kasagar srinidhi.kasagar at stericsson.com
Mon Jan 21 08:14:53 EST 2013


Make it possible to manage the errata by its own by using the
l2x0 ID register. This relieves the platforms from choosing the
Errata's at compile time

Signed-off-by: srinidhi kasagar <srinidhi.kasagar at stericsson.com>
---
 arch/arm/include/asm/hardware/cache-l2x0.h |    2 +
 arch/arm/mm/cache-l2x0.c                   |   77 +++++++++++++++-------------
 2 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 3b2c40b..d5994ac 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -117,6 +117,8 @@ static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
 }
 #endif
 
+asmlinkage u32 l2x0_get_rtl_release(void);
+
 struct l2x0_regs {
 	unsigned long phy_base;
 	unsigned long aux_ctrl;
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index c2f3739..49058ac 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -49,6 +49,16 @@ struct l2x0_of_data {
 
 static bool of_init = false;
 
+/*
+ * Identify ther RTL releases of l2x0 - This might help in applying
+ * the l2x0 errata's dynamically rather compile time options
+ */
+asmlinkage u32 l2x0_get_rtl_release(void)
+{
+	return readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
+			L2X0_CACHE_ID_RTL_MASK;
+}
+
 static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
 {
 	/* wait for cache operation by line or way to complete */
@@ -87,46 +97,41 @@ static inline void l2x0_inv_line(unsigned long addr)
 	writel_relaxed(addr, base + L2X0_INV_LINE_PA);
 }
 
-#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
-static inline void debug_writel(unsigned long val)
+static void debug_writel(unsigned long val)
 {
-	if (outer_cache.set_debug)
-		outer_cache.set_debug(val);
+	u32 l2x0_revision = l2x0_get_rtl_release();
+
+	if (l2x0_revision == L2X0_CACHE_ID_RTL_R3P0 ||
+		l2x0_revision == L2X0_CACHE_ID_RTL_R2P0 ||
+		l2x0_revision == L2X0_CACHE_ID_RTL_R1P0 ||
+		l2x0_revision == L2X0_CACHE_ID_RTL_R0P0)
+			if (outer_cache.set_debug)
+				outer_cache.set_debug(val);
 }
 
 static void pl310_set_debug(unsigned long val)
 {
 	writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
 }
-#else
-/* Optimised out for non-errata case */
-static inline void debug_writel(unsigned long val)
-{
-}
-
-#define pl310_set_debug	NULL
-#endif
-
-#ifdef CONFIG_PL310_ERRATA_588369
-static inline void l2x0_flush_line(unsigned long addr)
-{
-	void __iomem *base = l2x0_base;
-
-	/* Clean by PA followed by Invalidate by PA */
-	cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
-	writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
-	cache_wait(base + L2X0_INV_LINE_PA, 1);
-	writel_relaxed(addr, base + L2X0_INV_LINE_PA);
-}
-#else
 
 static inline void l2x0_flush_line(unsigned long addr)
 {
 	void __iomem *base = l2x0_base;
-	cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-	writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA);
+	u32 l2x0_revision = l2x0_get_rtl_release();
+
+	if (l2x0_revision == L2X0_CACHE_ID_RTL_R0P0 ||
+		l2x0_revision == L2X0_CACHE_ID_RTL_R1P0)
+	{
+		/* Clean by PA followed by Invalidate by PA */
+		cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+		writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
+		cache_wait(base + L2X0_INV_LINE_PA, 1);
+		writel_relaxed(addr, base + L2X0_INV_LINE_PA);
+	} else {
+		cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
+		writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA);
+	}
 }
-#endif
 
 static void l2x0_cache_sync(void)
 {
@@ -328,6 +333,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 	int ways;
 	int way_size_shift = L2X0_WAY_SIZE_SHIFT;
 	const char *type;
+	u32 l2x0_revision = l2x0_get_rtl_release();
 
 	l2x0_base = base;
 	if (cache_id_part_number_from_dt)
@@ -348,10 +354,11 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 		else
 			ways = 8;
 		type = "L310";
-#ifdef CONFIG_PL310_ERRATA_753970
-		/* Unmapped register. */
-		sync_reg_offset = L2X0_DUMMY_REG;
-#endif
+
+		if (l2x0_revision == L2X0_CACHE_ID_RTL_R3P0)
+			/* Unmapped register. */
+			sync_reg_offset = L2X0_DUMMY_REG;
+
 		if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0)
 			outer_cache.set_debug = pl310_set_debug;
 		break;
@@ -594,8 +601,7 @@ static void __init pl310_of_setup(const struct device_node *np,
 
 static void __init pl310_save(void)
 {
-	u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
-		L2X0_CACHE_ID_RTL_MASK;
+	u32 l2x0_revision = l2x0_get_rtl_release();
 
 	l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base +
 		L2X0_TAG_LATENCY_CTRL);
@@ -657,8 +663,7 @@ static void pl310_resume(void)
 		writel_relaxed(l2x0_saved_regs.filter_start,
 			l2x0_base + L2X0_ADDR_FILTER_START);
 
-		l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
-			L2X0_CACHE_ID_RTL_MASK;
+		l2x0_revision = l2x0_get_rtl_release();
 
 		if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
 			writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
-- 
1.7.2.dirty




More information about the linux-arm-kernel mailing list