root/drivers/gpu/drm/omapdrm/dss/pll.c

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

DEFINITIONS

This source file includes following definitions.
  1. dss_pll_register
  2. dss_pll_unregister
  3. dss_pll_find
  4. dss_pll_find_by_src
  5. dss_pll_get_clkout_idx_for_src
  6. dss_pll_enable
  7. dss_pll_disable
  8. dss_pll_set_config
  9. dss_pll_hsdiv_calc_a
  10. dss_pll_calc_a
  11. dss_pll_calc_b
  12. wait_for_bit_change
  13. dss_pll_wait_reset_done
  14. dss_wait_hsdiv_ack
  15. pll_is_locked
  16. dss_pll_write_config_type_a
  17. dss_pll_write_config_type_b

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
   4  */
   5 
   6 #define DSS_SUBSYS_NAME "PLL"
   7 
   8 #include <linux/delay.h>
   9 #include <linux/clk.h>
  10 #include <linux/io.h>
  11 #include <linux/kernel.h>
  12 #include <linux/regulator/consumer.h>
  13 #include <linux/sched.h>
  14 
  15 #include "omapdss.h"
  16 #include "dss.h"
  17 
  18 #define PLL_CONTROL                     0x0000
  19 #define PLL_STATUS                      0x0004
  20 #define PLL_GO                          0x0008
  21 #define PLL_CONFIGURATION1              0x000C
  22 #define PLL_CONFIGURATION2              0x0010
  23 #define PLL_CONFIGURATION3              0x0014
  24 #define PLL_SSC_CONFIGURATION1          0x0018
  25 #define PLL_SSC_CONFIGURATION2          0x001C
  26 #define PLL_CONFIGURATION4              0x0020
  27 
  28 int dss_pll_register(struct dss_device *dss, struct dss_pll *pll)
  29 {
  30         int i;
  31 
  32         for (i = 0; i < ARRAY_SIZE(dss->plls); ++i) {
  33                 if (!dss->plls[i]) {
  34                         dss->plls[i] = pll;
  35                         pll->dss = dss;
  36                         return 0;
  37                 }
  38         }
  39 
  40         return -EBUSY;
  41 }
  42 
  43 void dss_pll_unregister(struct dss_pll *pll)
  44 {
  45         struct dss_device *dss = pll->dss;
  46         int i;
  47 
  48         for (i = 0; i < ARRAY_SIZE(dss->plls); ++i) {
  49                 if (dss->plls[i] == pll) {
  50                         dss->plls[i] = NULL;
  51                         pll->dss = NULL;
  52                         return;
  53                 }
  54         }
  55 }
  56 
  57 struct dss_pll *dss_pll_find(struct dss_device *dss, const char *name)
  58 {
  59         int i;
  60 
  61         for (i = 0; i < ARRAY_SIZE(dss->plls); ++i) {
  62                 if (dss->plls[i] && strcmp(dss->plls[i]->name, name) == 0)
  63                         return dss->plls[i];
  64         }
  65 
  66         return NULL;
  67 }
  68 
  69 struct dss_pll *dss_pll_find_by_src(struct dss_device *dss,
  70                                     enum dss_clk_source src)
  71 {
  72         struct dss_pll *pll;
  73 
  74         switch (src) {
  75         default:
  76         case DSS_CLK_SRC_FCK:
  77                 return NULL;
  78 
  79         case DSS_CLK_SRC_HDMI_PLL:
  80                 return dss_pll_find(dss, "hdmi");
  81 
  82         case DSS_CLK_SRC_PLL1_1:
  83         case DSS_CLK_SRC_PLL1_2:
  84         case DSS_CLK_SRC_PLL1_3:
  85                 pll = dss_pll_find(dss, "dsi0");
  86                 if (!pll)
  87                         pll = dss_pll_find(dss, "video0");
  88                 return pll;
  89 
  90         case DSS_CLK_SRC_PLL2_1:
  91         case DSS_CLK_SRC_PLL2_2:
  92         case DSS_CLK_SRC_PLL2_3:
  93                 pll = dss_pll_find(dss, "dsi1");
  94                 if (!pll)
  95                         pll = dss_pll_find(dss, "video1");
  96                 return pll;
  97         }
  98 }
  99 
 100 unsigned int dss_pll_get_clkout_idx_for_src(enum dss_clk_source src)
 101 {
 102         switch (src) {
 103         case DSS_CLK_SRC_HDMI_PLL:
 104                 return 0;
 105 
 106         case DSS_CLK_SRC_PLL1_1:
 107         case DSS_CLK_SRC_PLL2_1:
 108                 return 0;
 109 
 110         case DSS_CLK_SRC_PLL1_2:
 111         case DSS_CLK_SRC_PLL2_2:
 112                 return 1;
 113 
 114         case DSS_CLK_SRC_PLL1_3:
 115         case DSS_CLK_SRC_PLL2_3:
 116                 return 2;
 117 
 118         default:
 119                 return 0;
 120         }
 121 }
 122 
 123 int dss_pll_enable(struct dss_pll *pll)
 124 {
 125         int r;
 126 
 127         r = clk_prepare_enable(pll->clkin);
 128         if (r)
 129                 return r;
 130 
 131         if (pll->regulator) {
 132                 r = regulator_enable(pll->regulator);
 133                 if (r)
 134                         goto err_reg;
 135         }
 136 
 137         r = pll->ops->enable(pll);
 138         if (r)
 139                 goto err_enable;
 140 
 141         return 0;
 142 
 143 err_enable:
 144         if (pll->regulator)
 145                 regulator_disable(pll->regulator);
 146 err_reg:
 147         clk_disable_unprepare(pll->clkin);
 148         return r;
 149 }
 150 
 151 void dss_pll_disable(struct dss_pll *pll)
 152 {
 153         pll->ops->disable(pll);
 154 
 155         if (pll->regulator)
 156                 regulator_disable(pll->regulator);
 157 
 158         clk_disable_unprepare(pll->clkin);
 159 
 160         memset(&pll->cinfo, 0, sizeof(pll->cinfo));
 161 }
 162 
 163 int dss_pll_set_config(struct dss_pll *pll, const struct dss_pll_clock_info *cinfo)
 164 {
 165         int r;
 166 
 167         r = pll->ops->set_config(pll, cinfo);
 168         if (r)
 169                 return r;
 170 
 171         pll->cinfo = *cinfo;
 172 
 173         return 0;
 174 }
 175 
 176 bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco,
 177                 unsigned long out_min, unsigned long out_max,
 178                 dss_hsdiv_calc_func func, void *data)
 179 {
 180         const struct dss_pll_hw *hw = pll->hw;
 181         int m, m_start, m_stop;
 182         unsigned long out;
 183 
 184         out_min = out_min ? out_min : 1;
 185         out_max = out_max ? out_max : ULONG_MAX;
 186 
 187         m_start = max(DIV_ROUND_UP(clkdco, out_max), 1ul);
 188 
 189         m_stop = min((unsigned)(clkdco / out_min), hw->mX_max);
 190 
 191         for (m = m_start; m <= m_stop; ++m) {
 192                 out = clkdco / m;
 193 
 194                 if (func(m, out, data))
 195                         return true;
 196         }
 197 
 198         return false;
 199 }
 200 
 201 /*
 202  * clkdco = clkin / n * m * 2
 203  * clkoutX = clkdco / mX
 204  */
 205 bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
 206                 unsigned long pll_min, unsigned long pll_max,
 207                 dss_pll_calc_func func, void *data)
 208 {
 209         const struct dss_pll_hw *hw = pll->hw;
 210         int n, n_start, n_stop, n_inc;
 211         int m, m_start, m_stop, m_inc;
 212         unsigned long fint, clkdco;
 213         unsigned long pll_hw_max;
 214         unsigned long fint_hw_min, fint_hw_max;
 215 
 216         pll_hw_max = hw->clkdco_max;
 217 
 218         fint_hw_min = hw->fint_min;
 219         fint_hw_max = hw->fint_max;
 220 
 221         n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
 222         n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
 223         n_inc = 1;
 224 
 225         if (hw->errata_i886) {
 226                 swap(n_start, n_stop);
 227                 n_inc = -1;
 228         }
 229 
 230         pll_max = pll_max ? pll_max : ULONG_MAX;
 231 
 232         for (n = n_start; n != n_stop; n += n_inc) {
 233                 fint = clkin / n;
 234 
 235                 m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
 236                                 1ul);
 237                 m_stop = min3((unsigned)(pll_max / fint / 2),
 238                                 (unsigned)(pll_hw_max / fint / 2),
 239                                 hw->m_max);
 240                 m_inc = 1;
 241 
 242                 if (hw->errata_i886) {
 243                         swap(m_start, m_stop);
 244                         m_inc = -1;
 245                 }
 246 
 247                 for (m = m_start; m != m_stop; m += m_inc) {
 248                         clkdco = 2 * m * fint;
 249 
 250                         if (func(n, m, fint, clkdco, data))
 251                                 return true;
 252                 }
 253         }
 254 
 255         return false;
 256 }
 257 
 258 /*
 259  * This calculates a PLL config that will provide the target_clkout rate
 260  * for clkout. Additionally clkdco rate will be the same as clkout rate
 261  * when clkout rate is >= min_clkdco.
 262  *
 263  * clkdco = clkin / n * m + clkin / n * mf / 262144
 264  * clkout = clkdco / m2
 265  */
 266 bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin,
 267         unsigned long target_clkout, struct dss_pll_clock_info *cinfo)
 268 {
 269         unsigned long fint, clkdco, clkout;
 270         unsigned long target_clkdco;
 271         unsigned long min_dco;
 272         unsigned int n, m, mf, m2, sd;
 273         const struct dss_pll_hw *hw = pll->hw;
 274 
 275         DSSDBG("clkin %lu, target clkout %lu\n", clkin, target_clkout);
 276 
 277         /* Fint */
 278         n = DIV_ROUND_UP(clkin, hw->fint_max);
 279         fint = clkin / n;
 280 
 281         /* adjust m2 so that the clkdco will be high enough */
 282         min_dco = roundup(hw->clkdco_min, fint);
 283         m2 = DIV_ROUND_UP(min_dco, target_clkout);
 284         if (m2 == 0)
 285                 m2 = 1;
 286 
 287         target_clkdco = target_clkout * m2;
 288         m = target_clkdco / fint;
 289 
 290         clkdco = fint * m;
 291 
 292         /* adjust clkdco with fractional mf */
 293         if (WARN_ON(target_clkdco - clkdco > fint))
 294                 mf = 0;
 295         else
 296                 mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint);
 297 
 298         if (mf > 0)
 299                 clkdco += (u32)div_u64((u64)mf * fint, 262144);
 300 
 301         clkout = clkdco / m2;
 302 
 303         /* sigma-delta */
 304         sd = DIV_ROUND_UP(fint * m, 250000000);
 305 
 306         DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n",
 307                 n, m, mf, m2, sd);
 308         DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
 309 
 310         cinfo->n = n;
 311         cinfo->m = m;
 312         cinfo->mf = mf;
 313         cinfo->mX[0] = m2;
 314         cinfo->sd = sd;
 315 
 316         cinfo->fint = fint;
 317         cinfo->clkdco = clkdco;
 318         cinfo->clkout[0] = clkout;
 319 
 320         return true;
 321 }
 322 
 323 static int wait_for_bit_change(void __iomem *reg, int bitnum, int value)
 324 {
 325         unsigned long timeout;
 326         ktime_t wait;
 327         int t;
 328 
 329         /* first busyloop to see if the bit changes right away */
 330         t = 100;
 331         while (t-- > 0) {
 332                 if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) == value)
 333                         return value;
 334         }
 335 
 336         /* then loop for 500ms, sleeping for 1ms in between */
 337         timeout = jiffies + msecs_to_jiffies(500);
 338         while (time_before(jiffies, timeout)) {
 339                 if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) == value)
 340                         return value;
 341 
 342                 wait = ns_to_ktime(1000 * 1000);
 343                 set_current_state(TASK_UNINTERRUPTIBLE);
 344                 schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
 345         }
 346 
 347         return !value;
 348 }
 349 
 350 int dss_pll_wait_reset_done(struct dss_pll *pll)
 351 {
 352         void __iomem *base = pll->base;
 353 
 354         if (wait_for_bit_change(base + PLL_STATUS, 0, 1) != 1)
 355                 return -ETIMEDOUT;
 356         else
 357                 return 0;
 358 }
 359 
 360 static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask)
 361 {
 362         int t = 100;
 363 
 364         while (t-- > 0) {
 365                 u32 v = readl_relaxed(pll->base + PLL_STATUS);
 366                 v &= hsdiv_ack_mask;
 367                 if (v == hsdiv_ack_mask)
 368                         return 0;
 369         }
 370 
 371         return -ETIMEDOUT;
 372 }
 373 
 374 static bool pll_is_locked(u32 stat)
 375 {
 376         /*
 377          * Required value for each bitfield listed below
 378          *
 379          * PLL_STATUS[6] = 0  PLL_BYPASS
 380          * PLL_STATUS[5] = 0  PLL_HIGHJITTER
 381          *
 382          * PLL_STATUS[3] = 0  PLL_LOSSREF
 383          * PLL_STATUS[2] = 0  PLL_RECAL
 384          * PLL_STATUS[1] = 1  PLL_LOCK
 385          * PLL_STATUS[0] = 1  PLL_CTRL_RESET_DONE
 386          */
 387         return ((stat & 0x6f) == 0x3);
 388 }
 389 
 390 int dss_pll_write_config_type_a(struct dss_pll *pll,
 391                 const struct dss_pll_clock_info *cinfo)
 392 {
 393         const struct dss_pll_hw *hw = pll->hw;
 394         void __iomem *base = pll->base;
 395         int r = 0;
 396         u32 l;
 397 
 398         l = 0;
 399         if (hw->has_stopmode)
 400                 l = FLD_MOD(l, 1, 0, 0);                /* PLL_STOPMODE */
 401         l = FLD_MOD(l, cinfo->n - 1, hw->n_msb, hw->n_lsb);     /* PLL_REGN */
 402         l = FLD_MOD(l, cinfo->m, hw->m_msb, hw->m_lsb);         /* PLL_REGM */
 403         /* M4 */
 404         l = FLD_MOD(l, cinfo->mX[0] ? cinfo->mX[0] - 1 : 0,
 405                         hw->mX_msb[0], hw->mX_lsb[0]);
 406         /* M5 */
 407         l = FLD_MOD(l, cinfo->mX[1] ? cinfo->mX[1] - 1 : 0,
 408                         hw->mX_msb[1], hw->mX_lsb[1]);
 409         writel_relaxed(l, base + PLL_CONFIGURATION1);
 410 
 411         l = 0;
 412         /* M6 */
 413         l = FLD_MOD(l, cinfo->mX[2] ? cinfo->mX[2] - 1 : 0,
 414                         hw->mX_msb[2], hw->mX_lsb[2]);
 415         /* M7 */
 416         l = FLD_MOD(l, cinfo->mX[3] ? cinfo->mX[3] - 1 : 0,
 417                         hw->mX_msb[3], hw->mX_lsb[3]);
 418         writel_relaxed(l, base + PLL_CONFIGURATION3);
 419 
 420         l = readl_relaxed(base + PLL_CONFIGURATION2);
 421         if (hw->has_freqsel) {
 422                 u32 f = cinfo->fint < 1000000 ? 0x3 :
 423                         cinfo->fint < 1250000 ? 0x4 :
 424                         cinfo->fint < 1500000 ? 0x5 :
 425                         cinfo->fint < 1750000 ? 0x6 :
 426                         0x7;
 427 
 428                 l = FLD_MOD(l, f, 4, 1);        /* PLL_FREQSEL */
 429         } else if (hw->has_selfreqdco) {
 430                 u32 f = cinfo->clkdco < hw->clkdco_low ? 0x2 : 0x4;
 431 
 432                 l = FLD_MOD(l, f, 3, 1);        /* PLL_SELFREQDCO */
 433         }
 434         l = FLD_MOD(l, 1, 13, 13);              /* PLL_REFEN */
 435         l = FLD_MOD(l, 0, 14, 14);              /* PHY_CLKINEN */
 436         l = FLD_MOD(l, 0, 16, 16);              /* M4_CLOCK_EN */
 437         l = FLD_MOD(l, 0, 18, 18);              /* M5_CLOCK_EN */
 438         l = FLD_MOD(l, 1, 20, 20);              /* HSDIVBYPASS */
 439         if (hw->has_refsel)
 440                 l = FLD_MOD(l, 3, 22, 21);      /* REFSEL = sysclk */
 441         l = FLD_MOD(l, 0, 23, 23);              /* M6_CLOCK_EN */
 442         l = FLD_MOD(l, 0, 25, 25);              /* M7_CLOCK_EN */
 443         writel_relaxed(l, base + PLL_CONFIGURATION2);
 444 
 445         if (hw->errata_i932) {
 446                 int cnt = 0;
 447                 u32 sleep_time;
 448                 const u32 max_lock_retries = 20;
 449 
 450                 /*
 451                  * Calculate wait time for PLL LOCK
 452                  * 1000 REFCLK cycles in us.
 453                  */
 454                 sleep_time = DIV_ROUND_UP(1000*1000*1000, cinfo->fint);
 455 
 456                 for (cnt = 0; cnt < max_lock_retries; cnt++) {
 457                         writel_relaxed(1, base + PLL_GO);       /* PLL_GO */
 458 
 459                         /**
 460                          * read the register back to ensure the write is
 461                          * flushed
 462                          */
 463                         readl_relaxed(base + PLL_GO);
 464 
 465                         usleep_range(sleep_time, sleep_time + 5);
 466                         l = readl_relaxed(base + PLL_STATUS);
 467 
 468                         if (pll_is_locked(l) &&
 469                             !(readl_relaxed(base + PLL_GO) & 0x1))
 470                                 break;
 471 
 472                 }
 473 
 474                 if (cnt == max_lock_retries) {
 475                         DSSERR("cannot lock PLL\n");
 476                         r = -EIO;
 477                         goto err;
 478                 }
 479         } else {
 480                 writel_relaxed(1, base + PLL_GO);       /* PLL_GO */
 481 
 482                 if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
 483                         DSSERR("DSS DPLL GO bit not going down.\n");
 484                         r = -EIO;
 485                         goto err;
 486                 }
 487 
 488                 if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
 489                         DSSERR("cannot lock DSS DPLL\n");
 490                         r = -EIO;
 491                         goto err;
 492                 }
 493         }
 494 
 495         l = readl_relaxed(base + PLL_CONFIGURATION2);
 496         l = FLD_MOD(l, 1, 14, 14);                      /* PHY_CLKINEN */
 497         l = FLD_MOD(l, cinfo->mX[0] ? 1 : 0, 16, 16);   /* M4_CLOCK_EN */
 498         l = FLD_MOD(l, cinfo->mX[1] ? 1 : 0, 18, 18);   /* M5_CLOCK_EN */
 499         l = FLD_MOD(l, 0, 20, 20);                      /* HSDIVBYPASS */
 500         l = FLD_MOD(l, cinfo->mX[2] ? 1 : 0, 23, 23);   /* M6_CLOCK_EN */
 501         l = FLD_MOD(l, cinfo->mX[3] ? 1 : 0, 25, 25);   /* M7_CLOCK_EN */
 502         writel_relaxed(l, base + PLL_CONFIGURATION2);
 503 
 504         r = dss_wait_hsdiv_ack(pll,
 505                 (cinfo->mX[0] ? BIT(7) : 0) |
 506                 (cinfo->mX[1] ? BIT(8) : 0) |
 507                 (cinfo->mX[2] ? BIT(10) : 0) |
 508                 (cinfo->mX[3] ? BIT(11) : 0));
 509         if (r) {
 510                 DSSERR("failed to enable HSDIV clocks\n");
 511                 goto err;
 512         }
 513 
 514 err:
 515         return r;
 516 }
 517 
 518 int dss_pll_write_config_type_b(struct dss_pll *pll,
 519                 const struct dss_pll_clock_info *cinfo)
 520 {
 521         const struct dss_pll_hw *hw = pll->hw;
 522         void __iomem *base = pll->base;
 523         u32 l;
 524 
 525         l = 0;
 526         l = FLD_MOD(l, cinfo->m, 20, 9);        /* PLL_REGM */
 527         l = FLD_MOD(l, cinfo->n - 1, 8, 1);     /* PLL_REGN */
 528         writel_relaxed(l, base + PLL_CONFIGURATION1);
 529 
 530         l = readl_relaxed(base + PLL_CONFIGURATION2);
 531         l = FLD_MOD(l, 0x0, 12, 12);    /* PLL_HIGHFREQ divide by 2 */
 532         l = FLD_MOD(l, 0x1, 13, 13);    /* PLL_REFEN */
 533         l = FLD_MOD(l, 0x0, 14, 14);    /* PHY_CLKINEN */
 534         if (hw->has_refsel)
 535                 l = FLD_MOD(l, 0x3, 22, 21);    /* REFSEL = SYSCLK */
 536 
 537         /* PLL_SELFREQDCO */
 538         if (cinfo->clkdco > hw->clkdco_low)
 539                 l = FLD_MOD(l, 0x4, 3, 1);
 540         else
 541                 l = FLD_MOD(l, 0x2, 3, 1);
 542         writel_relaxed(l, base + PLL_CONFIGURATION2);
 543 
 544         l = readl_relaxed(base + PLL_CONFIGURATION3);
 545         l = FLD_MOD(l, cinfo->sd, 17, 10);      /* PLL_REGSD */
 546         writel_relaxed(l, base + PLL_CONFIGURATION3);
 547 
 548         l = readl_relaxed(base + PLL_CONFIGURATION4);
 549         l = FLD_MOD(l, cinfo->mX[0], 24, 18);   /* PLL_REGM2 */
 550         l = FLD_MOD(l, cinfo->mf, 17, 0);       /* PLL_REGM_F */
 551         writel_relaxed(l, base + PLL_CONFIGURATION4);
 552 
 553         writel_relaxed(1, base + PLL_GO);       /* PLL_GO */
 554 
 555         if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
 556                 DSSERR("DSS DPLL GO bit not going down.\n");
 557                 return -EIO;
 558         }
 559 
 560         if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
 561                 DSSERR("cannot lock DSS DPLL\n");
 562                 return -ETIMEDOUT;
 563         }
 564 
 565         return 0;
 566 }

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