MLK-10496: Check the PL310 version for applying errata
authorNitin Garg <nitin.garg@freescale.com>
Fri, 27 Mar 2015 19:45:43 +0000 (14:45 -0500)
committerYe Li <ye.li@nxp.com>
Wed, 5 Apr 2017 06:04:34 +0000 (14:04 +0800)
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>
(cherry picked from commit 31751fa9cf29ef4056f49fe06a54700a89c9bdc5)

arch/arm/imx-common/cache.c
arch/arm/include/asm/pl310.h

index 1c4a9a2..af14702 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Freescale Semiconductor, Inc.
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
  *
  * SPDX-License-Identifier:     GPL-2.0+
  */
@@ -41,7 +41,7 @@ void v7_outer_cache_enable(void)
 {
        struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
-       unsigned int val;
+       unsigned int val, cache_id;
 
 
        /*
@@ -71,22 +71,24 @@ void v7_outer_cache_enable(void)
 
        val = readl(&pl310->pl310_prefetch_ctrl);
 
-       /* Turn on the L2 I/D prefetch */
-       val |= 0x30000000;
+       /* Turn on the L2 I/D prefetch, double linefill */
+       /* Set prefetch offset with any value except 23 as per errata 765569 */
+       val |= 0x7000000f;
 
        /*
         * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
-        * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
+        * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL/SX/DQP
+        * is r3p2.
         * But according to ARM PL310 errata: 752271
         * ID: 752271: Double linefill feature can cause data corruption
         * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
         * Workaround: The only workaround to this erratum is to disable the
         * double linefill feature. This is the default behavior.
         */
-
-#ifndef CONFIG_MX6Q
-       val |= 0x40800000;
-#endif
+       cache_id = readl(&pl310->pl310_cache_id);
+       if (((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310)
+           && ((cache_id & L2X0_CACHE_ID_RTL_MASK) < L2X0_CACHE_ID_RTL_R3P2))
+               val &= ~(1 << 30);
        writel(val, &pl310->pl310_prefetch_ctrl);
 
        val = readl(&pl310->pl310_power_ctrl);
index d588f94..6f79178 100644 (file)
@@ -3,6 +3,8 @@
  * Texas Instruments, <www.ti.com>
  * Aneesh V <aneesh@ti.com>
  *
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #ifndef _PL310_H_
@@ -79,4 +81,9 @@ void pl310_clean_inval_all(void);
 void pl310_inval_range(u32 start, u32 end);
 void pl310_clean_inval_range(u32 start, u32 end);
 
+#define L2X0_CACHE_ID_PART_MASK                (0xf << 6)
+#define L2X0_CACHE_ID_PART_L310                (3 << 6)
+#define L2X0_CACHE_ID_RTL_MASK          0x3f
+#define L2X0_CACHE_ID_RTL_R3P2          0x8
+
 #endif