summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/imx6.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/imx6.c')
-rw-r--r--arch/arm/mach-imx/imx6.c127
1 files changed, 42 insertions, 85 deletions
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index 6a9ea23c71..b0d3d8ef2f 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -1,15 +1,4 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
+// SPDX-License-Identifier: GPL-2.0-or-later
#include <abort.h>
#include <init.h>
@@ -17,15 +6,15 @@
#include <io.h>
#include <linux/sizes.h>
#include <mfd/imx6q-iomuxc-gpr.h>
-#include <mach/clock-imx6.h>
-#include <mach/imx6.h>
-#include <mach/generic.h>
-#include <mach/revision.h>
-#include <mach/reset-reason.h>
-#include <mach/imx6-anadig.h>
-#include <mach/imx6-regs.h>
-#include <mach/imx6-fusemap.h>
-#include <mach/usb.h>
+#include <mach/imx/clock-imx6.h>
+#include <mach/imx/imx6.h>
+#include <mach/imx/generic.h>
+#include <mach/imx/revision.h>
+#include <mach/imx/reset-reason.h>
+#include <mach/imx/imx6-anadig.h>
+#include <mach/imx/imx6-regs.h>
+#include <mach/imx/imx6-fusemap.h>
+#include <mach/imx/usb.h>
#include <asm/mmu.h>
#include <asm/cache-l2x0.h>
#include <mfd/pfuze.h>
@@ -42,76 +31,44 @@
#define MX6_OCOTP_CFG0 0x410
#define MX6_OCOTP_CFG1 0x420
-static void imx6_init_lowlevel(void)
+static void imx6_configure_aips(void __iomem *aips)
{
- void __iomem *aips1 = (void *)MX6_AIPS1_ON_BASE_ADDR;
- void __iomem *aips2 = (void *)MX6_AIPS2_ON_BASE_ADDR;
- bool is_imx6q = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6Q;
- bool is_imx6d = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6D;
- uint32_t val_480;
- uint32_t val_528;
- uint32_t periph_sel_1;
- uint32_t periph_sel_2;
- uint32_t reg;
-
- if ((readl(MXC_CCM_CCGR6) & 0x3))
- imx_reset_otg_controller(IOMEM(MX6_OTG_BASE_ADDR));
-
/*
* Set all MPROTx to be non-bufferable, trusted for R/W,
* not forced to user-mode.
*/
- writel(0x77777777, aips1);
- writel(0x77777777, aips1 + 0x4);
- writel(0, aips1 + 0x40);
- writel(0, aips1 + 0x44);
- writel(0, aips1 + 0x48);
- writel(0, aips1 + 0x4c);
- writel(0, aips1 + 0x50);
-
- writel(0x77777777, aips2);
- writel(0x77777777, aips2 + 0x4);
- writel(0, aips2 + 0x40);
- writel(0, aips2 + 0x44);
- writel(0, aips2 + 0x48);
- writel(0, aips2 + 0x4c);
- writel(0, aips2 + 0x50);
-
- /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
- * to make sure PFD is working right, otherwise, PFDs may
- * not output clock after reset, MX6DL and MX6SL have added 396M pfd
- * workaround in ROM code, as bus clock need it.
- * Don't reset PLL2 PFD0 / PLL2 PFD2 if is's used by periph_clk.
- */
- if (is_imx6q || is_imx6d) {
- val_480 = BM_ANADIG_PFD_480_PFD3_CLKGATE |
- BM_ANADIG_PFD_480_PFD2_CLKGATE |
- BM_ANADIG_PFD_480_PFD1_CLKGATE |
- BM_ANADIG_PFD_480_PFD0_CLKGATE;
+ writel(0x77777777, aips);
+ writel(0x77777777, aips + 0x4);
- val_528 = BM_ANADIG_PFD_528_PFD3_CLKGATE |
- BM_ANADIG_PFD_528_PFD1_CLKGATE;
-
- reg = readl(MXC_CCM_CBCMR);
- periph_sel_1 = (reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
- >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
-
- periph_sel_2 = (reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)
- >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET;
-
- if ((periph_sel_1 != 0x2) && (periph_sel_2 != 0x2))
- val_528 |= BM_ANADIG_PFD_528_PFD0_CLKGATE;
+ /*
+ * Set all OPACRx to be non-bufferable, not require
+ * supervisor privilege level for access,allow for
+ * write access and untrusted master access.
+ */
+ writel(0, aips + 0x40);
+ writel(0, aips + 0x44);
+ writel(0, aips + 0x48);
+ writel(0, aips + 0x4c);
+ writel(0, aips + 0x50);
+}
- if ((periph_sel_1 != 0x1) && (periph_sel_2 != 0x1)
- && (periph_sel_1 != 0x3) && (periph_sel_2 != 0x3))
- val_528 |= BM_ANADIG_PFD_528_PFD2_CLKGATE;
+static void imx6_init_lowlevel(void)
+{
+ bool is_imx6ull = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6ULL;
+ bool is_imx6sx = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6SX;
- writel(val_480, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_SET);
- writel(val_528, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_SET);
+ /*
+ * Before reset the controller imx6_boot_save_loc() must be called to
+ * detect serial-downloader fall back boots. For further information
+ * check the comment in imx6_get_boot_source().
+ */
+ if ((readl(MXC_CCM_CCGR6) & 0x3))
+ imx_reset_otg_controller(IOMEM(MX6_OTG_BASE_ADDR));
- writel(val_480, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_CLR);
- writel(val_528, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_CLR);
- }
+ imx6_configure_aips(IOMEM(MX6_AIPS1_ON_BASE_ADDR));
+ imx6_configure_aips(IOMEM(MX6_AIPS2_ON_BASE_ADDR));
+ if (is_imx6ull || is_imx6sx)
+ imx6_configure_aips(IOMEM(MX6_AIPS3_ON_BASE_ADDR));
}
static bool imx6_has_ipu(void)
@@ -216,10 +173,10 @@ int imx6_init(void)
void __iomem *src = IOMEM(MX6_SRC_BASE_ADDR);
u64 mx6_uid;
- imx6_init_lowlevel();
-
imx6_boot_save_loc();
+ imx6_init_lowlevel();
+
mx6_silicon_revision = imx6_cpu_revision();
mx6_uid = imx6_uid();
@@ -369,7 +326,7 @@ static int imx6_fixup_cpus(struct device_node *root, void *context)
unsigned long scu_phys_base;
unsigned int max_core_index;
- cpus_node = of_find_node_by_name(root, "cpus");
+ cpus_node = of_find_node_by_name_address(root, "cpus");
if (!cpus_node)
return 0;