diff --git a/arch/arm/include/asm/arch-mx8m/clock.h b/arch/arm/include/asm/arch-mx8m/clock.h index 45cfea301851f41fee00b454f2774c1dc629ff56..55049f8ee2e3bc991a27594a2363aeefb81edede 100644 --- a/arch/arm/include/asm/arch-mx8m/clock.h +++ b/arch/arm/include/asm/arch-mx8m/clock.h @@ -631,6 +631,13 @@ enum frac_pll_out_val { FRAC_PLL_OUT_1600M, }; +enum sscg_pll_out_val { + SSCG_PLL_OUT_400M, + SSCG_PLL_OUT_600M, + SSCG_PLL_OUT_800M, +}; + +void dram_pll_init(enum sscg_pll_out_val pll_val); u32 imx_get_fecclk(void); u32 imx_get_uartclk(void); int clock_init(void); diff --git a/arch/arm/mach-imx/mx8m/clock.c b/arch/arm/mach-imx/mx8m/clock.c index fe32e1c3f123eb9c200207eb9cc26a28aa454eae..68c4aa1b75db00eecad18bae9b581c8e004b4be6 100644 --- a/arch/arm/mach-imx/mx8m/clock.c +++ b/arch/arm/mach-imx/mx8m/clock.c @@ -526,10 +526,11 @@ u32 imx_get_fecclk(void) } #ifdef CONFIG_SPL_BUILD -void dram_pll_init(void) +void dram_pll_init(enum sscg_pll_out_val pll_val) { struct src *src = (struct src *)SRC_BASE_ADDR; void __iomem *pll_control_reg = &ana_pll->dram_pll_cfg0; + void __iomem *pll_cfg_reg2 = &ana_pll->dram_pll_cfg2; u32 pwdn_mask = 0, pll_clke = 0, bypass1 = 0, bypass2 = 0; u32 val; int ret; @@ -546,6 +547,34 @@ void dram_pll_init(void) writel(SRC_DDR1_ENABLE_MASK, &src->ddr1_rcr); writel(SRC_DDR1_ENABLE_MASK, &src->ddr2_rcr); + /* Bypass */ + setbits_le32(pll_control_reg, bypass1); + setbits_le32(pll_control_reg, bypass2); + + switch (pll_val) { + case SSCG_PLL_OUT_400M: + val = readl(pll_cfg_reg2); + val &= ~(SSCG_PLL_OUTPUT_DIV_VAL_MASK | SSCG_PLL_FEEDBACK_DIV_F2_MASK); + val |= SSCG_PLL_OUTPUT_DIV_VAL(1); + val |= SSCG_PLL_FEEDBACK_DIV_F2_VAL(11); + writel(val, pll_cfg_reg2); + break; + case SSCG_PLL_OUT_600M: + val = readl(pll_cfg_reg2); + val &= ~(SSCG_PLL_OUTPUT_DIV_VAL_MASK | SSCG_PLL_FEEDBACK_DIV_F2_MASK); + val |= SSCG_PLL_OUTPUT_DIV_VAL(1); + val |= SSCG_PLL_FEEDBACK_DIV_F2_VAL(17); + writel(val, pll_cfg_reg2); + break; + case SSCG_PLL_OUT_800M: + val = readl(pll_cfg_reg2); + val &= ~(SSCG_PLL_OUTPUT_DIV_VAL_MASK | SSCG_PLL_FEEDBACK_DIV_F2_MASK); + val |= SSCG_PLL_OUTPUT_DIV_VAL(0); + val |= SSCG_PLL_FEEDBACK_DIV_F2_VAL(11); + writel(val, pll_cfg_reg2); + break; + } + /* Clear power down bit */ clrbits_le32(pll_control_reg, pwdn_mask); /* Eanble ARM_PLL/SYS_PLL */