diff options
-rw-r--r-- | arch/arm/mm/cache-l2x0.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 369a9d01d94f..84933f48edea 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -480,6 +480,11 @@ static const struct l2c_init_data l2c220_data = { * hit the line between the clean operation and invalidate operation, * resulting in the store being lost. * + * 752271: PL310 R3P0->R3P1-50REL0, fixed R3P2. + * Affects: 8x64-bit (double fill) line fetches + * double fill line fetches can fail to cause dirty data to be evicted + * from the cache before the new data overwrites the second line. + * * 753970: PL310 R3P0, fixed R3P1. * Affects: sync * prevents merging writes after the sync operation, until another L2C @@ -628,7 +633,7 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id, struct outer_cache_fns *fns) { unsigned revision = cache_id & L2X0_CACHE_ID_RTL_MASK; - const char *errata[4]; + const char *errata[8]; unsigned n = 0; /* For compatibility */ @@ -651,6 +656,17 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id, errata[n++] = "727915"; } + if (revision >= L310_CACHE_ID_RTL_R3P0 && + revision < L310_CACHE_ID_RTL_R3P2) { + u32 val = readl_relaxed(base + L2X0_PREFETCH_CTRL); + /* I don't think bit23 is required here... but iMX6 does so */ + if (val & (BIT(30) | BIT(23))) { + val &= ~(BIT(30) | BIT(23)); + l2c_write_sec(val, base, L2X0_PREFETCH_CTRL); + errata[n++] = "752271"; + } + } + if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) && revision == L310_CACHE_ID_RTL_R3P0) { sync_reg_offset = L2X0_DUMMY_REG; |