From ca974b7a4878e8bd929be422a2667b4c585ba1f0 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Fri, 23 Mar 2018 02:37:28 -0700 Subject: 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 (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) --- arch/arm/mach-imx/mx6/clock.c | 98 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/mx6/soc.c | 77 +++++++++++++++++++++++++++++++++- 2 files changed, 174 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-imx/mx6') 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 @@ -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 <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 #include #include +#include #include #include +#include +#include #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); -- cgit v1.2.3