clk: imx: Update the pllv4 to support imx8ulp
authorJacky Bai <ping.bai@nxp.com>
Tue, 14 Sep 2021 06:52:01 +0000 (14:52 +0800)
committerAbel Vesa <abel.vesa@nxp.com>
Thu, 30 Sep 2021 13:22:55 +0000 (16:22 +0300)
The PLLs used on i.MX8ULP is mostly the same as on i.MX7ULP,
except the PLL register offset is changed. Change the PLLv4
driver for code reuse on i.MX7ULP and i.MX8ULP.

Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
Link: https://lore.kernel.org/r/20210914065208.3582128-3-ping.bai@nxp.com
Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
drivers/clk/imx/clk-imx7ulp.c
drivers/clk/imx/clk-pllv4.c
drivers/clk/imx/clk.h

index 779e09105da7d19950a2583ad265491da2085948..ba50d6db8097223304dc144bd16195297d512557 100644 (file)
@@ -78,8 +78,8 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
        hws[IMX7ULP_CLK_SPLL_PRE_DIV]   = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608,        8,      3,      CLK_SET_RATE_GATE);
 
        /*                                              name     parent_name     base */
-       hws[IMX7ULP_CLK_APLL]           = imx_clk_hw_pllv4("apll",  "apll_pre_div", base + 0x500);
-       hws[IMX7ULP_CLK_SPLL]           = imx_clk_hw_pllv4("spll",  "spll_pre_div", base + 0x600);
+       hws[IMX7ULP_CLK_APLL]           = imx_clk_hw_pllv4(IMX_PLLV4_IMX7ULP, "apll",  "apll_pre_div", base + 0x500);
+       hws[IMX7ULP_CLK_SPLL]           = imx_clk_hw_pllv4(IMX_PLLV4_IMX7ULP, "spll",  "spll_pre_div", base + 0x600);
 
        /* APLL PFDs */
        hws[IMX7ULP_CLK_APLL_PFD0]      = imx_clk_hw_pfdv2("apll_pfd0", "apll", base + 0x50c, 0);
index 8ec703f2741786868dd6dc437fb6d55b48cbf43d..3c750ccbee251393b56a77fa3086632d90ceeb8a 100644 (file)
 
 /* PLL Configuration Register (xPLLCFG) */
 #define PLL_CFG_OFFSET         0x08
+#define IMX8ULP_PLL_CFG_OFFSET 0x10
 #define BP_PLL_MULT            16
 #define BM_PLL_MULT            (0x7f << 16)
 
 /* PLL Numerator Register (xPLLNUM) */
 #define PLL_NUM_OFFSET         0x10
+#define IMX8ULP_PLL_NUM_OFFSET 0x1c
 
 /* PLL Denominator Register (xPLLDENOM) */
 #define PLL_DENOM_OFFSET       0x14
+#define IMX8ULP_PLL_DENOM_OFFSET       0x18
 
 #define MAX_MFD                        0x3fffffff
 #define DEFAULT_MFD            1000000
@@ -38,6 +41,9 @@
 struct clk_pllv4 {
        struct clk_hw   hw;
        void __iomem    *base;
+       u32             cfg_offset;
+       u32             num_offset;
+       u32             denom_offset;
 };
 
 /* Valid PLL MULT Table */
@@ -72,12 +78,12 @@ static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw,
        u32 mult, mfn, mfd;
        u64 temp64;
 
-       mult = readl_relaxed(pll->base + PLL_CFG_OFFSET);
+       mult = readl_relaxed(pll->base + pll->cfg_offset);
        mult &= BM_PLL_MULT;
        mult >>= BP_PLL_MULT;
 
-       mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
-       mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
+       mfn = readl_relaxed(pll->base + pll->num_offset);
+       mfd = readl_relaxed(pll->base + pll->denom_offset);
        temp64 = parent_rate;
        temp64 *= mfn;
        do_div(temp64, mfd);
@@ -165,13 +171,13 @@ static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate,
        do_div(temp64, parent_rate);
        mfn = temp64;
 
-       val = readl_relaxed(pll->base + PLL_CFG_OFFSET);
+       val = readl_relaxed(pll->base + pll->cfg_offset);
        val &= ~BM_PLL_MULT;
        val |= mult << BP_PLL_MULT;
-       writel_relaxed(val, pll->base + PLL_CFG_OFFSET);
+       writel_relaxed(val, pll->base + pll->cfg_offset);
 
-       writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
-       writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
+       writel_relaxed(mfn, pll->base + pll->num_offset);
+       writel_relaxed(mfd, pll->base + pll->denom_offset);
 
        return 0;
 }
@@ -207,8 +213,8 @@ static const struct clk_ops clk_pllv4_ops = {
        .is_prepared    = clk_pllv4_is_prepared,
 };
 
-struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
-                         void __iomem *base)
+struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name,
+                const char *parent_name, void __iomem *base)
 {
        struct clk_pllv4 *pll;
        struct clk_hw *hw;
@@ -221,6 +227,16 @@ struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
 
        pll->base = base;
 
+       if (type == IMX_PLLV4_IMX8ULP) {
+               pll->cfg_offset = IMX8ULP_PLL_CFG_OFFSET;
+               pll->num_offset = IMX8ULP_PLL_NUM_OFFSET;
+               pll->denom_offset = IMX8ULP_PLL_DENOM_OFFSET;
+       } else {
+               pll->cfg_offset = PLL_CFG_OFFSET;
+               pll->num_offset = PLL_NUM_OFFSET;
+               pll->denom_offset = PLL_DENOM_OFFSET;
+       }
+
        init.name = name;
        init.ops = &clk_pllv4_ops;
        init.parent_names = &parent_name;
index e36d01411a4e0e7bb161cd05fb972d9abd3dd693..5af70d3519930a27022b79be9f5b797d69dda57b 100644 (file)
@@ -42,6 +42,11 @@ enum imx_pll14xx_type {
        PLL_1443X,
 };
 
+enum imx_pllv4_type {
+       IMX_PLLV4_IMX7ULP,
+       IMX_PLLV4_IMX8ULP,
+};
+
 /* NOTE: Rate table should be kept sorted in descending order. */
 struct imx_pll14xx_rate_table {
        unsigned int rate;
@@ -241,8 +246,8 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
                .kdiv   =       (_k),                   \
        }
 
-struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
-                            void __iomem *base);
+struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name,
+               const char *parent_name, void __iomem *base);
 
 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,