[PATCH v2 2/5] ARM: cache-l2x0: Manage the errata at run time
srinidhi kasagar
srinidhi.kasagar at stericsson.com
Tue Jan 29 05:14:39 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 | 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
More information about the linux-arm-kernel
mailing list