root/drivers/clk/imx/clk-sccg-pll.c

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

DEFINITIONS

This source file includes following definitions.
  1. clk_sccg_pll_wait_lock
  2. clk_sccg_pll2_check_match
  3. clk_sccg_divq_lookup
  4. clk_sccg_divf2_lookup
  5. clk_sccg_divr2_lookup
  6. clk_sccg_pll2_find_setup
  7. clk_sccg_divf1_lookup
  8. clk_sccg_divr1_lookup
  9. clk_sccg_pll1_find_setup
  10. clk_sccg_pll_find_setup
  11. clk_sccg_pll_is_prepared
  12. clk_sccg_pll_prepare
  13. clk_sccg_pll_unprepare
  14. clk_sccg_pll_recalc_rate
  15. clk_sccg_pll_set_rate
  16. clk_sccg_pll_get_parent
  17. clk_sccg_pll_set_parent
  18. __clk_sccg_pll_determine_rate
  19. clk_sccg_pll_determine_rate
  20. imx_clk_sccg_pll

   1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
   2 /*
   3  * Copyright 2018 NXP.
   4  *
   5  * This driver supports the SCCG plls found in the imx8m SOCs
   6  *
   7  * Documentation for this SCCG pll can be found at:
   8  *   https://www.nxp.com/docs/en/reference-manual/IMX8MDQLQRM.pdf#page=834
   9  */
  10 
  11 #include <linux/clk-provider.h>
  12 #include <linux/err.h>
  13 #include <linux/io.h>
  14 #include <linux/iopoll.h>
  15 #include <linux/slab.h>
  16 #include <linux/bitfield.h>
  17 
  18 #include "clk.h"
  19 
  20 /* PLL CFGs */
  21 #define PLL_CFG0                0x0
  22 #define PLL_CFG1                0x4
  23 #define PLL_CFG2                0x8
  24 
  25 #define PLL_DIVF1_MASK          GENMASK(18, 13)
  26 #define PLL_DIVF2_MASK          GENMASK(12, 7)
  27 #define PLL_DIVR1_MASK          GENMASK(27, 25)
  28 #define PLL_DIVR2_MASK          GENMASK(24, 19)
  29 #define PLL_DIVQ_MASK           GENMASK(6, 1)
  30 #define PLL_REF_MASK            GENMASK(2, 0)
  31 
  32 #define PLL_LOCK_MASK           BIT(31)
  33 #define PLL_PD_MASK             BIT(7)
  34 
  35 /* These are the specification limits for the SSCG PLL */
  36 #define PLL_REF_MIN_FREQ                25000000UL
  37 #define PLL_REF_MAX_FREQ                235000000UL
  38 
  39 #define PLL_STAGE1_MIN_FREQ             1600000000UL
  40 #define PLL_STAGE1_MAX_FREQ             2400000000UL
  41 
  42 #define PLL_STAGE1_REF_MIN_FREQ         25000000UL
  43 #define PLL_STAGE1_REF_MAX_FREQ         54000000UL
  44 
  45 #define PLL_STAGE2_MIN_FREQ             1200000000UL
  46 #define PLL_STAGE2_MAX_FREQ             2400000000UL
  47 
  48 #define PLL_STAGE2_REF_MIN_FREQ         54000000UL
  49 #define PLL_STAGE2_REF_MAX_FREQ         75000000UL
  50 
  51 #define PLL_OUT_MIN_FREQ                20000000UL
  52 #define PLL_OUT_MAX_FREQ                1200000000UL
  53 
  54 #define PLL_DIVR1_MAX                   7
  55 #define PLL_DIVR2_MAX                   63
  56 #define PLL_DIVF1_MAX                   63
  57 #define PLL_DIVF2_MAX                   63
  58 #define PLL_DIVQ_MAX                    63
  59 
  60 #define PLL_BYPASS_NONE                 0x0
  61 #define PLL_BYPASS1                     0x2
  62 #define PLL_BYPASS2                     0x1
  63 
  64 #define SSCG_PLL_BYPASS1_MASK           BIT(5)
  65 #define SSCG_PLL_BYPASS2_MASK           BIT(4)
  66 #define SSCG_PLL_BYPASS_MASK            GENMASK(5, 4)
  67 
  68 #define PLL_SCCG_LOCK_TIMEOUT           70
  69 
  70 struct clk_sccg_pll_setup {
  71         int divr1, divf1;
  72         int divr2, divf2;
  73         int divq;
  74         int bypass;
  75 
  76         uint64_t vco1;
  77         uint64_t vco2;
  78         uint64_t fout;
  79         uint64_t ref;
  80         uint64_t ref_div1;
  81         uint64_t ref_div2;
  82         uint64_t fout_request;
  83         int fout_error;
  84 };
  85 
  86 struct clk_sccg_pll {
  87         struct clk_hw   hw;
  88         const struct clk_ops  ops;
  89 
  90         void __iomem *base;
  91 
  92         struct clk_sccg_pll_setup setup;
  93 
  94         u8 parent;
  95         u8 bypass1;
  96         u8 bypass2;
  97 };
  98 
  99 #define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw)
 100 
 101 static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll)
 102 {
 103         u32 val;
 104 
 105         val = readl_relaxed(pll->base + PLL_CFG0);
 106 
 107         /* don't wait for lock if all plls are bypassed */
 108         if (!(val & SSCG_PLL_BYPASS2_MASK))
 109                 return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK,
 110                                                 0, PLL_SCCG_LOCK_TIMEOUT);
 111 
 112         return 0;
 113 }
 114 
 115 static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
 116                                         struct clk_sccg_pll_setup *temp_setup)
 117 {
 118         int new_diff = temp_setup->fout - temp_setup->fout_request;
 119         int diff = temp_setup->fout_error;
 120 
 121         if (abs(diff) > abs(new_diff)) {
 122                 temp_setup->fout_error = new_diff;
 123                 memcpy(setup, temp_setup, sizeof(struct clk_sccg_pll_setup));
 124 
 125                 if (temp_setup->fout_request == temp_setup->fout)
 126                         return 0;
 127         }
 128         return -1;
 129 }
 130 
 131 static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
 132                                 struct clk_sccg_pll_setup *temp_setup)
 133 {
 134         int ret = -EINVAL;
 135 
 136         for (temp_setup->divq = 0; temp_setup->divq <= PLL_DIVQ_MAX;
 137              temp_setup->divq++) {
 138                 temp_setup->vco2 = temp_setup->vco1;
 139                 do_div(temp_setup->vco2, temp_setup->divr2 + 1);
 140                 temp_setup->vco2 *= 2;
 141                 temp_setup->vco2 *= temp_setup->divf2 + 1;
 142                 if (temp_setup->vco2 >= PLL_STAGE2_MIN_FREQ &&
 143                                 temp_setup->vco2 <= PLL_STAGE2_MAX_FREQ) {
 144                         temp_setup->fout = temp_setup->vco2;
 145                         do_div(temp_setup->fout, 2 * (temp_setup->divq + 1));
 146 
 147                         ret = clk_sccg_pll2_check_match(setup, temp_setup);
 148                         if (!ret) {
 149                                 temp_setup->bypass = PLL_BYPASS1;
 150                                 return ret;
 151                         }
 152                 }
 153         }
 154 
 155         return ret;
 156 }
 157 
 158 static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
 159                                         struct clk_sccg_pll_setup *temp_setup)
 160 {
 161         int ret = -EINVAL;
 162 
 163         for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX;
 164              temp_setup->divf2++) {
 165                 ret = clk_sccg_divq_lookup(setup, temp_setup);
 166                 if (!ret)
 167                         return ret;
 168         }
 169 
 170         return ret;
 171 }
 172 
 173 static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
 174                                 struct clk_sccg_pll_setup *temp_setup)
 175 {
 176         int ret = -EINVAL;
 177 
 178         for (temp_setup->divr2 = 0; temp_setup->divr2 <= PLL_DIVR2_MAX;
 179              temp_setup->divr2++) {
 180                 temp_setup->ref_div2 = temp_setup->vco1;
 181                 do_div(temp_setup->ref_div2, temp_setup->divr2 + 1);
 182                 if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ &&
 183                     temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) {
 184                         ret = clk_sccg_divf2_lookup(setup, temp_setup);
 185                         if (!ret)
 186                                 return ret;
 187                 }
 188         }
 189 
 190         return ret;
 191 }
 192 
 193 static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
 194                                         struct clk_sccg_pll_setup *temp_setup,
 195                                         uint64_t ref)
 196 {
 197 
 198         int ret = -EINVAL;
 199 
 200         if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
 201                 return ret;
 202 
 203         temp_setup->vco1 = ref;
 204 
 205         ret = clk_sccg_divr2_lookup(setup, temp_setup);
 206         return ret;
 207 }
 208 
 209 static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
 210                                 struct clk_sccg_pll_setup *temp_setup)
 211 {
 212         int ret = -EINVAL;
 213 
 214         for (temp_setup->divf1 = 0; temp_setup->divf1 <= PLL_DIVF1_MAX;
 215              temp_setup->divf1++) {
 216                 uint64_t vco1 = temp_setup->ref;
 217 
 218                 do_div(vco1, temp_setup->divr1 + 1);
 219                 vco1 *= 2;
 220                 vco1 *= temp_setup->divf1 + 1;
 221 
 222                 ret = clk_sccg_pll2_find_setup(setup, temp_setup, vco1);
 223                 if (!ret) {
 224                         temp_setup->bypass = PLL_BYPASS_NONE;
 225                         return ret;
 226                 }
 227         }
 228 
 229         return ret;
 230 }
 231 
 232 static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
 233                                 struct clk_sccg_pll_setup *temp_setup)
 234 {
 235         int ret = -EINVAL;
 236 
 237         for (temp_setup->divr1 = 0; temp_setup->divr1 <= PLL_DIVR1_MAX;
 238              temp_setup->divr1++) {
 239                 temp_setup->ref_div1 = temp_setup->ref;
 240                 do_div(temp_setup->ref_div1, temp_setup->divr1 + 1);
 241                 if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ &&
 242                     temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) {
 243                         ret = clk_sccg_divf1_lookup(setup, temp_setup);
 244                         if (!ret)
 245                                 return ret;
 246                 }
 247         }
 248 
 249         return ret;
 250 }
 251 
 252 static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
 253                                         struct clk_sccg_pll_setup *temp_setup,
 254                                         uint64_t ref)
 255 {
 256 
 257         int ret = -EINVAL;
 258 
 259         if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
 260                 return ret;
 261 
 262         temp_setup->ref = ref;
 263 
 264         ret = clk_sccg_divr1_lookup(setup, temp_setup);
 265 
 266         return ret;
 267 }
 268 
 269 static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
 270                                         uint64_t prate,
 271                                         uint64_t rate, int try_bypass)
 272 {
 273         struct clk_sccg_pll_setup temp_setup;
 274         int ret = -EINVAL;
 275 
 276         memset(&temp_setup, 0, sizeof(struct clk_sccg_pll_setup));
 277         memset(setup, 0, sizeof(struct clk_sccg_pll_setup));
 278 
 279         temp_setup.fout_error = PLL_OUT_MAX_FREQ;
 280         temp_setup.fout_request = rate;
 281 
 282         switch (try_bypass) {
 283 
 284         case PLL_BYPASS2:
 285                 if (prate == rate) {
 286                         setup->bypass = PLL_BYPASS2;
 287                         setup->fout = rate;
 288                         ret = 0;
 289                 }
 290                 break;
 291 
 292         case PLL_BYPASS1:
 293                 ret = clk_sccg_pll2_find_setup(setup, &temp_setup, prate);
 294                 break;
 295 
 296         case PLL_BYPASS_NONE:
 297                 ret = clk_sccg_pll1_find_setup(setup, &temp_setup, prate);
 298                 break;
 299         }
 300 
 301         return ret;
 302 }
 303 
 304 
 305 static int clk_sccg_pll_is_prepared(struct clk_hw *hw)
 306 {
 307         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 308 
 309         u32 val = readl_relaxed(pll->base + PLL_CFG0);
 310 
 311         return (val & PLL_PD_MASK) ? 0 : 1;
 312 }
 313 
 314 static int clk_sccg_pll_prepare(struct clk_hw *hw)
 315 {
 316         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 317         u32 val;
 318 
 319         val = readl_relaxed(pll->base + PLL_CFG0);
 320         val &= ~PLL_PD_MASK;
 321         writel_relaxed(val, pll->base + PLL_CFG0);
 322 
 323         return clk_sccg_pll_wait_lock(pll);
 324 }
 325 
 326 static void clk_sccg_pll_unprepare(struct clk_hw *hw)
 327 {
 328         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 329         u32 val;
 330 
 331         val = readl_relaxed(pll->base + PLL_CFG0);
 332         val |= PLL_PD_MASK;
 333         writel_relaxed(val, pll->base + PLL_CFG0);
 334 }
 335 
 336 static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
 337                                          unsigned long parent_rate)
 338 {
 339         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 340         u32 val, divr1, divf1, divr2, divf2, divq;
 341         u64 temp64;
 342 
 343         val = readl_relaxed(pll->base + PLL_CFG2);
 344         divr1 = FIELD_GET(PLL_DIVR1_MASK, val);
 345         divr2 = FIELD_GET(PLL_DIVR2_MASK, val);
 346         divf1 = FIELD_GET(PLL_DIVF1_MASK, val);
 347         divf2 = FIELD_GET(PLL_DIVF2_MASK, val);
 348         divq = FIELD_GET(PLL_DIVQ_MASK, val);
 349 
 350         temp64 = parent_rate;
 351 
 352         val = readl(pll->base + PLL_CFG0);
 353         if (val & SSCG_PLL_BYPASS2_MASK) {
 354                 temp64 = parent_rate;
 355         } else if (val & SSCG_PLL_BYPASS1_MASK) {
 356                 temp64 *= divf2;
 357                 do_div(temp64, (divr2 + 1) * (divq + 1));
 358         } else {
 359                 temp64 *= 2;
 360                 temp64 *= (divf1 + 1) * (divf2 + 1);
 361                 do_div(temp64, (divr1 + 1) * (divr2 + 1) * (divq + 1));
 362         }
 363 
 364         return temp64;
 365 }
 366 
 367 static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 368                             unsigned long parent_rate)
 369 {
 370         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 371         struct clk_sccg_pll_setup *setup = &pll->setup;
 372         u32 val;
 373 
 374         /* set bypass here too since the parent might be the same */
 375         val = readl(pll->base + PLL_CFG0);
 376         val &= ~SSCG_PLL_BYPASS_MASK;
 377         val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass);
 378         writel(val, pll->base + PLL_CFG0);
 379 
 380         val = readl_relaxed(pll->base + PLL_CFG2);
 381         val &= ~(PLL_DIVF1_MASK | PLL_DIVF2_MASK);
 382         val &= ~(PLL_DIVR1_MASK | PLL_DIVR2_MASK | PLL_DIVQ_MASK);
 383         val |= FIELD_PREP(PLL_DIVF1_MASK, setup->divf1);
 384         val |= FIELD_PREP(PLL_DIVF2_MASK, setup->divf2);
 385         val |= FIELD_PREP(PLL_DIVR1_MASK, setup->divr1);
 386         val |= FIELD_PREP(PLL_DIVR2_MASK, setup->divr2);
 387         val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq);
 388         writel_relaxed(val, pll->base + PLL_CFG2);
 389 
 390         return clk_sccg_pll_wait_lock(pll);
 391 }
 392 
 393 static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
 394 {
 395         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 396         u32 val;
 397         u8 ret = pll->parent;
 398 
 399         val = readl(pll->base + PLL_CFG0);
 400         if (val & SSCG_PLL_BYPASS2_MASK)
 401                 ret = pll->bypass2;
 402         else if (val & SSCG_PLL_BYPASS1_MASK)
 403                 ret = pll->bypass1;
 404         return ret;
 405 }
 406 
 407 static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
 408 {
 409         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 410         u32 val;
 411 
 412         val = readl(pll->base + PLL_CFG0);
 413         val &= ~SSCG_PLL_BYPASS_MASK;
 414         val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
 415         writel(val, pll->base + PLL_CFG0);
 416 
 417         return clk_sccg_pll_wait_lock(pll);
 418 }
 419 
 420 static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
 421                                         struct clk_rate_request *req,
 422                                         uint64_t min,
 423                                         uint64_t max,
 424                                         uint64_t rate,
 425                                         int bypass)
 426 {
 427         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 428         struct clk_sccg_pll_setup *setup = &pll->setup;
 429         struct clk_hw *parent_hw = NULL;
 430         int bypass_parent_index;
 431         int ret = -EINVAL;
 432 
 433         req->max_rate = max;
 434         req->min_rate = min;
 435 
 436         switch (bypass) {
 437         case PLL_BYPASS2:
 438                 bypass_parent_index = pll->bypass2;
 439                 break;
 440         case PLL_BYPASS1:
 441                 bypass_parent_index = pll->bypass1;
 442                 break;
 443         default:
 444                 bypass_parent_index = pll->parent;
 445                 break;
 446         }
 447 
 448         parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index);
 449         ret = __clk_determine_rate(parent_hw, req);
 450         if (!ret) {
 451                 ret = clk_sccg_pll_find_setup(setup, req->rate,
 452                                                 rate, bypass);
 453         }
 454 
 455         req->best_parent_hw = parent_hw;
 456         req->best_parent_rate = req->rate;
 457         req->rate = setup->fout;
 458 
 459         return ret;
 460 }
 461 
 462 static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
 463                                        struct clk_rate_request *req)
 464 {
 465         struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 466         struct clk_sccg_pll_setup *setup = &pll->setup;
 467         uint64_t rate = req->rate;
 468         uint64_t min = req->min_rate;
 469         uint64_t max = req->max_rate;
 470         int ret = -EINVAL;
 471 
 472         if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ)
 473                 return ret;
 474 
 475         ret = __clk_sccg_pll_determine_rate(hw, req, req->rate, req->rate,
 476                                                 rate, PLL_BYPASS2);
 477         if (!ret)
 478                 return ret;
 479 
 480         ret = __clk_sccg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
 481                                                 PLL_STAGE1_REF_MAX_FREQ, rate,
 482                                                 PLL_BYPASS1);
 483         if (!ret)
 484                 return ret;
 485 
 486         ret = __clk_sccg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
 487                                                 PLL_REF_MAX_FREQ, rate,
 488                                                 PLL_BYPASS_NONE);
 489         if (!ret)
 490                 return ret;
 491 
 492         if (setup->fout >= min && setup->fout <= max)
 493                 ret = 0;
 494 
 495         return ret;
 496 }
 497 
 498 static const struct clk_ops clk_sccg_pll_ops = {
 499         .prepare        = clk_sccg_pll_prepare,
 500         .unprepare      = clk_sccg_pll_unprepare,
 501         .is_prepared    = clk_sccg_pll_is_prepared,
 502         .recalc_rate    = clk_sccg_pll_recalc_rate,
 503         .set_rate       = clk_sccg_pll_set_rate,
 504         .set_parent     = clk_sccg_pll_set_parent,
 505         .get_parent     = clk_sccg_pll_get_parent,
 506         .determine_rate = clk_sccg_pll_determine_rate,
 507 };
 508 
 509 struct clk *imx_clk_sccg_pll(const char *name,
 510                                 const char * const *parent_names,
 511                                 u8 num_parents,
 512                                 u8 parent, u8 bypass1, u8 bypass2,
 513                                 void __iomem *base,
 514                                 unsigned long flags)
 515 {
 516         struct clk_sccg_pll *pll;
 517         struct clk_init_data init;
 518         struct clk_hw *hw;
 519         int ret;
 520 
 521         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 522         if (!pll)
 523                 return ERR_PTR(-ENOMEM);
 524 
 525         pll->parent = parent;
 526         pll->bypass1 = bypass1;
 527         pll->bypass2 = bypass2;
 528 
 529         pll->base = base;
 530         init.name = name;
 531         init.ops = &clk_sccg_pll_ops;
 532 
 533         init.flags = flags;
 534         init.parent_names = parent_names;
 535         init.num_parents = num_parents;
 536 
 537         pll->base = base;
 538         pll->hw.init = &init;
 539 
 540         hw = &pll->hw;
 541 
 542         ret = clk_hw_register(NULL, hw);
 543         if (ret) {
 544                 kfree(pll);
 545                 return ERR_PTR(ret);
 546         }
 547 
 548         return hw->clk;
 549 }

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