summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/mx6
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2018-03-23 02:37:28 -0700
committerYe Li <ye.li@nxp.com>2022-04-06 15:58:23 +0800
commitca974b7a4878e8bd929be422a2667b4c585ba1f0 (patch)
tree553aae1dd848cb3d5d318e3d38254bab9eb6062e /arch/arm/mach-imx/mx6
parenta9ae45e3d0e6a4ecc8088cc8dcf94a273f00df7a (diff)
MLK-18146-1 mx6: Align SOC level codes with v2020.04
Update codes for i.MX6 soc and clock settings to align with v2020.04 Signed-off-by: Ye Li <ye.li@nxp.com> (cherry picked from commit 82ecba47271848a339a53eef7e770526bc3b3967) (cherry picked from commit fa452a1fa374f5a26ed8c178c8c1fb3e383962e5) (cherry picked from commit d745866a43c0a69e4132c23a29106bfba6a32c9a) (cherry picked from commit e25ef41b6b62f55ed718669b831b6cd0d5595e90) (cherry picked from commit 8141deee6914f9ed88a9dc516707ad2101b3a618)
Diffstat (limited to 'arch/arm/mach-imx/mx6')
-rw-r--r--arch/arm/mach-imx/mx6/clock.c98
-rw-r--r--arch/arm/mach-imx/mx6/soc.c77
2 files changed, 174 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/mx6/clock.c b/arch/arm/mach-imx/mx6/clock.c
index 5735afd5f5..b4160a2906 100644
--- a/arch/arm/mach-imx/mx6/clock.c
+++ b/arch/arm/mach-imx/mx6/clock.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
*/
#include <common.h>
@@ -60,6 +61,12 @@ void setup_gpmi_io_clk(u32 cfg)
cfg);
setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK);
+#elif defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL)
+ clrsetbits_le32(&imx_ccm->cs2cdr,
+ MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
+ MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
+ MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
+ cfg);
#else
clrbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
@@ -851,6 +858,65 @@ int enable_lcdif_clock(u32 base_addr, bool enable)
return 0;
}
+
+int enable_lvds_bridge(u32 lcd_base_addr)
+{
+ u32 reg = 0;
+ struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+ if (is_cpu_type(MXC_CPU_MX6SX)) {
+ if ((lcd_base_addr != LCDIF1_BASE_ADDR) &&
+ (lcd_base_addr != LCDIF2_BASE_ADDR)) {
+ puts("Wrong LCD interface!\n");
+ return -EINVAL;
+ }
+ } else {
+ debug("This chip not support lvds bridge!\n");
+ return 0;
+ }
+
+ /* Turn on LDB DI0 clocks */
+ reg = readl(&imx_ccm->CCGR3);
+ reg |= MXC_CCM_CCGR3_LDB_DI0_MASK;
+ writel(reg, &imx_ccm->CCGR3);
+
+ /* set LDB DI0 clk select to 011 PLL2 PFD3 200M*/
+ reg = readl(&imx_ccm->cs2cdr);
+ reg &= ~MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK;
+ reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET);
+ writel(reg, &imx_ccm->cs2cdr);
+
+ reg = readl(&imx_ccm->cscmr2);
+ reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
+ writel(reg, &imx_ccm->cscmr2);
+
+ /* set LDB DI0 clock for LCDIF PIX clock */
+ reg = readl(&imx_ccm->cscdr2);
+ if (lcd_base_addr == LCDIF1_BASE_ADDR) {
+ reg &= ~MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK;
+ reg |= (0x3 << MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_OFFSET);
+ } else {
+ reg &= ~MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK;
+ reg |= (0x3 << MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_OFFSET);
+ }
+ writel(reg, &imx_ccm->cscdr2);
+
+ reg = IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
+ | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
+ | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
+ | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
+ writel(reg, &iomux->gpr[6]);
+
+ reg = readl(&iomux->gpr[5]);
+ if (lcd_base_addr == LCDIF1_BASE_ADDR)
+ reg &= ~0x8; /* MUX LVDS to LCDIF1 */
+ else
+ reg |= 0x8; /* MUX LVDS to LCDIF2 */
+ writel(reg, &iomux->gpr[5]);
+
+ return 0;
+}
+
#endif
#ifdef CONFIG_FSL_QSPI
@@ -1507,6 +1573,38 @@ void select_ldb_di_clock_source(enum ldb_di_clock clk)
}
#endif
+
+#if defined(CONFIG_MXC_EPDC)
+#if defined(CONFIG_MX6ULL) || defined(CONFIG_MX6SLL)
+void enable_epdc_clock(void)
+{
+ u32 reg = 0;
+
+ /* disable the clock gate first */
+ clrbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_EPDC_CLK_ENABLE_MASK);
+
+ /* PLL3_PFD2 */
+ reg = readl(&imx_ccm->chsccdr);
+ reg &= ~MXC_CCM_CHSCCDR_EPDC_PRE_CLK_SEL_MASK;
+ reg |= 5 << MXC_CCM_CHSCCDR_EPDC_PRE_CLK_SEL_OFFSET;
+ writel(reg, &imx_ccm->chsccdr);
+
+ reg = readl(&imx_ccm->chsccdr);
+ reg &= ~MXC_CCM_CHSCCDR_EPDC_PODF_MASK;
+ reg |= 7 << MXC_CCM_CHSCCDR_EPDC_PODF_OFFSET;
+ writel(reg, &imx_ccm->chsccdr);
+
+ reg = readl(&imx_ccm->chsccdr);
+ reg &= ~MXC_CCM_CHSCCDR_EPDC_CLK_SEL_MASK;
+ reg |= 0 <<MXC_CCM_CHSCCDR_EPDC_CLK_SEL_OFFSET;
+ writel(reg, &imx_ccm->chsccdr);
+
+ /* enable the clock gate */
+ setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_EPDC_CLK_ENABLE_MASK);
+}
+#endif
+#endif
+
/***************************************************/
U_BOOT_CMD(
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c
index b0ca72fdb3..a2419a4a94 100644
--- a/arch/arm/mach-imx/mx6/soc.c
+++ b/arch/arm/mach-imx/mx6/soc.c
@@ -24,8 +24,11 @@
#include <asm/arch/mxc_hdmi.h>
#include <asm/arch/crm_regs.h>
#include <dm.h>
+#include <fsl_sec.h>
#include <imx_thermal.h>
#include <mmc.h>
+#include <hang.h>
+#include <cpu_func.h>
#define has_err007805() \
(is_mx6sl() || is_mx6dl() || is_mx6solo() || is_mx6ull())
@@ -234,6 +237,21 @@ u32 __weak get_board_rev(void)
}
#endif
+static void init_csu(void)
+{
+#ifdef CONFIG_ARMV7_NONSEC
+ int i;
+ u32 csu = CSU_BASE_ADDR;
+ /*
+ * This is to allow device can be accessed in non-secure world.
+ * All imx6 chips CSU have 40 Config security level registers.
+ */
+ for (i = 0; i < 40; i ++) {
+ *((u32 *)csu + i) = 0xffffffff;
+ }
+#endif
+}
+
static void clear_ldo_ramp(void)
{
struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
@@ -407,7 +425,6 @@ static void noc_setup(void)
#endif
#ifdef CONFIG_MX6SX
-
void pcie_power_up(void)
{
set_ldo_voltage(LDO_PU, 1100); /* Set VDDPU to 1.1V */
@@ -482,6 +499,8 @@ int arch_cpu_init(void)
init_aips();
+ init_csu();
+
/* Need to clear MMDC_CHx_MASK to make warm reset work. */
clear_mmdc_ch_mask();
@@ -642,6 +661,19 @@ int board_postclk_init(void)
return 0;
}
+#ifdef CONFIG_SERIAL_TAG
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[0];
+ struct fuse_bank0_regs *fuse =
+ (struct fuse_bank0_regs *)bank->fuse_regs;
+
+ serialnr->low = fuse->uid_low;
+ serialnr->high = fuse->uid_high;
+}
+#endif
+
#ifndef CONFIG_SPL_BUILD
/*
* cfg_val will be used for
@@ -671,6 +703,49 @@ const struct boot_mode soc_boot_modes[] = {
};
#endif
+enum boot_device get_boot_device(void)
+{
+ enum boot_device boot_dev = UNKNOWN_BOOT;
+ uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
+ uint bt_mem_ctl = (soc_sbmr & 0x000000FF) >> 4 ;
+ uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3;
+ uint bt_dev_port = (soc_sbmr & 0x00001800) >> 11;
+
+ switch (bt_mem_ctl) {
+ case 0x0:
+ if (bt_mem_type)
+ boot_dev = ONE_NAND_BOOT;
+ else
+ boot_dev = WEIM_NOR_BOOT;
+ break;
+ case 0x2:
+ boot_dev = SATA_BOOT;
+ break;
+ case 0x3:
+ if (bt_mem_type)
+ boot_dev = I2C_BOOT;
+ else
+ boot_dev = SPI_NOR_BOOT;
+ break;
+ case 0x4:
+ case 0x5:
+ boot_dev = bt_dev_port + SD1_BOOT;
+ break;
+ case 0x6:
+ case 0x7:
+ boot_dev = bt_dev_port + MMC1_BOOT;
+ break;
+ case 0x8 ... 0xf:
+ boot_dev = NAND_BOOT;
+ break;
+ default:
+ boot_dev = UNKNOWN_BOOT;
+ break;
+ }
+
+ return boot_dev;
+}
+
void set_wdog_reset(struct wdog_regs *wdog)
{
u32 reg = readw(&wdog->wcr);