root/drivers/clk/rockchip/clk-pll.c

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

DEFINITIONS

This source file includes following definitions.
  1. rockchip_get_pll_settings
  2. rockchip_pll_round_rate
  3. rockchip_pll_wait_lock
  4. rockchip_rk3036_pll_get_params
  5. rockchip_rk3036_pll_recalc_rate
  6. rockchip_rk3036_pll_set_params
  7. rockchip_rk3036_pll_set_rate
  8. rockchip_rk3036_pll_enable
  9. rockchip_rk3036_pll_disable
  10. rockchip_rk3036_pll_is_enabled
  11. rockchip_rk3036_pll_init
  12. rockchip_rk3066_pll_get_params
  13. rockchip_rk3066_pll_recalc_rate
  14. rockchip_rk3066_pll_set_params
  15. rockchip_rk3066_pll_set_rate
  16. rockchip_rk3066_pll_enable
  17. rockchip_rk3066_pll_disable
  18. rockchip_rk3066_pll_is_enabled
  19. rockchip_rk3066_pll_init
  20. rockchip_rk3399_pll_wait_lock
  21. rockchip_rk3399_pll_get_params
  22. rockchip_rk3399_pll_recalc_rate
  23. rockchip_rk3399_pll_set_params
  24. rockchip_rk3399_pll_set_rate
  25. rockchip_rk3399_pll_enable
  26. rockchip_rk3399_pll_disable
  27. rockchip_rk3399_pll_is_enabled
  28. rockchip_rk3399_pll_init
  29. rockchip_clk_register_pll

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (c) 2014 MundoReader S.L.
   4  * Author: Heiko Stuebner <heiko@sntech.de>
   5  *
   6  * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
   7  * Author: Xing Zheng <zhengxing@rock-chips.com>
   8  */
   9 
  10 #include <asm/div64.h>
  11 #include <linux/slab.h>
  12 #include <linux/io.h>
  13 #include <linux/delay.h>
  14 #include <linux/clk-provider.h>
  15 #include <linux/regmap.h>
  16 #include <linux/clk.h>
  17 #include "clk.h"
  18 
  19 #define PLL_MODE_MASK           0x3
  20 #define PLL_MODE_SLOW           0x0
  21 #define PLL_MODE_NORM           0x1
  22 #define PLL_MODE_DEEP           0x2
  23 #define PLL_RK3328_MODE_MASK    0x1
  24 
  25 struct rockchip_clk_pll {
  26         struct clk_hw           hw;
  27 
  28         struct clk_mux          pll_mux;
  29         const struct clk_ops    *pll_mux_ops;
  30 
  31         struct notifier_block   clk_nb;
  32 
  33         void __iomem            *reg_base;
  34         int                     lock_offset;
  35         unsigned int            lock_shift;
  36         enum rockchip_pll_type  type;
  37         u8                      flags;
  38         const struct rockchip_pll_rate_table *rate_table;
  39         unsigned int            rate_count;
  40         spinlock_t              *lock;
  41 
  42         struct rockchip_clk_provider *ctx;
  43 };
  44 
  45 #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
  46 #define to_rockchip_clk_pll_nb(nb) \
  47                         container_of(nb, struct rockchip_clk_pll, clk_nb)
  48 
  49 static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
  50                             struct rockchip_clk_pll *pll, unsigned long rate)
  51 {
  52         const struct rockchip_pll_rate_table  *rate_table = pll->rate_table;
  53         int i;
  54 
  55         for (i = 0; i < pll->rate_count; i++) {
  56                 if (rate == rate_table[i].rate)
  57                         return &rate_table[i];
  58         }
  59 
  60         return NULL;
  61 }
  62 
  63 static long rockchip_pll_round_rate(struct clk_hw *hw,
  64                             unsigned long drate, unsigned long *prate)
  65 {
  66         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
  67         const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
  68         int i;
  69 
  70         /* Assumming rate_table is in descending order */
  71         for (i = 0; i < pll->rate_count; i++) {
  72                 if (drate >= rate_table[i].rate)
  73                         return rate_table[i].rate;
  74         }
  75 
  76         /* return minimum supported value */
  77         return rate_table[i - 1].rate;
  78 }
  79 
  80 /*
  81  * Wait for the pll to reach the locked state.
  82  * The calling set_rate function is responsible for making sure the
  83  * grf regmap is available.
  84  */
  85 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
  86 {
  87         struct regmap *grf = pll->ctx->grf;
  88         unsigned int val;
  89         int delay = 24000000, ret;
  90 
  91         while (delay > 0) {
  92                 ret = regmap_read(grf, pll->lock_offset, &val);
  93                 if (ret) {
  94                         pr_err("%s: failed to read pll lock status: %d\n",
  95                                __func__, ret);
  96                         return ret;
  97                 }
  98 
  99                 if (val & BIT(pll->lock_shift))
 100                         return 0;
 101                 delay--;
 102         }
 103 
 104         pr_err("%s: timeout waiting for pll to lock\n", __func__);
 105         return -ETIMEDOUT;
 106 }
 107 
 108 /**
 109  * PLL used in RK3036
 110  */
 111 
 112 #define RK3036_PLLCON(i)                        (i * 0x4)
 113 #define RK3036_PLLCON0_FBDIV_MASK               0xfff
 114 #define RK3036_PLLCON0_FBDIV_SHIFT              0
 115 #define RK3036_PLLCON0_POSTDIV1_MASK            0x7
 116 #define RK3036_PLLCON0_POSTDIV1_SHIFT           12
 117 #define RK3036_PLLCON1_REFDIV_MASK              0x3f
 118 #define RK3036_PLLCON1_REFDIV_SHIFT             0
 119 #define RK3036_PLLCON1_POSTDIV2_MASK            0x7
 120 #define RK3036_PLLCON1_POSTDIV2_SHIFT           6
 121 #define RK3036_PLLCON1_DSMPD_MASK               0x1
 122 #define RK3036_PLLCON1_DSMPD_SHIFT              12
 123 #define RK3036_PLLCON2_FRAC_MASK                0xffffff
 124 #define RK3036_PLLCON2_FRAC_SHIFT               0
 125 
 126 #define RK3036_PLLCON1_PWRDOWN                  (1 << 13)
 127 
 128 static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
 129                                         struct rockchip_pll_rate_table *rate)
 130 {
 131         u32 pllcon;
 132 
 133         pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
 134         rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT)
 135                                 & RK3036_PLLCON0_FBDIV_MASK);
 136         rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT)
 137                                 & RK3036_PLLCON0_POSTDIV1_MASK);
 138 
 139         pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
 140         rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT)
 141                                 & RK3036_PLLCON1_REFDIV_MASK);
 142         rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT)
 143                                 & RK3036_PLLCON1_POSTDIV2_MASK);
 144         rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT)
 145                                 & RK3036_PLLCON1_DSMPD_MASK);
 146 
 147         pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
 148         rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT)
 149                                 & RK3036_PLLCON2_FRAC_MASK);
 150 }
 151 
 152 static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
 153                                                      unsigned long prate)
 154 {
 155         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 156         struct rockchip_pll_rate_table cur;
 157         u64 rate64 = prate;
 158 
 159         rockchip_rk3036_pll_get_params(pll, &cur);
 160 
 161         rate64 *= cur.fbdiv;
 162         do_div(rate64, cur.refdiv);
 163 
 164         if (cur.dsmpd == 0) {
 165                 /* fractional mode */
 166                 u64 frac_rate64 = prate * cur.frac;
 167 
 168                 do_div(frac_rate64, cur.refdiv);
 169                 rate64 += frac_rate64 >> 24;
 170         }
 171 
 172         do_div(rate64, cur.postdiv1);
 173         do_div(rate64, cur.postdiv2);
 174 
 175         return (unsigned long)rate64;
 176 }
 177 
 178 static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
 179                                 const struct rockchip_pll_rate_table *rate)
 180 {
 181         const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
 182         struct clk_mux *pll_mux = &pll->pll_mux;
 183         struct rockchip_pll_rate_table cur;
 184         u32 pllcon;
 185         int rate_change_remuxed = 0;
 186         int cur_parent;
 187         int ret;
 188 
 189         pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
 190                 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
 191                 rate->postdiv2, rate->dsmpd, rate->frac);
 192 
 193         rockchip_rk3036_pll_get_params(pll, &cur);
 194         cur.rate = 0;
 195 
 196         cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
 197         if (cur_parent == PLL_MODE_NORM) {
 198                 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
 199                 rate_change_remuxed = 1;
 200         }
 201 
 202         /* update pll values */
 203         writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
 204                                           RK3036_PLLCON0_FBDIV_SHIFT) |
 205                        HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
 206                                              RK3036_PLLCON0_POSTDIV1_SHIFT),
 207                        pll->reg_base + RK3036_PLLCON(0));
 208 
 209         writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
 210                                                    RK3036_PLLCON1_REFDIV_SHIFT) |
 211                        HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
 212                                                      RK3036_PLLCON1_POSTDIV2_SHIFT) |
 213                        HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
 214                                                   RK3036_PLLCON1_DSMPD_SHIFT),
 215                        pll->reg_base + RK3036_PLLCON(1));
 216 
 217         /* GPLL CON2 is not HIWORD_MASK */
 218         pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
 219         pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
 220         pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
 221         writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
 222 
 223         /* wait for the pll to lock */
 224         ret = rockchip_pll_wait_lock(pll);
 225         if (ret) {
 226                 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
 227                         __func__);
 228                 rockchip_rk3036_pll_set_params(pll, &cur);
 229         }
 230 
 231         if (rate_change_remuxed)
 232                 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
 233 
 234         return ret;
 235 }
 236 
 237 static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 238                                         unsigned long prate)
 239 {
 240         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 241         const struct rockchip_pll_rate_table *rate;
 242 
 243         pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
 244                  __func__, __clk_get_name(hw->clk), drate, prate);
 245 
 246         /* Get required rate settings from table */
 247         rate = rockchip_get_pll_settings(pll, drate);
 248         if (!rate) {
 249                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 250                         drate, __clk_get_name(hw->clk));
 251                 return -EINVAL;
 252         }
 253 
 254         return rockchip_rk3036_pll_set_params(pll, rate);
 255 }
 256 
 257 static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
 258 {
 259         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 260 
 261         writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
 262                pll->reg_base + RK3036_PLLCON(1));
 263         rockchip_pll_wait_lock(pll);
 264 
 265         return 0;
 266 }
 267 
 268 static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
 269 {
 270         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 271 
 272         writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
 273                              RK3036_PLLCON1_PWRDOWN, 0),
 274                pll->reg_base + RK3036_PLLCON(1));
 275 }
 276 
 277 static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
 278 {
 279         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 280         u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));
 281 
 282         return !(pllcon & RK3036_PLLCON1_PWRDOWN);
 283 }
 284 
 285 static void rockchip_rk3036_pll_init(struct clk_hw *hw)
 286 {
 287         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 288         const struct rockchip_pll_rate_table *rate;
 289         struct rockchip_pll_rate_table cur;
 290         unsigned long drate;
 291 
 292         if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
 293                 return;
 294 
 295         drate = clk_hw_get_rate(hw);
 296         rate = rockchip_get_pll_settings(pll, drate);
 297 
 298         /* when no rate setting for the current rate, rely on clk_set_rate */
 299         if (!rate)
 300                 return;
 301 
 302         rockchip_rk3036_pll_get_params(pll, &cur);
 303 
 304         pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
 305                  drate);
 306         pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
 307                  cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
 308                  cur.dsmpd, cur.frac);
 309         pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
 310                  rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
 311                  rate->dsmpd, rate->frac);
 312 
 313         if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
 314                 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
 315                 rate->dsmpd != cur.dsmpd ||
 316                 (!cur.dsmpd && (rate->frac != cur.frac))) {
 317                 struct clk *parent = clk_get_parent(hw->clk);
 318 
 319                 if (!parent) {
 320                         pr_warn("%s: parent of %s not available\n",
 321                                 __func__, __clk_get_name(hw->clk));
 322                         return;
 323                 }
 324 
 325                 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
 326                          __func__, __clk_get_name(hw->clk));
 327                 rockchip_rk3036_pll_set_params(pll, rate);
 328         }
 329 }
 330 
 331 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
 332         .recalc_rate = rockchip_rk3036_pll_recalc_rate,
 333         .enable = rockchip_rk3036_pll_enable,
 334         .disable = rockchip_rk3036_pll_disable,
 335         .is_enabled = rockchip_rk3036_pll_is_enabled,
 336 };
 337 
 338 static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
 339         .recalc_rate = rockchip_rk3036_pll_recalc_rate,
 340         .round_rate = rockchip_pll_round_rate,
 341         .set_rate = rockchip_rk3036_pll_set_rate,
 342         .enable = rockchip_rk3036_pll_enable,
 343         .disable = rockchip_rk3036_pll_disable,
 344         .is_enabled = rockchip_rk3036_pll_is_enabled,
 345         .init = rockchip_rk3036_pll_init,
 346 };
 347 
 348 /**
 349  * PLL used in RK3066, RK3188 and RK3288
 350  */
 351 
 352 #define RK3066_PLL_RESET_DELAY(nr)      ((nr * 500) / 24 + 1)
 353 
 354 #define RK3066_PLLCON(i)                (i * 0x4)
 355 #define RK3066_PLLCON0_OD_MASK          0xf
 356 #define RK3066_PLLCON0_OD_SHIFT         0
 357 #define RK3066_PLLCON0_NR_MASK          0x3f
 358 #define RK3066_PLLCON0_NR_SHIFT         8
 359 #define RK3066_PLLCON1_NF_MASK          0x1fff
 360 #define RK3066_PLLCON1_NF_SHIFT         0
 361 #define RK3066_PLLCON2_NB_MASK          0xfff
 362 #define RK3066_PLLCON2_NB_SHIFT         0
 363 #define RK3066_PLLCON3_RESET            (1 << 5)
 364 #define RK3066_PLLCON3_PWRDOWN          (1 << 1)
 365 #define RK3066_PLLCON3_BYPASS           (1 << 0)
 366 
 367 static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
 368                                         struct rockchip_pll_rate_table *rate)
 369 {
 370         u32 pllcon;
 371 
 372         pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
 373         rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
 374                                 & RK3066_PLLCON0_NR_MASK) + 1;
 375         rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
 376                                 & RK3066_PLLCON0_OD_MASK) + 1;
 377 
 378         pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
 379         rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
 380                                 & RK3066_PLLCON1_NF_MASK) + 1;
 381 
 382         pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
 383         rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
 384                                 & RK3066_PLLCON2_NB_MASK) + 1;
 385 }
 386 
 387 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
 388                                                      unsigned long prate)
 389 {
 390         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 391         struct rockchip_pll_rate_table cur;
 392         u64 rate64 = prate;
 393         u32 pllcon;
 394 
 395         pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
 396         if (pllcon & RK3066_PLLCON3_BYPASS) {
 397                 pr_debug("%s: pll %s is bypassed\n", __func__,
 398                         clk_hw_get_name(hw));
 399                 return prate;
 400         }
 401 
 402         rockchip_rk3066_pll_get_params(pll, &cur);
 403 
 404         rate64 *= cur.nf;
 405         do_div(rate64, cur.nr);
 406         do_div(rate64, cur.no);
 407 
 408         return (unsigned long)rate64;
 409 }
 410 
 411 static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
 412                                 const struct rockchip_pll_rate_table *rate)
 413 {
 414         const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
 415         struct clk_mux *pll_mux = &pll->pll_mux;
 416         struct rockchip_pll_rate_table cur;
 417         int rate_change_remuxed = 0;
 418         int cur_parent;
 419         int ret;
 420 
 421         pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
 422                  __func__, rate->rate, rate->nr, rate->no, rate->nf);
 423 
 424         rockchip_rk3066_pll_get_params(pll, &cur);
 425         cur.rate = 0;
 426 
 427         cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
 428         if (cur_parent == PLL_MODE_NORM) {
 429                 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
 430                 rate_change_remuxed = 1;
 431         }
 432 
 433         /* enter reset mode */
 434         writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0),
 435                pll->reg_base + RK3066_PLLCON(3));
 436 
 437         /* update pll values */
 438         writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK,
 439                                            RK3066_PLLCON0_NR_SHIFT) |
 440                HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK,
 441                                            RK3066_PLLCON0_OD_SHIFT),
 442                pll->reg_base + RK3066_PLLCON(0));
 443 
 444         writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,
 445                                                    RK3066_PLLCON1_NF_SHIFT),
 446                        pll->reg_base + RK3066_PLLCON(1));
 447         writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK,
 448                                                    RK3066_PLLCON2_NB_SHIFT),
 449                        pll->reg_base + RK3066_PLLCON(2));
 450 
 451         /* leave reset and wait the reset_delay */
 452         writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0),
 453                pll->reg_base + RK3066_PLLCON(3));
 454         udelay(RK3066_PLL_RESET_DELAY(rate->nr));
 455 
 456         /* wait for the pll to lock */
 457         ret = rockchip_pll_wait_lock(pll);
 458         if (ret) {
 459                 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
 460                         __func__);
 461                 rockchip_rk3066_pll_set_params(pll, &cur);
 462         }
 463 
 464         if (rate_change_remuxed)
 465                 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
 466 
 467         return ret;
 468 }
 469 
 470 static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 471                                         unsigned long prate)
 472 {
 473         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 474         const struct rockchip_pll_rate_table *rate;
 475 
 476         pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
 477                  __func__, clk_hw_get_name(hw), drate, prate);
 478 
 479         /* Get required rate settings from table */
 480         rate = rockchip_get_pll_settings(pll, drate);
 481         if (!rate) {
 482                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 483                         drate, clk_hw_get_name(hw));
 484                 return -EINVAL;
 485         }
 486 
 487         return rockchip_rk3066_pll_set_params(pll, rate);
 488 }
 489 
 490 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
 491 {
 492         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 493 
 494         writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0),
 495                pll->reg_base + RK3066_PLLCON(3));
 496         rockchip_pll_wait_lock(pll);
 497 
 498         return 0;
 499 }
 500 
 501 static void rockchip_rk3066_pll_disable(struct clk_hw *hw)
 502 {
 503         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 504 
 505         writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN,
 506                              RK3066_PLLCON3_PWRDOWN, 0),
 507                pll->reg_base + RK3066_PLLCON(3));
 508 }
 509 
 510 static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
 511 {
 512         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 513         u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
 514 
 515         return !(pllcon & RK3066_PLLCON3_PWRDOWN);
 516 }
 517 
 518 static void rockchip_rk3066_pll_init(struct clk_hw *hw)
 519 {
 520         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 521         const struct rockchip_pll_rate_table *rate;
 522         struct rockchip_pll_rate_table cur;
 523         unsigned long drate;
 524 
 525         if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
 526                 return;
 527 
 528         drate = clk_hw_get_rate(hw);
 529         rate = rockchip_get_pll_settings(pll, drate);
 530 
 531         /* when no rate setting for the current rate, rely on clk_set_rate */
 532         if (!rate)
 533                 return;
 534 
 535         rockchip_rk3066_pll_get_params(pll, &cur);
 536 
 537         pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
 538                  __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
 539                  rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
 540         if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
 541                                                      || rate->nb != cur.nb) {
 542                 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
 543                          __func__, clk_hw_get_name(hw));
 544                 rockchip_rk3066_pll_set_params(pll, rate);
 545         }
 546 }
 547 
 548 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
 549         .recalc_rate = rockchip_rk3066_pll_recalc_rate,
 550         .enable = rockchip_rk3066_pll_enable,
 551         .disable = rockchip_rk3066_pll_disable,
 552         .is_enabled = rockchip_rk3066_pll_is_enabled,
 553 };
 554 
 555 static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
 556         .recalc_rate = rockchip_rk3066_pll_recalc_rate,
 557         .round_rate = rockchip_pll_round_rate,
 558         .set_rate = rockchip_rk3066_pll_set_rate,
 559         .enable = rockchip_rk3066_pll_enable,
 560         .disable = rockchip_rk3066_pll_disable,
 561         .is_enabled = rockchip_rk3066_pll_is_enabled,
 562         .init = rockchip_rk3066_pll_init,
 563 };
 564 
 565 /**
 566  * PLL used in RK3399
 567  */
 568 
 569 #define RK3399_PLLCON(i)                        (i * 0x4)
 570 #define RK3399_PLLCON0_FBDIV_MASK               0xfff
 571 #define RK3399_PLLCON0_FBDIV_SHIFT              0
 572 #define RK3399_PLLCON1_REFDIV_MASK              0x3f
 573 #define RK3399_PLLCON1_REFDIV_SHIFT             0
 574 #define RK3399_PLLCON1_POSTDIV1_MASK            0x7
 575 #define RK3399_PLLCON1_POSTDIV1_SHIFT           8
 576 #define RK3399_PLLCON1_POSTDIV2_MASK            0x7
 577 #define RK3399_PLLCON1_POSTDIV2_SHIFT           12
 578 #define RK3399_PLLCON2_FRAC_MASK                0xffffff
 579 #define RK3399_PLLCON2_FRAC_SHIFT               0
 580 #define RK3399_PLLCON2_LOCK_STATUS              BIT(31)
 581 #define RK3399_PLLCON3_PWRDOWN                  BIT(0)
 582 #define RK3399_PLLCON3_DSMPD_MASK               0x1
 583 #define RK3399_PLLCON3_DSMPD_SHIFT              3
 584 
 585 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
 586 {
 587         u32 pllcon;
 588         int delay = 24000000;
 589 
 590         /* poll check the lock status in rk3399 xPLLCON2 */
 591         while (delay > 0) {
 592                 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
 593                 if (pllcon & RK3399_PLLCON2_LOCK_STATUS)
 594                         return 0;
 595 
 596                 delay--;
 597         }
 598 
 599         pr_err("%s: timeout waiting for pll to lock\n", __func__);
 600         return -ETIMEDOUT;
 601 }
 602 
 603 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
 604                                         struct rockchip_pll_rate_table *rate)
 605 {
 606         u32 pllcon;
 607 
 608         pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
 609         rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)
 610                                 & RK3399_PLLCON0_FBDIV_MASK);
 611 
 612         pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
 613         rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)
 614                                 & RK3399_PLLCON1_REFDIV_MASK);
 615         rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)
 616                                 & RK3399_PLLCON1_POSTDIV1_MASK);
 617         rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)
 618                                 & RK3399_PLLCON1_POSTDIV2_MASK);
 619 
 620         pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
 621         rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)
 622                                 & RK3399_PLLCON2_FRAC_MASK);
 623 
 624         pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
 625         rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)
 626                                 & RK3399_PLLCON3_DSMPD_MASK);
 627 }
 628 
 629 static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
 630                                                      unsigned long prate)
 631 {
 632         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 633         struct rockchip_pll_rate_table cur;
 634         u64 rate64 = prate;
 635 
 636         rockchip_rk3399_pll_get_params(pll, &cur);
 637 
 638         rate64 *= cur.fbdiv;
 639         do_div(rate64, cur.refdiv);
 640 
 641         if (cur.dsmpd == 0) {
 642                 /* fractional mode */
 643                 u64 frac_rate64 = prate * cur.frac;
 644 
 645                 do_div(frac_rate64, cur.refdiv);
 646                 rate64 += frac_rate64 >> 24;
 647         }
 648 
 649         do_div(rate64, cur.postdiv1);
 650         do_div(rate64, cur.postdiv2);
 651 
 652         return (unsigned long)rate64;
 653 }
 654 
 655 static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
 656                                 const struct rockchip_pll_rate_table *rate)
 657 {
 658         const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
 659         struct clk_mux *pll_mux = &pll->pll_mux;
 660         struct rockchip_pll_rate_table cur;
 661         u32 pllcon;
 662         int rate_change_remuxed = 0;
 663         int cur_parent;
 664         int ret;
 665 
 666         pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
 667                 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
 668                 rate->postdiv2, rate->dsmpd, rate->frac);
 669 
 670         rockchip_rk3399_pll_get_params(pll, &cur);
 671         cur.rate = 0;
 672 
 673         cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
 674         if (cur_parent == PLL_MODE_NORM) {
 675                 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
 676                 rate_change_remuxed = 1;
 677         }
 678 
 679         /* update pll values */
 680         writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
 681                                                   RK3399_PLLCON0_FBDIV_SHIFT),
 682                        pll->reg_base + RK3399_PLLCON(0));
 683 
 684         writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,
 685                                                    RK3399_PLLCON1_REFDIV_SHIFT) |
 686                        HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,
 687                                                      RK3399_PLLCON1_POSTDIV1_SHIFT) |
 688                        HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,
 689                                                      RK3399_PLLCON1_POSTDIV2_SHIFT),
 690                        pll->reg_base + RK3399_PLLCON(1));
 691 
 692         /* xPLL CON2 is not HIWORD_MASK */
 693         pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
 694         pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
 695         pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
 696         writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));
 697 
 698         writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,
 699                                             RK3399_PLLCON3_DSMPD_SHIFT),
 700                        pll->reg_base + RK3399_PLLCON(3));
 701 
 702         /* wait for the pll to lock */
 703         ret = rockchip_rk3399_pll_wait_lock(pll);
 704         if (ret) {
 705                 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
 706                         __func__);
 707                 rockchip_rk3399_pll_set_params(pll, &cur);
 708         }
 709 
 710         if (rate_change_remuxed)
 711                 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
 712 
 713         return ret;
 714 }
 715 
 716 static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 717                                         unsigned long prate)
 718 {
 719         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 720         const struct rockchip_pll_rate_table *rate;
 721 
 722         pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
 723                  __func__, __clk_get_name(hw->clk), drate, prate);
 724 
 725         /* Get required rate settings from table */
 726         rate = rockchip_get_pll_settings(pll, drate);
 727         if (!rate) {
 728                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 729                         drate, __clk_get_name(hw->clk));
 730                 return -EINVAL;
 731         }
 732 
 733         return rockchip_rk3399_pll_set_params(pll, rate);
 734 }
 735 
 736 static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
 737 {
 738         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 739 
 740         writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),
 741                pll->reg_base + RK3399_PLLCON(3));
 742         rockchip_rk3399_pll_wait_lock(pll);
 743 
 744         return 0;
 745 }
 746 
 747 static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
 748 {
 749         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 750 
 751         writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
 752                              RK3399_PLLCON3_PWRDOWN, 0),
 753                pll->reg_base + RK3399_PLLCON(3));
 754 }
 755 
 756 static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
 757 {
 758         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 759         u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));
 760 
 761         return !(pllcon & RK3399_PLLCON3_PWRDOWN);
 762 }
 763 
 764 static void rockchip_rk3399_pll_init(struct clk_hw *hw)
 765 {
 766         struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 767         const struct rockchip_pll_rate_table *rate;
 768         struct rockchip_pll_rate_table cur;
 769         unsigned long drate;
 770 
 771         if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
 772                 return;
 773 
 774         drate = clk_hw_get_rate(hw);
 775         rate = rockchip_get_pll_settings(pll, drate);
 776 
 777         /* when no rate setting for the current rate, rely on clk_set_rate */
 778         if (!rate)
 779                 return;
 780 
 781         rockchip_rk3399_pll_get_params(pll, &cur);
 782 
 783         pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
 784                  drate);
 785         pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
 786                  cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
 787                  cur.dsmpd, cur.frac);
 788         pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
 789                  rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
 790                  rate->dsmpd, rate->frac);
 791 
 792         if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
 793                 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
 794                 rate->dsmpd != cur.dsmpd ||
 795                 (!cur.dsmpd && (rate->frac != cur.frac))) {
 796                 struct clk *parent = clk_get_parent(hw->clk);
 797 
 798                 if (!parent) {
 799                         pr_warn("%s: parent of %s not available\n",
 800                                 __func__, __clk_get_name(hw->clk));
 801                         return;
 802                 }
 803 
 804                 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
 805                          __func__, __clk_get_name(hw->clk));
 806                 rockchip_rk3399_pll_set_params(pll, rate);
 807         }
 808 }
 809 
 810 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
 811         .recalc_rate = rockchip_rk3399_pll_recalc_rate,
 812         .enable = rockchip_rk3399_pll_enable,
 813         .disable = rockchip_rk3399_pll_disable,
 814         .is_enabled = rockchip_rk3399_pll_is_enabled,
 815 };
 816 
 817 static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
 818         .recalc_rate = rockchip_rk3399_pll_recalc_rate,
 819         .round_rate = rockchip_pll_round_rate,
 820         .set_rate = rockchip_rk3399_pll_set_rate,
 821         .enable = rockchip_rk3399_pll_enable,
 822         .disable = rockchip_rk3399_pll_disable,
 823         .is_enabled = rockchip_rk3399_pll_is_enabled,
 824         .init = rockchip_rk3399_pll_init,
 825 };
 826 
 827 /*
 828  * Common registering of pll clocks
 829  */
 830 
 831 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
 832                 enum rockchip_pll_type pll_type,
 833                 const char *name, const char *const *parent_names,
 834                 u8 num_parents, int con_offset, int grf_lock_offset,
 835                 int lock_shift, int mode_offset, int mode_shift,
 836                 struct rockchip_pll_rate_table *rate_table,
 837                 unsigned long flags, u8 clk_pll_flags)
 838 {
 839         const char *pll_parents[3];
 840         struct clk_init_data init;
 841         struct rockchip_clk_pll *pll;
 842         struct clk_mux *pll_mux;
 843         struct clk *pll_clk, *mux_clk;
 844         char pll_name[20];
 845 
 846         if ((pll_type != pll_rk3328 && num_parents != 2) ||
 847             (pll_type == pll_rk3328 && num_parents != 1)) {
 848                 pr_err("%s: needs two parent clocks\n", __func__);
 849                 return ERR_PTR(-EINVAL);
 850         }
 851 
 852         /* name the actual pll */
 853         snprintf(pll_name, sizeof(pll_name), "pll_%s", name);
 854 
 855         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 856         if (!pll)
 857                 return ERR_PTR(-ENOMEM);
 858 
 859         /* create the mux on top of the real pll */
 860         pll->pll_mux_ops = &clk_mux_ops;
 861         pll_mux = &pll->pll_mux;
 862         pll_mux->reg = ctx->reg_base + mode_offset;
 863         pll_mux->shift = mode_shift;
 864         if (pll_type == pll_rk3328)
 865                 pll_mux->mask = PLL_RK3328_MODE_MASK;
 866         else
 867                 pll_mux->mask = PLL_MODE_MASK;
 868         pll_mux->flags = 0;
 869         pll_mux->lock = &ctx->lock;
 870         pll_mux->hw.init = &init;
 871 
 872         if (pll_type == pll_rk3036 ||
 873             pll_type == pll_rk3066 ||
 874             pll_type == pll_rk3328 ||
 875             pll_type == pll_rk3399)
 876                 pll_mux->flags |= CLK_MUX_HIWORD_MASK;
 877 
 878         /* the actual muxing is xin24m, pll-output, xin32k */
 879         pll_parents[0] = parent_names[0];
 880         pll_parents[1] = pll_name;
 881         pll_parents[2] = parent_names[1];
 882 
 883         init.name = name;
 884         init.flags = CLK_SET_RATE_PARENT;
 885         init.ops = pll->pll_mux_ops;
 886         init.parent_names = pll_parents;
 887         if (pll_type == pll_rk3328)
 888                 init.num_parents = 2;
 889         else
 890                 init.num_parents = ARRAY_SIZE(pll_parents);
 891 
 892         mux_clk = clk_register(NULL, &pll_mux->hw);
 893         if (IS_ERR(mux_clk))
 894                 goto err_mux;
 895 
 896         /* now create the actual pll */
 897         init.name = pll_name;
 898 
 899         /* keep all plls untouched for now */
 900         init.flags = flags | CLK_IGNORE_UNUSED;
 901 
 902         init.parent_names = &parent_names[0];
 903         init.num_parents = 1;
 904 
 905         if (rate_table) {
 906                 int len;
 907 
 908                 /* find count of rates in rate_table */
 909                 for (len = 0; rate_table[len].rate != 0; )
 910                         len++;
 911 
 912                 pll->rate_count = len;
 913                 pll->rate_table = kmemdup(rate_table,
 914                                         pll->rate_count *
 915                                         sizeof(struct rockchip_pll_rate_table),
 916                                         GFP_KERNEL);
 917                 WARN(!pll->rate_table,
 918                         "%s: could not allocate rate table for %s\n",
 919                         __func__, name);
 920         }
 921 
 922         switch (pll_type) {
 923         case pll_rk3036:
 924         case pll_rk3328:
 925                 if (!pll->rate_table || IS_ERR(ctx->grf))
 926                         init.ops = &rockchip_rk3036_pll_clk_norate_ops;
 927                 else
 928                         init.ops = &rockchip_rk3036_pll_clk_ops;
 929                 break;
 930         case pll_rk3066:
 931                 if (!pll->rate_table || IS_ERR(ctx->grf))
 932                         init.ops = &rockchip_rk3066_pll_clk_norate_ops;
 933                 else
 934                         init.ops = &rockchip_rk3066_pll_clk_ops;
 935                 break;
 936         case pll_rk3399:
 937                 if (!pll->rate_table)
 938                         init.ops = &rockchip_rk3399_pll_clk_norate_ops;
 939                 else
 940                         init.ops = &rockchip_rk3399_pll_clk_ops;
 941                 break;
 942         default:
 943                 pr_warn("%s: Unknown pll type for pll clk %s\n",
 944                         __func__, name);
 945         }
 946 
 947         pll->hw.init = &init;
 948         pll->type = pll_type;
 949         pll->reg_base = ctx->reg_base + con_offset;
 950         pll->lock_offset = grf_lock_offset;
 951         pll->lock_shift = lock_shift;
 952         pll->flags = clk_pll_flags;
 953         pll->lock = &ctx->lock;
 954         pll->ctx = ctx;
 955 
 956         pll_clk = clk_register(NULL, &pll->hw);
 957         if (IS_ERR(pll_clk)) {
 958                 pr_err("%s: failed to register pll clock %s : %ld\n",
 959                         __func__, name, PTR_ERR(pll_clk));
 960                 goto err_pll;
 961         }
 962 
 963         return mux_clk;
 964 
 965 err_pll:
 966         clk_unregister(mux_clk);
 967         mux_clk = pll_clk;
 968 err_mux:
 969         kfree(pll);
 970         return mux_clk;
 971 }

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