[PATCH v2 2/5] ARM: cache-l2x0: Manage the errata at run time
From: srinidhi kasagar <hidden>
Date: 2013-01-29 10:14:39
Subsystem:
arm port, the rest · Maintainers:
Russell King, Linus Torvalds
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 <redacted> --- arch/arm/include/asm/hardware/cache-l2x0.h | 1 + arch/arm/mm/cache-l2x0.c | 72 +++++++++++++-------------- 2 files changed, 36 insertions(+), 37 deletions(-)
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 49ac638..ab76131 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h@@ -134,6 +134,7 @@ struct l2x0_regs { }; extern struct l2x0_regs l2x0_saved_regs; +extern u32 l2x0_revision; #endif /* __ASSEMBLY__ */
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 432fef0..4f66e64 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c@@ -38,8 +38,10 @@ static unsigned long sync_reg_offset = L2X0_CACHE_SYNC; /* Aurora don't have the cache ID register available, so we have to * pass it though the device tree */ static u32 cache_id_part_number_from_dt; +static u32 cache_rtl_number_from_dt; struct l2x0_regs l2x0_saved_regs; +u32 l2x0_revision; struct l2x0_of_data { void (*setup)(const struct device_node *, u32 *, u32 *);
@@ -87,7 +89,6 @@ 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) { if (outer_cache.set_debug)
@@ -96,37 +97,31 @@ static inline void debug_writel(unsigned long 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) -{ + /* manage ERRATA_588369 and ERRATA_727915 */ + if (l2x0_revision == L2X0_CACHE_ID_RTL_R0P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R1P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R2P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R3P0) + writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); } -#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); + /* manage the ERRATA_588369 */ + 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) {
@@ -330,11 +325,15 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask, bool smc) const char *type; l2x0_base = base; - if (cache_id_part_number_from_dt) + if (cache_id_part_number_from_dt) { cache_id = cache_id_part_number_from_dt; - else + l2x0_revision = cache_rtl_number_from_dt; + } else { cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & L2X0_CACHE_ID_PART_MASK; + l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) + & L2X0_CACHE_ID_RTL_MASK; + } aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); aux &= aux_mask;
@@ -348,10 +347,13 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask, bool smc) else ways = 8; type = "L310"; -#ifdef CONFIG_PL310_ERRATA_753970 - /* Unmapped register. */ - sync_reg_offset = L2X0_DUMMY_REG; -#endif + + /* handle ERRATA_753970 */ + if (l2x0_revision == L2X0_CACHE_ID_RTL_R3P0) { + /* Unmapped register. */ + sync_reg_offset = L2X0_DUMMY_REG; + } + if (smc) outer_cache.set_debug = pl310_set_debug; else
@@ -605,8 +607,6 @@ 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; l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base + L2X0_TAG_LATENCY_CTRL);
@@ -655,7 +655,6 @@ static void l2x0_resume(void) static void pl310_resume(void) { - u32 l2x0_revision; if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { /* restore pl310 setup */
@@ -668,9 +667,6 @@ 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; - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) { writel_relaxed(l2x0_saved_regs.prefetch_ctrl, l2x0_base + L2X0_PREFETCH_CTRL);
@@ -710,6 +706,8 @@ static void __init aurora_of_setup(const struct device_node *np, of_property_read_u32(np, "cache-id-part", &cache_id_part_number_from_dt); + of_property_read_u32(np, "cache-id-rtl", + &cache_rtl_number_from_dt); /* Determine and save the write policy */ l2_wt_override = of_property_read_bool(np, "wt-override");
--
1.7.2.dirty