Commit 48277f0a5162d2e1d67e6cfb830be9799f1c1904

Authored by Nitin Garg
1 parent be21be765d

MLK-10496: Check the PL310 version for applying errata

Apply errata based on PL310 version instead of compile
time. Also set Prefetch offset to 15, since it improves
memcpy performance by 35%. Don't enable Incr double
Linefill enable since it adversely affects memcpy
performance by about 32MB/s and reads by 90MB/s. Tested
with 4K to 16MB sized src and dst aligned buffer.

Signed-off-by: Nitin Garg <nitin.garg@freescale.com>

Showing 2 changed files with 15 additions and 8 deletions Side-by-side Diff

arch/arm/cpu/armv7/mx6/soc.c
... ... @@ -1029,7 +1029,7 @@
1029 1029 void v7_outer_cache_enable(void)
1030 1030 {
1031 1031 struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
1032   - unsigned int val;
  1032 + unsigned int val, cache_id;
1033 1033  
1034 1034 #if defined CONFIG_MX6SL
1035 1035 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
1036 1036  
1037 1037  
... ... @@ -1049,22 +1049,24 @@
1049 1049  
1050 1050 val = readl(&pl310->pl310_prefetch_ctrl);
1051 1051  
1052   - /* Turn on the L2 I/D prefetch */
1053   - val |= 0x30000000;
  1052 + /* Turn on the L2 I/D prefetch, double linefill */
  1053 + /* Set prefetch offset with any value except 23 as per errata 765569 */
  1054 + val |= 0x7000000f;
1054 1055  
1055 1056 /*
1056 1057 * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
1057   - * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
  1058 + * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL/SX
  1059 + * is r3p2.
1058 1060 * But according to ARM PL310 errata: 752271
1059 1061 * ID: 752271: Double linefill feature can cause data corruption
1060 1062 * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
1061 1063 * Workaround: The only workaround to this erratum is to disable the
1062 1064 * double linefill feature. This is the default behavior.
1063 1065 */
1064   -
1065   -#ifndef CONFIG_MX6Q
1066   - val |= 0x40800000;
1067   -#endif
  1066 + cache_id = readl(&pl310->pl310_cache_id);
  1067 + if (((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310)
  1068 + && ((cache_id & L2X0_CACHE_ID_RTL_MASK) < L2X0_CACHE_ID_RTL_R3P2))
  1069 + val &= ~(1 << 30);
1068 1070 writel(val, &pl310->pl310_prefetch_ctrl);
1069 1071  
1070 1072 val = readl(&pl310->pl310_power_ctrl);
arch/arm/include/asm/pl310.h
... ... @@ -75,5 +75,10 @@
75 75 void pl310_inval_range(u32 start, u32 end);
76 76 void pl310_clean_inval_range(u32 start, u32 end);
77 77  
  78 +#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
  79 +#define L2X0_CACHE_ID_PART_L310 (3 << 6)
  80 +#define L2X0_CACHE_ID_RTL_MASK 0x3f
  81 +#define L2X0_CACHE_ID_RTL_R3P2 0x8
  82 +
78 83 #endif