MLK-17109-1 imx8m: clock: Add more frequencies support in dram pll init function
authorYe Li <ye.li@nxp.com>
Wed, 15 Nov 2017 06:44:30 +0000 (00:44 -0600)
committerYe Li <ye.li@nxp.com>
Fri, 8 Dec 2017 13:00:29 +0000 (07:00 -0600)
Add 400Mhz, 600Mhz and 800Mhz frequencies for dram pll init function to
support DDR3L/DDR4/LPDDR4.

Signed-off-by: Ye Li <ye.li@nxp.com>
arch/arm/cpu/armv8/imx8m/clock.c
arch/arm/include/asm/arch-imx8m/clock.h
board/freescale/imx8mq_evk/ddr/ddr.h
board/freescale/imx8mq_evk/ddr/ddr_init.c

index 29ef70d..cf4e597 100644 (file)
@@ -475,13 +475,15 @@ void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq)
        *reg = (0x4 << 24) | (0x7 << 16);
 }
 
-void dram_pll_init(void)
+void dram_pll_init(enum sscg_pll_out_val pll_val)
 {
        unsigned long pll_control_reg = DRAM_PLL_CFG0;
+       unsigned long pll_cfg_reg2 = DRAM_PLL_CFG2;
        u32 pwdn_mask = 0;
        u32 pll_clke = 0;
        u32 bypass1 = 0;
        u32 bypass2 = 0;
+       u32 val;
 
        #define SRC_DDR1_ENABLE_MASK (0x8F000000UL)
        #define SRC_DDR2_ENABLE_MASK (0x8F000000UL)
@@ -499,6 +501,34 @@ void dram_pll_init(void)
        writel(SRC_DDR1_ENABLE_MASK, SRC_BASE_ADDR + 0x1000);
        writel(SRC_DDR1_ENABLE_MASK, SRC_BASE_ADDR + 0x1004);
 
+       /* 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  */
index c6e9a66..0460ec1 100644 (file)
@@ -785,7 +785,7 @@ struct clk_root_map {
                                         SSCG_PLL_FEEDBACK_DIV_F2_MASK)
 #define SSCG_PLL_OUTPUT_DIV_VAL_MASK   (0x3f << 1)
 #define SSCG_PLL_OUTPUT_DIV_VAL_SHIFT  (1)
-#define SSCG_PLL_OUTPUT_DIV_VAL(n)     ((n) << 1) & \
+#define SSCG_PLL_OUTPUT_DIV_VAL(n)     (((n) << 1) & \
                                         SSCG_PLL_OUTPUT_DIV_VAL_MASK)
 #define SSCG_PLL_FILTER_RANGE_MASK     (0x1)
 
@@ -838,6 +838,13 @@ enum enet_freq {
        ENET_125MHz,
 };
 
+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);
index bf55355..9acb29c 100644 (file)
@@ -12,7 +12,6 @@ enum fw_type {
 void ddr_init(void);
 void ddr_load_train_code(enum fw_type type);
 void lpddr4_800M_cfg_phy(void);
-extern void dram_pll_init(void);
 
 static inline void reg32_write(unsigned long addr, u32 val)
 {
index ba46201..80971ec 100644 (file)
@@ -172,7 +172,7 @@ void ddr_init(void)
        reg32setbit(0x303A00F8,5);
        reg32_write(SRC_DDRC_RCR_ADDR + 0x04, 0x8F000000);
 
-       dram_pll_init();
+       dram_pll_init(SSCG_PLL_OUT_800M);
 
        reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000006);