
Move common imx6 arch init setup, init.c can be extended and reused to support imx7 SoC keeping init arch common code.
Signed-off-by: Adrian Alonso aalonso@freescale.com --- Apply patch on top of: arm: imx: common rework cache settings for imx6
arch/arm/cpu/armv7/mx6/soc.c | 274 ----------------------------- arch/arm/imx-common/Makefile | 2 +- arch/arm/imx-common/init.c | 289 +++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 4 + 4 files changed, 294 insertions(+), 275 deletions(-) create mode 100644 arch/arm/imx-common/init.c
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 2f7d5c8..d2e5776 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -8,25 +8,17 @@ */
#include <common.h> -#include <asm/errno.h> #include <asm/io.h> #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> #include <asm/imx-common/boot_mode.h> -#include <asm/imx-common/dma.h> #include <stdbool.h> #include <asm/arch/mxc_hdmi.h> #include <asm/arch/crm_regs.h> #include <dm.h> #include <imx_thermal.h>
-enum ldo_reg { - LDO_ARM, - LDO_SOC, - LDO_PU, -}; - struct scu_regs { u32 ctrl; u32 config; @@ -183,260 +175,6 @@ u32 __weak get_board_rev(void) } #endif
-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_CONFIG_BASE_ADDR; -#endif - - /* - * Set all MPROTx to be non-bufferable, trusted for R/W, - * not forced to user-mode. - */ - writel(0x77777777, &aips1->mprot0); - writel(0x77777777, &aips1->mprot1); - writel(0x77777777, &aips2->mprot0); - writel(0x77777777, &aips2->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, &aips1->opacr0); - writel(0x00000000, &aips1->opacr1); - writel(0x00000000, &aips1->opacr2); - writel(0x00000000, &aips1->opacr3); - writel(0x00000000, &aips1->opacr4); - writel(0x00000000, &aips2->opacr0); - writel(0x00000000, &aips2->opacr1); - 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) -{ - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - int reg; - - /* ROM may modify LDO ramp up time according to fuse setting, so in - * order to be in the safe side we neeed to reset these settings to - * match the reset value: 0'b00 - */ - reg = readl(&anatop->ana_misc2); - reg &= ~(0x3f << 24); - writel(reg, &anatop->ana_misc2); -} - -/* - * Set the PMU_REG_CORE register - * - * 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). - */ -static int set_ldo_voltage(enum ldo_reg ldo, u32 mv) -{ - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - u32 val, step, old, reg = readl(&anatop->reg_core); - u8 shift; - - if (mv < 725) - val = 0x00; /* Power gated off */ - else if (mv > 1450) - val = 0x1F; /* Power FET switched full on. No regulation */ - else - val = (mv - 700) / 25; - - clear_ldo_ramp(); - - switch (ldo) { - case LDO_SOC: - shift = 18; - break; - case LDO_PU: - shift = 9; - break; - case LDO_ARM: - shift = 0; - break; - default: - return -EINVAL; - } - - old = (reg & (0x1F << shift)) >> shift; - step = abs(val - old); - if (step == 0) - return 0; - - reg = (reg & ~(0x1F << shift)) | (val << shift); - writel(reg, &anatop->reg_core); - - /* - * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per - * step - */ - udelay(3 * step); - - return 0; -} - -static void imx_set_wdog_powerdown(bool enable) -{ - struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR; - struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR; - struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR; - - if (is_cpu_type(MXC_CPU_MX6SX) || is_cpu_type(MXC_CPU_MX6UL)) - writew(enable, &wdog3->wmcr); - - /* Write to the PDE (Power Down Enable) bit */ - writew(enable, &wdog1->wmcr); - writew(enable, &wdog2->wmcr); -} - -static void set_ahb_rate(u32 val) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 reg, div; - - div = get_periph_clk() / val - 1; - reg = readl(&mxc_ccm->cbcdr); - - writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) | - (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr); -} - -static void clear_mmdc_ch_mask(void) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 reg; - reg = readl(&mxc_ccm->ccdr); - - /* Clear MMDC channel mask */ - reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK | MXC_CCM_CCDR_MMDC_CH0_HS_MASK); - writel(reg, &mxc_ccm->ccdr); -} - -static void init_bandgap(void) -{ - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - /* - * Ensure the bandgap has stabilized. - */ - while (!(readl(&anatop->ana_misc0) & 0x80)) - ; - /* - * For best noise performance of the analog blocks using the - * outputs of the bandgap, the reftop_selfbiasoff bit should - * be set. - */ - writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set); -} - - -#ifdef CONFIG_MX6SL -static void set_preclk_from_osc(void) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 reg; - - reg = readl(&mxc_ccm->cscmr1); - reg |= MXC_CCM_CSCMR1_PER_CLK_SEL_MASK; - writel(reg, &mxc_ccm->cscmr1); -} -#endif - -#define SRC_SCR_WARM_RESET_ENABLE 0 - -static void init_src(void) -{ - struct src *src_regs = (struct src *)SRC_BASE_ADDR; - u32 val; - - /* - * force warm reset sources to generate cold reset - * for a more reliable restart - */ - val = readl(&src_regs->scr); - val &= ~(1 << SRC_SCR_WARM_RESET_ENABLE); - writel(val, &src_regs->scr); -} - -int arch_cpu_init(void) -{ - init_aips(); - - /* Need to clear MMDC_CHx_MASK to make warm reset work. */ - clear_mmdc_ch_mask(); - - /* - * Disable self-bias circuit in the analog bandap. - * The self-bias circuit is used by the bandgap during startup. - * This bit should be set after the bandgap has initialized. - */ - init_bandgap(); - - /* - * When low freq boot is enabled, ROM will not set AHB - * freq, so we need to ensure AHB freq is 132MHz in such - * scenario. - */ - if (mxc_get_clock(MXC_ARM_CLK) == 396000000) - set_ahb_rate(132000000); - - /* Set perclk to source from OSC 24MHz */ -#if defined(CONFIG_MX6SL) - set_preclk_from_osc(); -#endif - - imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */ - -#ifdef CONFIG_APBH_DMA - /* Start APBH DMA */ - mxs_dma_init(); -#endif - - init_src(); - - return 0; -} - -int board_postclk_init(void) -{ - set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */ - - return 0; -} - #if defined(CONFIG_FEC_MXC) void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) { @@ -458,18 +196,6 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) } #endif
-void boot_mode_apply(unsigned cfg_val) -{ - unsigned reg; - struct src *psrc = (struct src *)SRC_BASE_ADDR; - writel(cfg_val, &psrc->gpr9); - reg = readl(&psrc->gpr10); - if (cfg_val) - reg |= 1 << 28; - else - reg &= ~(1 << 28); - writel(reg, &psrc->gpr10); -} /* * cfg_val will be used for * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile index 3b034e1..d77a236 100644 --- a/arch/arm/imx-common/Makefile +++ b/arch/arm/imx-common/Makefile @@ -19,7 +19,7 @@ obj-y += misc.o obj-$(CONFIG_SPL_BUILD) += spl.o endif ifeq ($(SOC),$(filter $(SOC),mx6)) -obj-y += cache.o +obj-y += cache.o init.o obj-$(CONFIG_CMD_SATA) += sata.o obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o endif diff --git a/arch/arm/imx-common/init.c b/arch/arm/imx-common/init.c new file mode 100644 index 0000000..aae8b5d --- /dev/null +++ b/arch/arm/imx-common/init.c @@ -0,0 +1,289 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/imx-common/boot_mode.h> +#include <asm/imx-common/dma.h> +#include <asm/arch/crm_regs.h> + +enum ldo_reg { + LDO_ARM, + LDO_SOC, + LDO_PU, +}; + +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, + * not forced to user-mode. + */ + writel(0x77777777, &aips1->mprot0); + writel(0x77777777, &aips1->mprot1); + writel(0x77777777, &aips2->mprot0); + writel(0x77777777, &aips2->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, &aips1->opacr0); + writel(0x00000000, &aips1->opacr1); + writel(0x00000000, &aips1->opacr2); + writel(0x00000000, &aips1->opacr3); + writel(0x00000000, &aips1->opacr4); + writel(0x00000000, &aips2->opacr0); + writel(0x00000000, &aips2->opacr1); + 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) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + int reg; + + /* ROM may modify LDO ramp up time according to fuse setting, so in + * order to be in the safe side we neeed to reset these settings to + * match the reset value: 0'b00 + */ + reg = readl(&anatop->ana_misc2); + reg &= ~(0x3f << 24); + writel(reg, &anatop->ana_misc2); +} + +/* + * Set the PMU_REG_CORE register + * + * 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). + */ +static int set_ldo_voltage(enum ldo_reg ldo, u32 mv) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + u32 val, step, old, reg = readl(&anatop->reg_core); + u8 shift; + + if (mv < 725) + val = 0x00; /* Power gated off */ + else if (mv > 1450) + val = 0x1F; /* Power FET switched full on. No regulation */ + else + val = (mv - 700) / 25; + + clear_ldo_ramp(); + + switch (ldo) { + case LDO_SOC: + shift = 18; + break; + case LDO_PU: + shift = 9; + break; + case LDO_ARM: + shift = 0; + break; + default: + return -EINVAL; + } + + old = (reg & (0x1F << shift)) >> shift; + step = abs(val - old); + if (step == 0) + return 0; + + reg = (reg & ~(0x1F << shift)) | (val << shift); + writel(reg, &anatop->reg_core); + + /* + * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per + * step + */ + udelay(3 * step); + + return 0; +} + +static void imx_set_wdog_powerdown(bool enable) +{ + struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR; + struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR; + struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR; + + if (is_cpu_type(MXC_CPU_MX6SX) || is_cpu_type(MXC_CPU_MX6UL)) + writew(enable, &wdog3->wmcr); + + /* Write to the PDE (Power Down Enable) bit */ + writew(enable, &wdog1->wmcr); + writew(enable, &wdog2->wmcr); +} + +static void set_ahb_rate(u32 val) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 reg, div; + + div = get_periph_clk() / val - 1; + reg = readl(&mxc_ccm->cbcdr); + + writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) | + (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr); +} + +static void clear_mmdc_ch_mask(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 reg; + reg = readl(&mxc_ccm->ccdr); + + /* Clear MMDC channel mask */ + reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK | MXC_CCM_CCDR_MMDC_CH0_HS_MASK); + writel(reg, &mxc_ccm->ccdr); +} + +static void init_bandgap(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + /* + * Ensure the bandgap has stabilized. + */ + while (!(readl(&anatop->ana_misc0) & 0x80)) + ; + /* + * For best noise performance of the analog blocks using the + * outputs of the bandgap, the reftop_selfbiasoff bit should + * be set. + */ + writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set); +} + + +#ifdef CONFIG_MX6SL +static void set_preclk_from_osc(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 reg; + + reg = readl(&mxc_ccm->cscmr1); + reg |= MXC_CCM_CSCMR1_PER_CLK_SEL_MASK; + writel(reg, &mxc_ccm->cscmr1); +} +#endif + +#define SRC_SCR_WARM_RESET_ENABLE 0 + +static void init_src(void) +{ + struct src *src_regs = (struct src *)SRC_BASE_ADDR; + u32 val; + + /* + * force warm reset sources to generate cold reset + * for a more reliable restart + */ + val = readl(&src_regs->scr); + val &= ~(1 << SRC_SCR_WARM_RESET_ENABLE); + writel(val, &src_regs->scr); +} + +int arch_cpu_init(void) +{ + init_aips(); + + /* Need to clear MMDC_CHx_MASK to make warm reset work. */ + clear_mmdc_ch_mask(); + + /* + * Disable self-bias circuit in the analog bandap. + * The self-bias circuit is used by the bandgap during startup. + * This bit should be set after the bandgap has initialized. + */ + init_bandgap(); + + /* + * When low freq boot is enabled, ROM will not set AHB + * freq, so we need to ensure AHB freq is 132MHz in such + * scenario. + */ + if (mxc_get_clock(MXC_ARM_CLK) == 396000000) + set_ahb_rate(132000000); + + /* Set perclk to source from OSC 24MHz */ +#if defined(CONFIG_MX6SL) + set_preclk_from_osc(); +#endif + + imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */ + +#ifdef CONFIG_APBH_DMA + /* Start APBH DMA */ + mxs_dma_init(); +#endif + + init_src(); + + return 0; +} + +#ifdef CONFIG_BOARD_POSTCLK_INIT +int board_postclk_init(void) +{ + set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */ + + return 0; +} +#endif + +void boot_mode_apply(unsigned cfg_val) +{ + unsigned reg; + struct src *psrc = (struct src *)SRC_BASE_ADDR; + writel(cfg_val, &psrc->gpr9); + reg = readl(&psrc->gpr10); + if (cfg_val) + reg |= 1 << 28; + else + reg &= ~(1 << 28); + writel(reg, &psrc->gpr10); +} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 4d84a9b..9a079e5 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -137,8 +137,10 @@ /* Defines for Blocks connected via AIPS (SkyBlue) */ #define ATZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR #define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR +#define ATZ3_BASE_ADDR AIPS3_ARB_BASE_ADDR #define AIPS1_BASE_ADDR AIPS1_ON_BASE_ADDR #define AIPS2_BASE_ADDR AIPS2_ON_BASE_ADDR +#define AIPS3_BASE_ADDR AIPS3_ON_BASE_ADDR
#define SPDIF_BASE_ADDR (ATZ1_BASE_ADDR + 0x04000) #define ECSPI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x08000) @@ -219,6 +221,8 @@
#define AIPS2_ON_BASE_ADDR (ATZ2_BASE_ADDR + 0x7C000) #define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000) +#define AIPS3_ON_BASE_ADDR (ATZ3_BASE_ADDR + 0x7C000) +#define AIPS3_OFF_BASE_ADDR (ATZ3_BASE_ADDR + 0x80000) #define CAAM_BASE_ADDR (ATZ2_BASE_ADDR) #define ARM_BASE_ADDR (ATZ2_BASE_ADDR + 0x40000)