imx8m: rename clock to clock_imx8mq
[oweals/u-boot.git] / arch / arm / mach-imx / cache.c
index 11f90ed8a21ca41094b6edb61ab9fb3db23e5a5d..a60594250335289bc26a401fbe6b6dc377f86a5c 100644 (file)
@@ -9,7 +9,35 @@
 #include <asm/io.h>
 #include <asm/mach-imx/sys_proto.h>
 
-#ifndef CONFIG_SYS_DCACHE_OFF
+static void enable_ca7_smp(void)
+{
+       u32 val;
+
+       /* Read MIDR */
+       asm volatile ("mrc p15, 0, %0, c0, c0, 0\n\t" : "=r"(val));
+       val = (val >> 4);
+       val &= 0xf;
+
+       /* Only set the SMP for Cortex A7 */
+       if (val == 0x7) {
+               /* Read auxiliary control register */
+               asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t" : "=r"(val));
+
+               if (val & (1 << 6))
+                       return;
+
+               /* Enable SMP */
+               val |= (1 << 6);
+
+               /* Write auxiliary control register */
+               asm volatile ("mcr p15, 0, %0, c1, c0, 1\n\t" : : "r"(val));
+
+               DSB;
+               ISB;
+       }
+}
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
 void enable_caches(void)
 {
 #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
@@ -20,6 +48,9 @@ void enable_caches(void)
        /* Avoid random hang when download by usb */
        invalidate_dcache_all();
 
+       /* Set ACTLR.SMP bit for Cortex-A7 */
+       enable_ca7_smp();
+
        /* Enable D-cache. I-cache is already enabled in start.S */
        dcache_enable();
 
@@ -31,6 +62,17 @@ void enable_caches(void)
                                        IRAM_SIZE,
                                        option);
 }
+#else
+void enable_caches(void)
+{
+       /*
+        * Set ACTLR.SMP bit for Cortex-A7, even if the caches are
+        * disabled by u-boot
+        */
+       enable_ca7_smp();
+
+       puts("WARNING: Caches not enabled\n");
+}
 #endif
 
 #ifndef CONFIG_SYS_L2CACHE_OFF
@@ -40,7 +82,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;
 
 
        /*
@@ -70,22 +112,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);