MLK-21700-1 clk: imx8mm: Rename int_pll to pll14xx for upstream alignment
authorLeonard Crestez <leonard.crestez@nxp.com>
Fri, 3 May 2019 15:47:01 +0000 (18:47 +0300)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 15 May 2019 12:02:16 +0000 (15:02 +0300)
Only cosmetic changes in this patch

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
drivers/clk/imx/Makefile
drivers/clk/imx/clk-imx8mm.c
drivers/clk/imx/clk-intpll.c [deleted file]
drivers/clk/imx/clk-pll14xx.c [new file with mode: 0644]
drivers/clk/imx/clk.h

index 6be120d..69120e4 100644 (file)
@@ -35,4 +35,4 @@ obj-$(CONFIG_SOC_VF610)  += clk-vf610.o
 obj-$(CONFIG_ARCH_FSL_IMX8QM)  += clk.o clk-imx8qm.o clk-imx8.o clk-divider-scu.o clk-gate-scu.o clk-mux-scu.o
 obj-$(CONFIG_ARCH_FSL_IMX8QXP) += clk.o clk-imx8qxp.o clk-imx8.o clk-divider-scu.o clk-gate-scu.o clk-mux-scu.o
 obj-$(CONFIG_ARCH_FSL_IMX8MQ)  += clk.o clk-imx8mq.o clk-frac-pll.o clk-sccg-pll.o clk-gate2.o clk-composite-8m.o
-obj-$(CONFIG_ARCH_FSL_IMX8MM)  += clk.o clk-imx8mm.o clk-intpll.o clk-gate2.o clk-cpu.o
+obj-$(CONFIG_ARCH_FSL_IMX8MM)  += clk.o clk-imx8mm.o clk-pll14xx.o clk-gate2.o clk-cpu.o
index 1af5814..a1aca3f 100644 (file)
@@ -65,7 +65,7 @@ enum {
                .kdiv   =       (_k),                   \
        }
 
