]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/arm/cpu/armv7/mx6/soc.c
Merge branch 'master' of git://git.denx.de/u-boot
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / mx6 / soc.c
index 2aad0a15bb90391f715578502312cb19634cf07f..2012caf2e77e033ffa60259d71817d002e828ca3 100644 (file)
@@ -8,6 +8,8 @@
  */
 
 #include <common.h>
+#include <asm/armv7.h>
+#include <asm/pl310.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
@@ -41,14 +43,19 @@ u32 get_cpu_rev(void)
 
        if (type != MXC_CPU_MX6SL) {
                reg = readl(&anatop->digprog);
+               struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
+               u32 cfg = readl(&scu->config) & 3;
                type = ((reg >> 16) & 0xff);
                if (type == MXC_CPU_MX6DL) {
-                       struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
-                       u32 cfg = readl(&scu->config) & 3;
-
                        if (!cfg)
                                type = MXC_CPU_MX6SOLO;
                }
+
+               if (type == MXC_CPU_MX6Q) {
+                       if (cfg == 1)
+                               type = MXC_CPU_MX6D;
+               }
+
        }
        reg &= 0xff;            /* mx6 silicon revision */
        return (type << 12) | (reg + 0x10);
@@ -62,6 +69,9 @@ u32 __weak get_board_rev(void)
        if (type == MXC_CPU_MX6SOLO)
                cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
 
+       if (type == MXC_CPU_MX6D)
+               cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF);
+
        return cpurev;
 }
 #endif
@@ -69,9 +79,15 @@ u32 __weak get_board_rev(void)
 void init_aips(void)
 {
        struct aipstz_regs *aips1, *aips2;
+#ifdef CONFIG_MX6SX
+       struct aipstz_regs *aips3;
+#endif
 
        aips1 = (struct aipstz_regs *)AIPS1_BASE_ADDR;
        aips2 = (struct aipstz_regs *)AIPS2_BASE_ADDR;
+#ifdef CONFIG_MX6SX
+       aips3 = (struct aipstz_regs *)AIPS3_BASE_ADDR;
+#endif
 
        /*
         * Set all MPROTx to be non-bufferable, trusted for R/W,
@@ -97,6 +113,26 @@ void init_aips(void)
        writel(0x00000000, &aips2->opacr2);
        writel(0x00000000, &aips2->opacr3);
        writel(0x00000000, &aips2->opacr4);
+
+#ifdef CONFIG_MX6SX
+       /*
+        * Set all MPROTx to be non-bufferable, trusted for R/W,
+        * not forced to user-mode.
+        */
+       writel(0x77777777, &aips3->mprot0);
+       writel(0x77777777, &aips3->mprot1);
+
+       /*
+        * Set all OPACRx to be non-bufferable, not require
+        * supervisor privilege level for access,allow for
+        * write access and untrusted master access.
+        */
+       writel(0x00000000, &aips3->opacr0);
+       writel(0x00000000, &aips3->opacr1);
+       writel(0x00000000, &aips3->opacr2);
+       writel(0x00000000, &aips3->opacr3);
+       writel(0x00000000, &aips3->opacr4);
+#endif
 }
 
 static void clear_ldo_ramp(void)
@@ -114,10 +150,9 @@ static void clear_ldo_ramp(void)
 }
 
 /*
- * Set the VDDSOC
+ * Set the PMU_REG_CORE register
  *
- * Mask out the REG_CORE[22:18] bits (REG2_TRIG) and set
- * them to the specified millivolt level.
+ * Set LDO_SOC/PU/ARM regulators to the specified millivolt level.
  * Possible values are from 0.725V to 1.450V in steps of
  * 0.025V (25mV).
  */
@@ -367,3 +402,59 @@ void imx_setup_hdmi(void)
        writel(reg, &mxc_ccm->chsccdr);
 }
 #endif
+
+#ifndef CONFIG_SYS_L2CACHE_OFF
+#define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002
+void v7_outer_cache_enable(void)
+{
+       struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
+       unsigned int val;
+
+#if defined CONFIG_MX6SL
+       struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+       val = readl(&iomux->gpr[11]);
+       if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) {
+               /* L2 cache configured as OCRAM, reset it */
+               val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM;
+               writel(val, &iomux->gpr[11]);
+       }
+#endif
+
+       writel(0x132, &pl310->pl310_tag_latency_ctrl);
+       writel(0x132, &pl310->pl310_data_latency_ctrl);
+
+       val = readl(&pl310->pl310_prefetch_ctrl);
+
+       /* Turn on the L2 I/D prefetch */
+       val |= 0x30000000;
+
+       /*
+        * 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
+        * 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
+       writel(val, &pl310->pl310_prefetch_ctrl);
+
+       val = readl(&pl310->pl310_power_ctrl);
+       val |= L2X0_DYNAMIC_CLK_GATING_EN;
+       val |= L2X0_STNDBY_MODE_EN;
+       writel(val, &pl310->pl310_power_ctrl);
+
+       setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+}
+
+void v7_outer_cache_disable(void)
+{
+       struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
+
+       clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+}
+#endif /* !CONFIG_SYS_L2CACHE_OFF */