root/drivers/clk/imx/clk-pll14xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. imx_get_pll_settings
  2. clk_pll14xx_round_rate
  3. clk_pll1416x_recalc_rate
  4. clk_pll1443x_recalc_rate
  5. clk_pll14xx_mp_change
  6. clk_pll14xx_wait_lock
  7. clk_pll1416x_set_rate
  8. clk_pll1443x_set_rate
  9. clk_pll14xx_prepare
  10. clk_pll14xx_is_prepared
  11. clk_pll14xx_unprepare
  12. imx_clk_pll14xx

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright 2017-2018 NXP.
   4  */
   5 
   6 #include <linux/bitops.h>
   7 #include <linux/clk-provider.h>
   8 #include <linux/err.h>
   9 #include <linux/io.h>
  10 #include <linux/iopoll.h>
  11 #include <linux/slab.h>
  12 #include <linux/jiffies.h>
  13 
  14 #include "clk.h"
  15 
  16 #define GNRL_CTL        0x0
  17 #define DIV_CTL         0x4
  18 #define LOCK_STATUS     BIT(31)
  19 #define LOCK_SEL_MASK   BIT(29)
  20 #define CLKE_MASK       BIT(11)
  21 #define RST_MASK        BIT(9)
  22 #define BYPASS_MASK     BIT(4)
  23 #define MDIV_SHIFT      12
  24 #define MDIV_MASK       GENMASK(21, 12)
  25 #define PDIV_SHIFT      4
  26 #define PDIV_MASK       GENMASK(9, 4)
  27 #define SDIV_SHIFT      0
  28 #define SDIV_MASK       GENMASK(2, 0)
  29 #define KDIV_SHIFT      0
  30 #define KDIV_MASK       GENMASK(15, 0)
  31 
  32 #define LOCK_TIMEOUT_US         10000
  33 
  34 struct clk_pll14xx {
  35         struct clk_hw                   hw;
  36         void __iomem                    *base;
  37         enum imx_pll14xx_type           type;
  38         const struct imx_pll14xx_rate_table *rate_table;
  39         int rate_count;
  40 };
  41 
  42 #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
  43 
  44 static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
  45                 struct clk_pll14xx *pll, unsigned long rate)
  46 {
  47         const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
  48         int i;
  49 
  50         for (i = 0; i < pll->rate_count; i++)
  51                 if (rate == rate_table[i].rate)
  52                         return &rate_table[i];
  53 
  54         return NULL;
  55 }
  56 
  57 static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
  58                         unsigned long *prate)
  59 {
  60         struct clk_pll14xx *pll = to_clk_pll14xx(hw);
  61         const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
  62         int i;
  63 
  64         /* Assumming rate_table is in descending order */
  65         for (i = 0; i < pll->rate_count; i++)
  66                 if (rate >= rate_table[i].rate)
  67                         return rate_table[i].rate;
  68 
  69         /* return minimum supported value */
  70         return rate_table[i - 1].rate;
  71 }
  72 
  73 static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
  74                                                   unsigned long parent_rate)
  75 {
  76         struct clk_pll14xx *pll = to_clk_pll14xx(hw);
  77         u32 mdiv, pdiv, sdiv, pll_div;
  78         u64 fvco = parent_rate;
  79 
  80         pll_div = readl_relaxed(pll->base + 4);
  81         mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
  82         pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
  83         sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
  84 
  85         fvco *= mdiv;
  86         do_div(fvco, pdiv << sdiv);
  87 
  88         return fvco;
  89 }
  90 
  91 static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
  92                                                   unsigned long parent_rate)
  93 {
  94         struct clk_pll14xx *pll = to_clk_pll14xx(hw);
  95         u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1;
  96         short int kdiv;
  97         u64 fvco = parent_rate;
  98 
  99         pll_div_ctl0 = readl_relaxed(pll->base + 4);
 100         pll_div_ctl1 = readl_relaxed(pll->base + 8);
 101         mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
 102         pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
 103         sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
 104         kdiv = pll_div_ctl1 & KDIV_MASK;
 105 
 106         /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
 107         fvco *= (mdiv * 65536 + kdiv);
 108         pdiv *= 65536;
 109 
 110         do_div(fvco, pdiv << sdiv);
 111 
 112         return fvco;
 113 }
 114 
 115 static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate,
 116                                           u32 pll_div)
 117 {
 118         u32 old_mdiv, old_pdiv;
 119 
 120         old_mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
 121         old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
 122 
 123         return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv;
 124 }
 125 
 126 static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
 127 {
 128         u32 val;
 129 
 130         return readl_poll_timeout(pll->base, val, val & LOCK_STATUS, 0,
 131                         LOCK_TIMEOUT_US);
 132 }
 133 
 134 static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
 135                                  unsigned long prate)
 136 {
 137         struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 138         const struct imx_pll14xx_rate_table *rate;
 139         u32 tmp, div_val;
 140         int ret;
 141 
 142         rate = imx_get_pll_settings(pll, drate);
 143         if (!rate) {
 144                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 145                        drate, clk_hw_get_name(hw));
 146                 return -EINVAL;
 147         }
 148 
 149         tmp = readl_relaxed(pll->base + 4);
 150 
 151         if (!clk_pll14xx_mp_change(rate, tmp)) {
 152                 tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
 153                 tmp |= rate->sdiv << SDIV_SHIFT;
 154                 writel_relaxed(tmp, pll->base + 4);
 155 
 156                 return 0;
 157         }
 158 
 159         /* Bypass clock and set lock to pll output lock */
 160         tmp = readl_relaxed(pll->base);
 161         tmp |= LOCK_SEL_MASK;
 162         writel_relaxed(tmp, pll->base);
 163 
 164         /* Enable RST */
 165         tmp &= ~RST_MASK;
 166         writel_relaxed(tmp, pll->base);
 167 
 168         /* Enable BYPASS */
 169         tmp |= BYPASS_MASK;
 170         writel(tmp, pll->base);
 171 
 172         div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
 173                 (rate->sdiv << SDIV_SHIFT);
 174         writel_relaxed(div_val, pll->base + 0x4);
 175 
 176         /*
 177          * According to SPEC, t3 - t2 need to be greater than
 178          * 1us and 1/FREF, respectively.
 179          * FREF is FIN / Prediv, the prediv is [1, 63], so choose
 180          * 3us.
 181          */
 182         udelay(3);
 183 
 184         /* Disable RST */
 185         tmp |= RST_MASK;
 186         writel_relaxed(tmp, pll->base);
 187 
 188         /* Wait Lock */
 189         ret = clk_pll14xx_wait_lock(pll);
 190         if (ret)
 191                 return ret;
 192 
 193         /* Bypass */
 194         tmp &= ~BYPASS_MASK;
 195         writel_relaxed(tmp, pll->base);
 196 
 197         return 0;
 198 }
 199 
 200 static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 201                                  unsigned long prate)
 202 {
 203         struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 204         const struct imx_pll14xx_rate_table *rate;
 205         u32 tmp, div_val;
 206         int ret;
 207 
 208         rate = imx_get_pll_settings(pll, drate);
 209         if (!rate) {
 210                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 211                         drate, clk_hw_get_name(hw));
 212                 return -EINVAL;
 213         }
 214 
 215         tmp = readl_relaxed(pll->base + 4);
 216 
 217         if (!clk_pll14xx_mp_change(rate, tmp)) {
 218                 tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
 219                 tmp |= rate->sdiv << SDIV_SHIFT;
 220                 writel_relaxed(tmp, pll->base + 4);
 221 
 222                 tmp = rate->kdiv << KDIV_SHIFT;
 223                 writel_relaxed(tmp, pll->base + 8);
 224 
 225                 return 0;
 226         }
 227 
 228         /* Enable RST */
 229         tmp = readl_relaxed(pll->base);
 230         tmp &= ~RST_MASK;
 231         writel_relaxed(tmp, pll->base);
 232 
 233         /* Enable BYPASS */
 234         tmp |= BYPASS_MASK;
 235         writel_relaxed(tmp, pll->base);
 236 
 237         div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
 238                 (rate->sdiv << SDIV_SHIFT);
 239         writel_relaxed(div_val, pll->base + 0x4);
 240         writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
 241 
 242         /*
 243          * According to SPEC, t3 - t2 need to be greater than
 244          * 1us and 1/FREF, respectively.
 245          * FREF is FIN / Prediv, the prediv is [1, 63], so choose
 246          * 3us.
 247          */
 248         udelay(3);
 249 
 250         /* Disable RST */
 251         tmp |= RST_MASK;
 252         writel_relaxed(tmp, pll->base);
 253 
 254         /* Wait Lock*/
 255         ret = clk_pll14xx_wait_lock(pll);
 256         if (ret)
 257                 return ret;
 258 
 259         /* Bypass */
 260         tmp &= ~BYPASS_MASK;
 261         writel_relaxed(tmp, pll->base);
 262 
 263         return 0;
 264 }
 265 
 266 static int clk_pll14xx_prepare(struct clk_hw *hw)
 267 {
 268         struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 269         u32 val;
 270         int ret;
 271 
 272         /*
 273          * RESETB = 1 from 0, PLL starts its normal
 274          * operation after lock time
 275          */
 276         val = readl_relaxed(pll->base + GNRL_CTL);
 277         if (val & RST_MASK)
 278                 return 0;
 279         val |= BYPASS_MASK;
 280         writel_relaxed(val, pll->base + GNRL_CTL);
 281         val |= RST_MASK;
 282         writel_relaxed(val, pll->base + GNRL_CTL);
 283 
 284         ret = clk_pll14xx_wait_lock(pll);
 285         if (ret)
 286                 return ret;
 287 
 288         val &= ~BYPASS_MASK;
 289         writel_relaxed(val, pll->base + GNRL_CTL);
 290 
 291         return 0;
 292 }
 293 
 294 static int clk_pll14xx_is_prepared(struct clk_hw *hw)
 295 {
 296         struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 297         u32 val;
 298 
 299         val = readl_relaxed(pll->base + GNRL_CTL);
 300 
 301         return (val & RST_MASK) ? 1 : 0;
 302 }
 303 
 304 static void clk_pll14xx_unprepare(struct clk_hw *hw)
 305 {
 306         struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 307         u32 val;
 308 
 309         /*
 310          * Set RST to 0, power down mode is enabled and
 311          * every digital block is reset
 312          */
 313         val = readl_relaxed(pll->base + GNRL_CTL);
 314         val &= ~RST_MASK;
 315         writel_relaxed(val, pll->base + GNRL_CTL);
 316 }
 317 
 318 static const struct clk_ops clk_pll1416x_ops = {
 319         .prepare        = clk_pll14xx_prepare,
 320         .unprepare      = clk_pll14xx_unprepare,
 321         .is_prepared    = clk_pll14xx_is_prepared,
 322         .recalc_rate    = clk_pll1416x_recalc_rate,
 323         .round_rate     = clk_pll14xx_round_rate,
 324         .set_rate       = clk_pll1416x_set_rate,
 325 };
 326 
 327 static const struct clk_ops clk_pll1416x_min_ops = {
 328         .recalc_rate    = clk_pll1416x_recalc_rate,
 329 };
 330 
 331 static const struct clk_ops clk_pll1443x_ops = {
 332         .prepare        = clk_pll14xx_prepare,
 333         .unprepare      = clk_pll14xx_unprepare,
 334         .is_prepared    = clk_pll14xx_is_prepared,
 335         .recalc_rate    = clk_pll1443x_recalc_rate,
 336         .round_rate     = clk_pll14xx_round_rate,
 337         .set_rate       = clk_pll1443x_set_rate,
 338 };
 339 
 340 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
 341                             void __iomem *base,
 342                             const struct imx_pll14xx_clk *pll_clk)
 343 {
 344         struct clk_pll14xx *pll;
 345         struct clk *clk;
 346         struct clk_init_data init;
 347         u32 val;
 348 
 349         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 350         if (!pll)
 351                 return ERR_PTR(-ENOMEM);
 352 
 353         init.name = name;
 354         init.flags = pll_clk->flags;
 355         init.parent_names = &parent_name;
 356         init.num_parents = 1;
 357 
 358         switch (pll_clk->type) {
 359         case PLL_1416X:
 360                 if (!pll_clk->rate_table)
 361                         init.ops = &clk_pll1416x_min_ops;
 362                 else
 363                         init.ops = &clk_pll1416x_ops;
 364                 break;
 365         case PLL_1443X:
 366                 init.ops = &clk_pll1443x_ops;
 367                 break;
 368         default:
 369                 pr_err("%s: Unknown pll type for pll clk %s\n",
 370                        __func__, name);
 371         };
 372 
 373         pll->base = base;
 374         pll->hw.init = &init;
 375         pll->type = pll_clk->type;
 376         pll->rate_table = pll_clk->rate_table;
 377         pll->rate_count = pll_clk->rate_count;
 378 
 379         val = readl_relaxed(pll->base + GNRL_CTL);
 380         val &= ~BYPASS_MASK;
 381         writel_relaxed(val, pll->base + GNRL_CTL);
 382 
 383         clk = clk_register(NULL, &pll->hw);
 384         if (IS_ERR(clk)) {
 385                 pr_err("%s: failed to register pll %s %lu\n",
 386                         __func__, name, PTR_ERR(clk));
 387                 kfree(pll);
 388         }
 389 
 390         return clk;
 391 }

/* [<][>][^][v][top][bottom][index][help] */