-static const struct imx_int_pll_rate_table imx8mm_intpll_tbl[] = {
+static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
        PLL_1416X_RATE(1800000000U, 225, 3, 0),
        PLL_1416X_RATE(1600000000U, 200, 3, 0),
        PLL_1416X_RATE(1200000000U, 300, 3, 1),
@@ -76,53 +76,53 @@ static const struct imx_int_pll_rate_table imx8mm_intpll_tbl[] = {
        PLL_1416X_RATE(600000000U,  300, 3, 2),
 };
 
-static const struct imx_int_pll_rate_table imx8mm_audiopll_tbl[] = {
+static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = {
        PLL_1443X_RATE(786432000U, 262, 2, 2, 9437),
        PLL_1443X_RATE(722534400U, 361, 3, 2, 17511),
 };
 
-static const struct imx_int_pll_rate_table imx8mm_videopll_tbl[] = {
+static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = {
        PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
        PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
 };
 
-static const struct imx_int_pll_rate_table imx8mm_drampll_tbl[] = {
+static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = {
        PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
 };
 
-static struct imx_int_pll_clk imx8mm_audio_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_audio_pll __initdata = {
                .type = PLL_1443X,
                .rate_table = imx8mm_audiopll_tbl,
 };
 
-static struct imx_int_pll_clk imx8mm_video_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_video_pll __initdata = {
                .type = PLL_1443X,
                .rate_table = imx8mm_videopll_tbl,
 };
 
-static struct imx_int_pll_clk imx8mm_dram_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = {
                .type = PLL_1443X,
                .rate_table = imx8mm_drampll_tbl,
 };
 
-static struct imx_int_pll_clk imx8mm_arm_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = {
                .type = PLL_1416X,
-               .rate_table = imx8mm_intpll_tbl,
+               .rate_table = imx8mm_pll1416x_tbl,
 };
 
-static struct imx_int_pll_clk imx8mm_gpu_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_gpu_pll __initdata = {
                .type = PLL_1416X,
-               .rate_table = imx8mm_intpll_tbl,
+               .rate_table = imx8mm_pll1416x_tbl,
 };
 
-static struct imx_int_pll_clk imx8mm_vpu_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_vpu_pll __initdata = {
                .type = PLL_1416X,
-               .rate_table = imx8mm_intpll_tbl,
+               .rate_table = imx8mm_pll1416x_tbl,
 };
 
-static struct imx_int_pll_clk imx8mm_sys_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = {
                .type = PLL_1416X,
-               .rate_table = imx8mm_intpll_tbl,
+               .rate_table = imx8mm_pll1416x_tbl,
 };
 
 static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
@@ -461,16 +461,16 @@ static void __init imx8mm_clocks_init(struct device_node *ccm_node)
        clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
        clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 
-       clks[IMX8MM_AUDIO_PLL1] = imx_clk_int_pll("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
-       clks[IMX8MM_AUDIO_PLL2] = imx_clk_int_pll("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
-       clks[IMX8MM_VIDEO_PLL1] = imx_clk_int_pll("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
-       clks[IMX8MM_DRAM_PLL] = imx_clk_int_pll("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
-       clks[IMX8MM_GPU_PLL] = imx_clk_int_pll("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
-       clks[IMX8MM_VPU_PLL] = imx_clk_int_pll("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
-       clks[IMX8MM_ARM_PLL] = imx_clk_int_pll("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
-       clks[IMX8MM_SYS_PLL1] = imx_clk_int_pll("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
-       clks[IMX8MM_SYS_PLL2] = imx_clk_int_pll("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
-       clks[IMX8MM_SYS_PLL3] = imx_clk_int_pll("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
+       clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
+       clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
+       clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
+       clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
+       clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
+       clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
+       clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
+       clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
+       clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
+       clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
 
        /* PLL bypass out */
        clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
diff --git a/drivers/clk/imx/clk-intpll.c b/drivers/clk/imx/clk-intpll.c
deleted file mode 100644 (file)
index 4c8e068..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright 2017-2018 NXP.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/bitops.h>
-#include <linux/clk-provider.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-
-#include "clk.h"
-
-#define GNRL_CTL       0x0
-#define DIV_CTL                0x4
-#define LOCK_STATUS    BIT(31)
-#define LOCK_SEL_MASK  BIT(29)
-#define CLKE_MASK      BIT(11)
-#define RST_MASK       BIT(9)
-#define BYPASS_MASK    BIT(4)
-#define        MDIV_SHIFT      12
-#define        MDIV_MASK       GENMASK(21, 12)
-#define PDIV_SHIFT     4
-#define PDIV_MASK      GENMASK(9, 4)
-#define SDIV_SHIFT     0
-#define SDIV_MASK      GENMASK(2, 0)
-#define KDIV_SHIFT     0
-#define KDIV_MASK      GENMASK(15, 0)
-
-struct clk_int_pll {
-       struct clk_hw                   hw;
-       void __iomem                    *base;
-       enum imx_int_pll_type           type;
-       struct imx_int_pll_rate_table   *rate_table;
-       int rate_count;
-};
-
-#define to_clk_int_pll(_hw) container_of(_hw, struct clk_int_pll, hw)
-
-static const struct imx_int_pll_rate_table *imx_get_pll_settings(
-               struct clk_int_pll *pll, unsigned long rate)
-{
-       const struct imx_int_pll_rate_table *rate_table = pll->rate_table;
-       int i;
-
-       for (i = 0; i < pll->rate_count; i++) {
-               if (rate == rate_table[i].rate)
-                       return &rate_table[i];
-       }
-
-       return NULL;
-}
-
-static long clk_int_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-                       unsigned long *prate)
-{
-       struct clk_int_pll *pll = to_clk_int_pll(hw);
-       const struct imx_int_pll_rate_table *rate_table = pll->rate_table;
-       int i;
-
-       /* Assumming rate_table is in descending order */
-       for (i = 0; i < pll->rate_count; i++) {
-               if (rate >= rate_table[i].rate)
-                       return rate_table[i].rate;
-       }
-       /* return minimum supported value */
-       return rate_table[i - 1].rate;
-}
-
-static unsigned long clk_int_pll1416x_recalc_rate(struct clk_hw *hw,
-                                                 unsigned long parent_rate)
-{
-       struct clk_int_pll *pll = to_clk_int_pll(hw);
-       u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
-       u64 fvco = parent_rate;
-
-       pll_gnrl = readl_relaxed(pll->base);
-       pll_div = readl_relaxed(pll->base + 4);
-       mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
-       pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
-       sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
-
-       fvco *= mdiv;
-       do_div(fvco, pdiv << sdiv);
-
-       return (unsigned long)fvco;
-}
-
-static unsigned long clk_int_pll1443x_recalc_rate(struct clk_hw *hw,
-                                                 unsigned long parent_rate)
-{
-       struct clk_int_pll *pll = to_clk_int_pll(hw);
-       const struct imx_int_pll_rate_table *rate_table = pll->rate_table;
-       u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
-       short int kdiv;
-       u64 fvco = parent_rate;
-       long rate = 0;
-       int i;
-
-       pll_gnrl = readl_relaxed(pll->base);
-       pll_div_ctl0 = readl_relaxed(pll->base + 4);
-       pll_div_ctl1 = readl_relaxed(pll->base + 8);
-       mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
-       pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
-       sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
-       kdiv = pll_div_ctl1 & KDIV_MASK;
-
-       /*
-        * Sometimes, the recalculated rate has deviation due to
-        * the frac part. So find the accurate pll rate from the table
-        * first, if no match rate in the table, use the rate calculated
-        * from the equation below.
-        */
-       for (i = 0; i < pll->rate_count; i++) {
-               if (rate_table[i].pdiv == pdiv && rate_table[i].mdiv == mdiv &&
-                   rate_table[i].sdiv == sdiv && rate_table[i].kdiv == kdiv)
-                       rate = rate_table[i].rate;
-       }
-
-       /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
-       fvco *= (mdiv * 65536 + kdiv);
-       pdiv *= 65536;
-
-       do_div(fvco, pdiv << sdiv);
-
-       return rate ? (unsigned long) rate : (unsigned long)fvco;
-}
-
-static inline bool clk_int_pll1416x_mp_change(const struct imx_int_pll_rate_table *rate,
-                                         u32 pll_div)
-{
-       u32 old_mdiv, old_pdiv;
-
-       old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
-       old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
-
-       return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
-}
-
-static inline bool clk_int_pll1443x_mpk_change(const struct imx_int_pll_rate_table *rate,
-                                         u32 pll_div_ctl0, u32 pll_div_ctl1)
-{
-       u32 old_mdiv, old_pdiv, old_kdiv;
-
-       old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
-       old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
-       old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
-
-       return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
-               rate->kdiv != old_kdiv);
-}
-
-static inline bool clk_int_pll1443x_mp_change(const struct imx_int_pll_rate_table *rate,
-                                         u32 pll_div_ctl0, u32 pll_div_ctl1)
-{
-       u32 old_mdiv, old_pdiv, old_kdiv;
-
-       old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
-       old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
-       old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
-
-       return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
-               rate->kdiv != old_kdiv);
-}
-
-static int clk_int_pll_wait_lock(struct clk_int_pll *pll)
-{
-       unsigned long timeout = jiffies + msecs_to_jiffies(10);
-
-       /* Wait for PLL to lock */
-       do {
-               if (readl_relaxed(pll->base) & LOCK_STATUS)
-                       break;
-               if (time_after(jiffies, timeout))
-                       break;
-       } while (1);
-
-       return readl_relaxed(pll->base) & LOCK_STATUS ? 0 : -ETIMEDOUT;
-}
-
-static int clk_int_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
-                                unsigned long prate)
-{
-       struct clk_int_pll *pll = to_clk_int_pll(hw);
-       const struct imx_int_pll_rate_table *rate;
-       u32 tmp, div_val;
-       int ret;
-
-       rate = imx_get_pll_settings(pll, drate);
-       if (!rate) {
-               pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-                      drate, clk_hw_get_name(hw));
-               return -EINVAL;
-       }
-
-       tmp = readl_relaxed(pll->base + 4);
-
-       if (!clk_int_pll1416x_mp_change(rate, tmp)) {
-               tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
-               tmp |= rate->sdiv << SDIV_SHIFT;
-               writel_relaxed(tmp, pll->base + 4);
-
-               return 0;
-       }
-
-       /* Bypass clock and set lock to pll output lock */
-       tmp = readl_relaxed(pll->base);
-       tmp |= LOCK_SEL_MASK;
-       writel_relaxed(tmp, pll->base);
-
-       /* Enable RST */
-       tmp &= ~RST_MASK;
-       writel_relaxed(tmp, pll->base);
-
-       div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
-               (rate->sdiv << SDIV_SHIFT);
-       writel_relaxed(div_val, pll->base + 0x4);
-
-       /*
-        * According to SPEC, t3 - t2 need to be greater than
-        * 1us and 1/FREF, respectively.
-        * FREF is FIN / Prediv, the prediv is [1, 63], so choose
-        * 3us.
-        */
-       udelay(3);
-
-       /* Disable RST */
-       tmp |= RST_MASK;
-       writel_relaxed(tmp, pll->base);
-
-       /* Wait Lock */
-       ret = clk_int_pll_wait_lock(pll);
-       if (ret)
-               return ret;
-
-       /* Bypass */
-       tmp &= ~BYPASS_MASK;
-       writel_relaxed(tmp, pll->base);
-
-       return 0;
-}
-
-static int clk_int_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
-                                unsigned long prate)
-{
-       struct clk_int_pll *pll = to_clk_int_pll(hw);
-       const struct imx_int_pll_rate_table *rate;
-       u32 tmp, div_val;
-       int ret;
-
-       rate = imx_get_pll_settings(pll, drate);
-       if (!rate) {
-               pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-                       drate, clk_hw_get_name(hw));
-               return -EINVAL;
-       }
-
-       tmp = readl_relaxed(pll->base + 4);
-       div_val = readl_relaxed(pll->base + 8);
-
-       if (!clk_int_pll1443x_mpk_change(rate, tmp, div_val)) {
-               tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
-               tmp |= rate->sdiv << SDIV_SHIFT;
-               writel_relaxed(tmp, pll->base + 4);
-
-               return 0;
-       }
-
-       /* Enable RST */
-       tmp = readl_relaxed(pll->base);
-       tmp &= ~RST_MASK;
-       writel_relaxed(tmp, pll->base);
-
-       div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
-               (rate->sdiv << SDIV_SHIFT);
-       writel_relaxed(div_val, pll->base + 0x4);
-       writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
-
-       /*
-        * According to SPEC, t3 - t2 need to be greater than
-        * 1us and 1/FREF, respectively.
-        * FREF is FIN / Prediv, the prediv is [1, 63], so choose
-        * 3us.
-        */
-       udelay(3);
-
-       /* Disable RST */
-       tmp |= RST_MASK;
-       writel_relaxed(tmp, pll->base);
-
-       /* Wait Lock*/
-       ret = clk_int_pll_wait_lock(pll);
-       if (ret)
-               return ret;
-
-       /* Bypass */
-       tmp &= ~BYPASS_MASK;
-       writel_relaxed(tmp, pll->base);
-
-       return 0;
-}
-
-static int clk_int_pll_prepare(struct clk_hw *hw)
-{
-       struct clk_int_pll *pll = to_clk_int_pll(hw);
-       u32 val;
-
-       /*
-        * RESETB = 1 from 0, PLL starts its normal
-        * operation after lock time
-        */
-       val = readl_relaxed(pll->base + GNRL_CTL);
-       val |= RST_MASK;
-       writel_relaxed(val, pll->base + GNRL_CTL);
-
-       return clk_int_pll_wait_lock(pll);
-}
-
-static int clk_int_pll_is_prepared(struct clk_hw *hw)
-{
-       struct clk_int_pll *pll = to_clk_int_pll(hw);
-       u32 val;
-
-       val = readl_relaxed(pll->base + GNRL_CTL);
-
-       return (val & RST_MASK) ? 1 : 0;
-}
-
-static void clk_int_pll_unprepare(struct clk_hw *hw)
-{
-       struct clk_int_pll *pll = to_clk_int_pll(hw);
-       u32 val;
-
-       /*
-        * Set RST to 0, power down mode is enabled and
-        * every digital block is reset
-        */
-       val = readl_relaxed(pll->base + GNRL_CTL);
-       val &= ~RST_MASK;
-       writel_relaxed(val, pll->base + GNRL_CTL);
-}
-
-static const struct clk_ops clk_pll1416x_ops = {
-       .prepare        = clk_int_pll_prepare,
-       .unprepare      = clk_int_pll_unprepare,
-       .is_prepared    = clk_int_pll_is_prepared,
-       .recalc_rate    = clk_int_pll1416x_recalc_rate,
-       .round_rate     = clk_int_pll_round_rate,
-       .set_rate       = clk_int_pll1416x_set_rate,
-};
-
-static const struct clk_ops clk_pll1416x_min_ops = {
-       .recalc_rate    = clk_int_pll1416x_recalc_rate,
-};
-
-static const struct clk_ops clk_pll1443x_ops = {
-       .prepare        = clk_int_pll_prepare,
-       .unprepare      = clk_int_pll_unprepare,
-       .is_prepared    = clk_int_pll_is_prepared,
-       .recalc_rate    = clk_int_pll1443x_recalc_rate,
-       .round_rate     = clk_int_pll_round_rate,
-       .set_rate       = clk_int_pll1443x_set_rate,
-};
-
-struct clk *imx_clk_int_pll(const char *name, const char *parent_name,
-                           void __iomem *base,
-                           const struct imx_int_pll_clk *pll_clk)
-{
-       struct clk_int_pll *pll;
-       struct clk *clk;
-       struct clk_init_data init;
-       int len;
-
-       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-       if (!pll)
-               return ERR_PTR(-ENOMEM);
-
-       init.name = name;
-       init.flags = pll_clk->flags;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-
-       if (pll_clk->rate_table) {
-               for (len = 0; pll_clk->rate_table[len].rate != 0; )
-                       len++;
-
-               pll->rate_count = len;
-               pll->rate_table = kmemdup(pll_clk->rate_table,
-                                         pll->rate_count *
-                                         sizeof(struct imx_int_pll_rate_table),
-                                         GFP_KERNEL);
-               WARN(!pll->rate_table, "%s : could not alloc rate table\n", __func__);
-       }
-
-       switch (pll_clk->type) {
-       case PLL_1416X:
-               if (!pll->rate_table)
-                       init.ops = &clk_pll1416x_min_ops;
-               else
-                       init.ops = &clk_pll1416x_ops;
-               break;
-       case PLL_1443X:
-               init.ops = &clk_pll1443x_ops;
-               break;
-       default:
-               pr_err("%s: Unknown pll type for pll clk %s\n",
-                      __func__, name);
-       };
-
-       pll->base = base;
-       pll->hw.init = &init;
-       pll->type = pll_clk->type;
-
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk)) {
-               pr_err("%s: failed to register pll %s %lu\n",
-                       __func__, name, PTR_ERR(clk));
-               kfree(pll);
-       }
-
-       return clk;
-}
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
new file mode 100644 (file)
index 0000000..f6d6658
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2017-2018 NXP.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+
+#include "clk.h"
+
+#define GNRL_CTL       0x0
+#define DIV_CTL                0x4
+#define LOCK_STATUS    BIT(31)
+#define LOCK_SEL_MASK  BIT(29)
+#define CLKE_MASK      BIT(11)
+#define RST_MASK       BIT(9)
+#define BYPASS_MASK    BIT(4)
+#define MDIV_SHIFT     12
+#define MDIV_MASK      GENMASK(21, 12)
+#define PDIV_SHIFT     4
+#define PDIV_MASK      GENMASK(9, 4)
+#define SDIV_SHIFT     0
+#define SDIV_MASK      GENMASK(2, 0)
+#define KDIV_SHIFT     0
+#define KDIV_MASK      GENMASK(15, 0)
+
+struct clk_pll14xx {
+       struct clk_hw                   hw;
+       void __iomem                    *base;
+       enum imx_pll14xx_type           type;
+       const struct imx_pll14xx_rate_table *rate_table;
+       int rate_count;
+};
+
+#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
+
+static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
+               struct clk_pll14xx *pll, unsigned long rate)
+{
+       const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
+       int i;
+
+       for (i = 0; i < pll->rate_count; i++)
+               if (rate == rate_table[i].rate)
+                       return &rate_table[i];
+
+       return NULL;
+}
+
+static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
+                       unsigned long *prate)
+{
+       struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+       const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
+       int i;
+
+       /* Assumming rate_table is in descending order */
+       for (i = 0; i < pll->rate_count; i++)
+               if (rate >= rate_table[i].rate)
+                       return rate_table[i].rate;
+
+       /* return minimum supported value */
+       return rate_table[i - 1].rate;
+}
+
+static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+       u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
+       u64 fvco = parent_rate;
+
+       pll_gnrl = readl_relaxed(pll->base);
+       pll_div = readl_relaxed(pll->base + 4);
+       mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
+       pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
+       sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
+
+       fvco *= mdiv;
+       do_div(fvco, pdiv << sdiv);
+
+       return fvco;
+}
+
+static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+       const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
+       u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
+       short int kdiv;
+       u64 fvco = parent_rate;
+       long rate = 0;
+       int i;
+
+       pll_gnrl = readl_relaxed(pll->base);
+       pll_div_ctl0 = readl_relaxed(pll->base + 4);
+       pll_div_ctl1 = readl_relaxed(pll->base + 8);
+       mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
+       pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
+       sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
+       kdiv = pll_div_ctl1 & KDIV_MASK;
+
+       /*
+        * Sometimes, the recalculated rate has deviation due to
+        * the frac part. So find the accurate pll rate from the table
+        * first, if no match rate in the table, use the rate calculated
+        * from the equation below.
+        */
+       for (i = 0; i < pll->rate_count; i++) {
+               if (rate_table[i].pdiv == pdiv && rate_table[i].mdiv == mdiv &&
+                   rate_table[i].sdiv == sdiv && rate_table[i].kdiv == kdiv)
+                       rate = rate_table[i].rate;
+       }
+
+       /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
+       fvco *= (mdiv * 65536 + kdiv);
+       pdiv *= 65536;
+
+       do_div(fvco, pdiv << sdiv);
+
+       return rate ? (unsigned long) rate : (unsigned long)fvco;
+}
+
+static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate,
+                                         u32 pll_div)
+{
+       u32 old_mdiv, old_pdiv;
+
+       old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
+       old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
+
+       return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv;
+}
+
+static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate,
+                                         u32 pll_div_ctl0, u32 pll_div_ctl1)
+{
+       u32 old_mdiv, old_pdiv, old_kdiv;
+
+       old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
+       old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
+       old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
+
+       return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+               rate->kdiv != old_kdiv;
+}
+
+static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate,
+                                         u32 pll_div_ctl0, u32 pll_div_ctl1)
+{
+       u32 old_mdiv, old_pdiv, old_kdiv;
+
+       old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
+       old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
+       old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
+
+       return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+               rate->kdiv != old_kdiv;
+}
+
+static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(10);
+
+       /* Wait for PLL to lock */
+       do {
+               if (readl_relaxed(pll->base) & LOCK_STATUS)
+                       break;
+               if (time_after(jiffies, timeout))
+                       break;
+       } while (1);
+
+       return readl_relaxed(pll->base) & LOCK_STATUS ? 0 : -ETIMEDOUT;
+}
+
+static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
+                                unsigned long prate)
+{
+       struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+       const struct imx_pll14xx_rate_table *rate;
+       u32 tmp, div_val;
+       int ret;
+
+       rate = imx_get_pll_settings(pll, drate);
+       if (!rate) {
+               pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+                      drate, clk_hw_get_name(hw));
+               return -EINVAL;
+       }
+
+       tmp = readl_relaxed(pll->base + 4);
+
+       if (!clk_pll1416x_mp_change(rate, tmp)) {
+               tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
+               tmp |= rate->sdiv << SDIV_SHIFT;
+               writel_relaxed(tmp, pll->base + 4);
+
+               return 0;
+       }
+
+       /* Bypass clock and set lock to pll output lock */
+       tmp = readl_relaxed(pll->base);
+       tmp |= LOCK_SEL_MASK;
+       writel_relaxed(tmp, pll->base);
+
+       /* Enable RST */
+       tmp &= ~RST_MASK;
+       writel_relaxed(tmp, pll->base);
+
+       div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
+               (rate->sdiv << SDIV_SHIFT);
+       writel_relaxed(div_val, pll->base + 0x4);
+
+       /*
+        * According to SPEC, t3 - t2 need to be greater than
+        * 1us and 1/FREF, respectively.
+        * FREF is FIN / Prediv, the prediv is [1, 63], so choose
+        * 3us.
+        */
+       udelay(3);
+
+       /* Disable RST */
+       tmp |= RST_MASK;
+       writel_relaxed(tmp, pll->base);
+
+       /* Wait Lock */
+       ret = clk_pll14xx_wait_lock(pll);
+       if (ret)
+               return ret;
+
+       /* Bypass */
+       tmp &= ~BYPASS_MASK;
+       writel_relaxed(tmp, pll->base);
+
+       return 0;
+}
+
+static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
+                                unsigned long prate)
+{
+       struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+       const struct imx_pll14xx_rate_table *rate;
+       u32 tmp, div_val;
+       int ret;
+
+       rate = imx_get_pll_settings(pll, drate);
+       if (!rate) {
+               pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+                       drate, clk_hw_get_name(hw));
+               return -EINVAL;
+       }
+
+       tmp = readl_relaxed(pll->base + 4);
+       div_val = readl_relaxed(pll->base + 8);
+
+       if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) {
+               tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
+               tmp |= rate->sdiv << SDIV_SHIFT;
+               writel_relaxed(tmp, pll->base + 4);
+
+               return 0;
+       }
+
+       /* Enable RST */
+       tmp = readl_relaxed(pll->base);
+       tmp &= ~RST_MASK;
+       writel_relaxed(tmp, pll->base);
+
+       div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
+               (rate->sdiv << SDIV_SHIFT);
+       writel_relaxed(div_val, pll->base + 0x4);
+       writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
+
+       /*
+        * According to SPEC, t3 - t2 need to be greater than
+        * 1us and 1/FREF, respectively.
+        * FREF is FIN / Prediv, the prediv is [1, 63], so choose
+        * 3us.
+        */
+       udelay(3);
+
+       /* Disable RST */
+       tmp |= RST_MASK;
+       writel_relaxed(tmp, pll->base);
+
+       /* Wait Lock*/
+       ret = clk_pll14xx_wait_lock(pll);
+       if (ret)
+               return ret;
+
+       /* Bypass */
+       tmp &= ~BYPASS_MASK;
+       writel_relaxed(tmp, pll->base);
+
+       return 0;
+}
+
+static int clk_pll14xx_prepare(struct clk_hw *hw)
+{
+       struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+       u32 val;
+
+       /*
+        * RESETB = 1 from 0, PLL starts its normal
+        * operation after lock time
+        */
+       val = readl_relaxed(pll->base + GNRL_CTL);
+       val |= RST_MASK;
+       writel_relaxed(val, pll->base + GNRL_CTL);
+
+       return clk_pll14xx_wait_lock(pll);
+}
+
+static int clk_pll14xx_is_prepared(struct clk_hw *hw)
+{
+       struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+       u32 val;
+
+       val = readl_relaxed(pll->base + GNRL_CTL);
+
+       return (val & RST_MASK) ? 1 : 0;
+}
+
+static void clk_pll14xx_unprepare(struct clk_hw *hw)
+{
+       struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+       u32 val;
+
+       /*
+        * Set RST to 0, power down mode is enabled and
+        * every digital block is reset
+        */
+       val = readl_relaxed(pll->base + GNRL_CTL);
+       val &= ~RST_MASK;
+       writel_relaxed(val, pll->base + GNRL_CTL);
+}
+
+static const struct clk_ops clk_pll1416x_ops = {
+       .prepare        = clk_pll14xx_prepare,
+       .unprepare      = clk_pll14xx_unprepare,
+       .is_prepared    = clk_pll14xx_is_prepared,
+       .recalc_rate    = clk_pll1416x_recalc_rate,
+       .round_rate     = clk_pll14xx_round_rate,
+       .set_rate       = clk_pll1416x_set_rate,
+};
+
+static const struct clk_ops clk_pll1416x_min_ops = {
+       .recalc_rate    = clk_pll1416x_recalc_rate,
+};
+
+static const struct clk_ops clk_pll1443x_ops = {
+       .prepare        = clk_pll14xx_prepare,
+       .unprepare      = clk_pll14xx_unprepare,
+       .is_prepared    = clk_pll14xx_is_prepared,
+       .recalc_rate    = clk_pll1443x_recalc_rate,
+       .round_rate     = clk_pll14xx_round_rate,
+       .set_rate       = clk_pll1443x_set_rate,
+};
+
+struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
+                           void __iomem *base,
+                           const struct imx_pll14xx_clk *pll_clk)
+{
+       struct clk_pll14xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+       int len;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.flags = pll_clk->flags;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       if (pll_clk->rate_table) {
+               for (len = 0; pll_clk->rate_table[len].rate != 0; )
+                       len++;
+
+               pll->rate_count = len;
+               pll->rate_table = kmemdup(pll_clk->rate_table,
+                                         pll->rate_count *
+                                         sizeof(struct imx_pll14xx_rate_table),
+                                         GFP_KERNEL);
+               WARN(!pll->rate_table, "%s : could not alloc rate table\n", __func__);
+       }
+
+       switch (pll_clk->type) {
+       case PLL_1416X:
+               if (!pll->rate_table)
+                       init.ops = &clk_pll1416x_min_ops;
+               else
+                       init.ops = &clk_pll1416x_ops;
+               break;
+       case PLL_1443X:
+               init.ops = &clk_pll1443x_ops;
+               break;
+       default:
+               pr_err("%s: Unknown pll type for pll clk %s\n",
+                      __func__, name);
+       };
+
+       pll->base = base;
+       pll->hw.init = &init;
+       pll->type = pll_clk->type;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register pll %s %lu\n",
+                       __func__, name, PTR_ERR(clk));
+               kfree(pll);
+       }
+
+       return clk;
+}
index d1ab055..f502260 100644 (file)
@@ -27,13 +27,13 @@ enum imx_pllv1_type {
        IMX_PLLV1_IMX35,
 };
 
-enum imx_int_pll_type {
+enum imx_pll14xx_type {
        PLL_1416X,
        PLL_1443X,
 };
 
 /* NOTE: Rate table should be kept sorted in descending order. */
-struct imx_int_pll_rate_table {
+struct imx_pll14xx_rate_table {
        unsigned int rate;
        unsigned int pdiv;
        unsigned int mdiv;
@@ -41,13 +41,14 @@ struct imx_int_pll_rate_table {
        unsigned int kdiv;
 };
 
-struct imx_int_pll_clk {
-       enum imx_int_pll_type type;
-       const struct imx_int_pll_rate_table *rate_table;
+struct imx_pll14xx_clk {
+       enum imx_pll14xx_type type;
+       const struct imx_pll14xx_rate_table *rate_table;
        int flags;
 };
 
-struct clk *imx_clk_int_pll(const char *name, const char *parent_name, void __iomem *base, const struct imx_int_pll_clk *pll_clk);
+struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
+                void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
 
 struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
                const char *parent, void __iomem *base);