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

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

DEFINITIONS

This source file includes following definitions.
  1. samsung_get_pll_settings
  2. samsung_pll_round_rate
  3. samsung_pll3xxx_enable
  4. samsung_pll3xxx_disable
  5. samsung_pll2126_recalc_rate
  6. samsung_pll3000_recalc_rate
  7. samsung_pll35xx_recalc_rate
  8. samsung_pll35xx_mp_change
  9. samsung_pll35xx_set_rate
  10. samsung_pll36xx_recalc_rate
  11. samsung_pll36xx_mpk_change
  12. samsung_pll36xx_set_rate
  13. samsung_pll45xx_recalc_rate
  14. samsung_pll45xx_mp_change
  15. samsung_pll45xx_set_rate
  16. samsung_pll46xx_recalc_rate
  17. samsung_pll46xx_mpk_change
  18. samsung_pll46xx_set_rate
  19. samsung_pll6552_recalc_rate
  20. samsung_pll6553_recalc_rate
  21. samsung_s3c2410_pll_recalc_rate
  22. samsung_s3c2440_mpll_recalc_rate
  23. samsung_s3c2410_pll_set_rate
  24. samsung_s3c2410_pll_enable
  25. samsung_s3c2410_mpll_enable
  26. samsung_s3c2410_mpll_disable
  27. samsung_s3c2410_upll_enable
  28. samsung_s3c2410_upll_disable
  29. samsung_pll2550x_recalc_rate
  30. samsung_pll2550xx_recalc_rate
  31. samsung_pll2550xx_mp_change
  32. samsung_pll2550xx_set_rate
  33. samsung_pll2650x_recalc_rate
  34. samsung_pll2650x_set_rate
  35. samsung_pll2650xx_recalc_rate
  36. samsung_pll2650xx_set_rate
  37. _samsung_clk_register_pll
  38. samsung_clk_register_pll

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
   4  * Copyright (c) 2013 Linaro Ltd.
   5  *
   6  * This file contains the utility functions to register the pll clocks.
   7 */
   8 
   9 #include <linux/errno.h>
  10 #include <linux/hrtimer.h>
  11 #include <linux/delay.h>
  12 #include <linux/slab.h>
  13 #include <linux/clk-provider.h>
  14 #include <linux/io.h>
  15 #include "clk.h"
  16 #include "clk-pll.h"
  17 
  18 #define PLL_TIMEOUT_MS          10
  19 
  20 struct samsung_clk_pll {
  21         struct clk_hw           hw;
  22         void __iomem            *lock_reg;
  23         void __iomem            *con_reg;
  24         /* PLL enable control bit offset in @con_reg register */
  25         unsigned short          enable_offs;
  26         /* PLL lock status bit offset in @con_reg register */
  27         unsigned short          lock_offs;
  28         enum samsung_pll_type   type;
  29         unsigned int            rate_count;
  30         const struct samsung_pll_rate_table *rate_table;
  31 };
  32 
  33 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
  34 
  35 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
  36                                 struct samsung_clk_pll *pll, unsigned long rate)
  37 {
  38         const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
  39         int i;
  40 
  41         for (i = 0; i < pll->rate_count; i++) {
  42                 if (rate == rate_table[i].rate)
  43                         return &rate_table[i];
  44         }
  45 
  46         return NULL;
  47 }
  48 
  49 static long samsung_pll_round_rate(struct clk_hw *hw,
  50                         unsigned long drate, unsigned long *prate)
  51 {
  52         struct samsung_clk_pll *pll = to_clk_pll(hw);
  53         const struct samsung_pll_rate_table *rate_table = pll->rate_table;
  54         int i;
  55 
  56         /* Assumming rate_table is in descending order */
  57         for (i = 0; i < pll->rate_count; i++) {
  58                 if (drate >= rate_table[i].rate)
  59                         return rate_table[i].rate;
  60         }
  61 
  62         /* return minimum supported value */
  63         return rate_table[i - 1].rate;
  64 }
  65 
  66 static int samsung_pll3xxx_enable(struct clk_hw *hw)
  67 {
  68         struct samsung_clk_pll *pll = to_clk_pll(hw);
  69         u32 tmp;
  70 
  71         tmp = readl_relaxed(pll->con_reg);
  72         tmp |= BIT(pll->enable_offs);
  73         writel_relaxed(tmp, pll->con_reg);
  74 
  75         /* wait lock time */
  76         do {
  77                 cpu_relax();
  78                 tmp = readl_relaxed(pll->con_reg);
  79         } while (!(tmp & BIT(pll->lock_offs)));
  80 
  81         return 0;
  82 }
  83 
  84 static void samsung_pll3xxx_disable(struct clk_hw *hw)
  85 {
  86         struct samsung_clk_pll *pll = to_clk_pll(hw);
  87         u32 tmp;
  88 
  89         tmp = readl_relaxed(pll->con_reg);
  90         tmp &= ~BIT(pll->enable_offs);
  91         writel_relaxed(tmp, pll->con_reg);
  92 }
  93 
  94 /*
  95  * PLL2126 Clock Type
  96  */
  97 
  98 #define PLL2126_MDIV_MASK       (0xff)
  99 #define PLL2126_PDIV_MASK       (0x3f)
 100 #define PLL2126_SDIV_MASK       (0x3)
 101 #define PLL2126_MDIV_SHIFT      (16)
 102 #define PLL2126_PDIV_SHIFT      (8)
 103 #define PLL2126_SDIV_SHIFT      (0)
 104 
 105 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
 106                                 unsigned long parent_rate)
 107 {
 108         struct samsung_clk_pll *pll = to_clk_pll(hw);
 109         u32 pll_con, mdiv, pdiv, sdiv;
 110         u64 fvco = parent_rate;
 111 
 112         pll_con = readl_relaxed(pll->con_reg);
 113         mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
 114         pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
 115         sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
 116 
 117         fvco *= (mdiv + 8);
 118         do_div(fvco, (pdiv + 2) << sdiv);
 119 
 120         return (unsigned long)fvco;
 121 }
 122 
 123 static const struct clk_ops samsung_pll2126_clk_ops = {
 124         .recalc_rate = samsung_pll2126_recalc_rate,
 125 };
 126 
 127 /*
 128  * PLL3000 Clock Type
 129  */
 130 
 131 #define PLL3000_MDIV_MASK       (0xff)
 132 #define PLL3000_PDIV_MASK       (0x3)
 133 #define PLL3000_SDIV_MASK       (0x3)
 134 #define PLL3000_MDIV_SHIFT      (16)
 135 #define PLL3000_PDIV_SHIFT      (8)
 136 #define PLL3000_SDIV_SHIFT      (0)
 137 
 138 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
 139                                 unsigned long parent_rate)
 140 {
 141         struct samsung_clk_pll *pll = to_clk_pll(hw);
 142         u32 pll_con, mdiv, pdiv, sdiv;
 143         u64 fvco = parent_rate;
 144 
 145         pll_con = readl_relaxed(pll->con_reg);
 146         mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
 147         pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
 148         sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
 149 
 150         fvco *= (2 * (mdiv + 8));
 151         do_div(fvco, pdiv << sdiv);
 152 
 153         return (unsigned long)fvco;
 154 }
 155 
 156 static const struct clk_ops samsung_pll3000_clk_ops = {
 157         .recalc_rate = samsung_pll3000_recalc_rate,
 158 };
 159 
 160 /*
 161  * PLL35xx Clock Type
 162  */
 163 /* Maximum lock time can be 270 * PDIV cycles */
 164 #define PLL35XX_LOCK_FACTOR     (270)
 165 
 166 #define PLL35XX_MDIV_MASK       (0x3FF)
 167 #define PLL35XX_PDIV_MASK       (0x3F)
 168 #define PLL35XX_SDIV_MASK       (0x7)
 169 #define PLL35XX_MDIV_SHIFT      (16)
 170 #define PLL35XX_PDIV_SHIFT      (8)
 171 #define PLL35XX_SDIV_SHIFT      (0)
 172 #define PLL35XX_LOCK_STAT_SHIFT (29)
 173 #define PLL35XX_ENABLE_SHIFT    (31)
 174 
 175 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 176                                 unsigned long parent_rate)
 177 {
 178         struct samsung_clk_pll *pll = to_clk_pll(hw);
 179         u32 mdiv, pdiv, sdiv, pll_con;
 180         u64 fvco = parent_rate;
 181 
 182         pll_con = readl_relaxed(pll->con_reg);
 183         mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
 184         pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
 185         sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
 186 
 187         fvco *= mdiv;
 188         do_div(fvco, (pdiv << sdiv));
 189 
 190         return (unsigned long)fvco;
 191 }
 192 
 193 static inline bool samsung_pll35xx_mp_change(
 194                 const struct samsung_pll_rate_table *rate, u32 pll_con)
 195 {
 196         u32 old_mdiv, old_pdiv;
 197 
 198         old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
 199         old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
 200 
 201         return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
 202 }
 203 
 204 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
 205                                         unsigned long prate)
 206 {
 207         struct samsung_clk_pll *pll = to_clk_pll(hw);
 208         const struct samsung_pll_rate_table *rate;
 209         u32 tmp;
 210 
 211         /* Get required rate settings from table */
 212         rate = samsung_get_pll_settings(pll, drate);
 213         if (!rate) {
 214                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 215                         drate, clk_hw_get_name(hw));
 216                 return -EINVAL;
 217         }
 218 
 219         tmp = readl_relaxed(pll->con_reg);
 220 
 221         if (!(samsung_pll35xx_mp_change(rate, tmp))) {
 222                 /* If only s change, change just s value only*/
 223                 tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
 224                 tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
 225                 writel_relaxed(tmp, pll->con_reg);
 226 
 227                 return 0;
 228         }
 229 
 230         /* Set PLL lock time. */
 231         writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
 232                         pll->lock_reg);
 233 
 234         /* Change PLL PMS values */
 235         tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
 236                         (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
 237                         (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
 238         tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
 239                         (rate->pdiv << PLL35XX_PDIV_SHIFT) |
 240                         (rate->sdiv << PLL35XX_SDIV_SHIFT);
 241         writel_relaxed(tmp, pll->con_reg);
 242 
 243         /* Wait until the PLL is locked if it is enabled. */
 244         if (tmp & BIT(pll->enable_offs)) {
 245                 do {
 246                         cpu_relax();
 247                         tmp = readl_relaxed(pll->con_reg);
 248                 } while (!(tmp & BIT(pll->lock_offs)));
 249         }
 250         return 0;
 251 }
 252 
 253 static const struct clk_ops samsung_pll35xx_clk_ops = {
 254         .recalc_rate = samsung_pll35xx_recalc_rate,
 255         .round_rate = samsung_pll_round_rate,
 256         .set_rate = samsung_pll35xx_set_rate,
 257         .enable = samsung_pll3xxx_enable,
 258         .disable = samsung_pll3xxx_disable,
 259 };
 260 
 261 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
 262         .recalc_rate = samsung_pll35xx_recalc_rate,
 263 };
 264 
 265 /*
 266  * PLL36xx Clock Type
 267  */
 268 /* Maximum lock time can be 3000 * PDIV cycles */
 269 #define PLL36XX_LOCK_FACTOR    (3000)
 270 
 271 #define PLL36XX_KDIV_MASK       (0xFFFF)
 272 #define PLL36XX_MDIV_MASK       (0x1FF)
 273 #define PLL36XX_PDIV_MASK       (0x3F)
 274 #define PLL36XX_SDIV_MASK       (0x7)
 275 #define PLL36XX_MDIV_SHIFT      (16)
 276 #define PLL36XX_PDIV_SHIFT      (8)
 277 #define PLL36XX_SDIV_SHIFT      (0)
 278 #define PLL36XX_KDIV_SHIFT      (0)
 279 #define PLL36XX_LOCK_STAT_SHIFT (29)
 280 #define PLL36XX_ENABLE_SHIFT    (31)
 281 
 282 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 283                                 unsigned long parent_rate)
 284 {
 285         struct samsung_clk_pll *pll = to_clk_pll(hw);
 286         u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
 287         s16 kdiv;
 288         u64 fvco = parent_rate;
 289 
 290         pll_con0 = readl_relaxed(pll->con_reg);
 291         pll_con1 = readl_relaxed(pll->con_reg + 4);
 292         mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
 293         pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
 294         sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
 295         kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
 296 
 297         fvco *= (mdiv << 16) + kdiv;
 298         do_div(fvco, (pdiv << sdiv));
 299         fvco >>= 16;
 300 
 301         return (unsigned long)fvco;
 302 }
 303 
 304 static inline bool samsung_pll36xx_mpk_change(
 305         const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
 306 {
 307         u32 old_mdiv, old_pdiv, old_kdiv;
 308 
 309         old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
 310         old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
 311         old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
 312 
 313         return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
 314                 rate->kdiv != old_kdiv);
 315 }
 316 
 317 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
 318                                         unsigned long parent_rate)
 319 {
 320         struct samsung_clk_pll *pll = to_clk_pll(hw);
 321         u32 tmp, pll_con0, pll_con1;
 322         const struct samsung_pll_rate_table *rate;
 323 
 324         rate = samsung_get_pll_settings(pll, drate);
 325         if (!rate) {
 326                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 327                         drate, clk_hw_get_name(hw));
 328                 return -EINVAL;
 329         }
 330 
 331         pll_con0 = readl_relaxed(pll->con_reg);
 332         pll_con1 = readl_relaxed(pll->con_reg + 4);
 333 
 334         if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
 335                 /* If only s change, change just s value only*/
 336                 pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
 337                 pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
 338                 writel_relaxed(pll_con0, pll->con_reg);
 339 
 340                 return 0;
 341         }
 342 
 343         /* Set PLL lock time. */
 344         writel_relaxed(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
 345 
 346          /* Change PLL PMS values */
 347         pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
 348                         (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
 349                         (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
 350         pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
 351                         (rate->pdiv << PLL36XX_PDIV_SHIFT) |
 352                         (rate->sdiv << PLL36XX_SDIV_SHIFT);
 353         writel_relaxed(pll_con0, pll->con_reg);
 354 
 355         pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
 356         pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
 357         writel_relaxed(pll_con1, pll->con_reg + 4);
 358 
 359         /* wait_lock_time */
 360         if (pll_con0 & BIT(pll->enable_offs)) {
 361                 do {
 362                         cpu_relax();
 363                         tmp = readl_relaxed(pll->con_reg);
 364                 } while (!(tmp & BIT(pll->lock_offs)));
 365         }
 366 
 367         return 0;
 368 }
 369 
 370 static const struct clk_ops samsung_pll36xx_clk_ops = {
 371         .recalc_rate = samsung_pll36xx_recalc_rate,
 372         .set_rate = samsung_pll36xx_set_rate,
 373         .round_rate = samsung_pll_round_rate,
 374         .enable = samsung_pll3xxx_enable,
 375         .disable = samsung_pll3xxx_disable,
 376 };
 377 
 378 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 379         .recalc_rate = samsung_pll36xx_recalc_rate,
 380 };
 381 
 382 /*
 383  * PLL45xx Clock Type
 384  */
 385 #define PLL4502_LOCK_FACTOR     400
 386 #define PLL4508_LOCK_FACTOR     240
 387 
 388 #define PLL45XX_MDIV_MASK       (0x3FF)
 389 #define PLL45XX_PDIV_MASK       (0x3F)
 390 #define PLL45XX_SDIV_MASK       (0x7)
 391 #define PLL45XX_AFC_MASK        (0x1F)
 392 #define PLL45XX_MDIV_SHIFT      (16)
 393 #define PLL45XX_PDIV_SHIFT      (8)
 394 #define PLL45XX_SDIV_SHIFT      (0)
 395 #define PLL45XX_AFC_SHIFT       (0)
 396 
 397 #define PLL45XX_ENABLE          BIT(31)
 398 #define PLL45XX_LOCKED          BIT(29)
 399 
 400 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
 401                                 unsigned long parent_rate)
 402 {
 403         struct samsung_clk_pll *pll = to_clk_pll(hw);
 404         u32 mdiv, pdiv, sdiv, pll_con;
 405         u64 fvco = parent_rate;
 406 
 407         pll_con = readl_relaxed(pll->con_reg);
 408         mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
 409         pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
 410         sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
 411 
 412         if (pll->type == pll_4508)
 413                 sdiv = sdiv - 1;
 414 
 415         fvco *= mdiv;
 416         do_div(fvco, (pdiv << sdiv));
 417 
 418         return (unsigned long)fvco;
 419 }
 420 
 421 static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
 422                                 const struct samsung_pll_rate_table *rate)
 423 {
 424         u32 old_mdiv, old_pdiv, old_afc;
 425 
 426         old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
 427         old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
 428         old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
 429 
 430         return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
 431                 || old_afc != rate->afc);
 432 }
 433 
 434 static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
 435                                         unsigned long prate)
 436 {
 437         struct samsung_clk_pll *pll = to_clk_pll(hw);
 438         const struct samsung_pll_rate_table *rate;
 439         u32 con0, con1;
 440         ktime_t start;
 441 
 442         /* Get required rate settings from table */
 443         rate = samsung_get_pll_settings(pll, drate);
 444         if (!rate) {
 445                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 446                         drate, clk_hw_get_name(hw));
 447                 return -EINVAL;
 448         }
 449 
 450         con0 = readl_relaxed(pll->con_reg);
 451         con1 = readl_relaxed(pll->con_reg + 0x4);
 452 
 453         if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
 454                 /* If only s change, change just s value only*/
 455                 con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
 456                 con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
 457                 writel_relaxed(con0, pll->con_reg);
 458 
 459                 return 0;
 460         }
 461 
 462         /* Set PLL PMS values. */
 463         con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
 464                         (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
 465                         (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
 466         con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
 467                         (rate->pdiv << PLL45XX_PDIV_SHIFT) |
 468                         (rate->sdiv << PLL45XX_SDIV_SHIFT);
 469 
 470         /* Set PLL AFC value. */
 471         con1 = readl_relaxed(pll->con_reg + 0x4);
 472         con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
 473         con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
 474 
 475         /* Set PLL lock time. */
 476         switch (pll->type) {
 477         case pll_4502:
 478                 writel_relaxed(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
 479                 break;
 480         case pll_4508:
 481                 writel_relaxed(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
 482                 break;
 483         default:
 484                 break;
 485         }
 486 
 487         /* Set new configuration. */
 488         writel_relaxed(con1, pll->con_reg + 0x4);
 489         writel_relaxed(con0, pll->con_reg);
 490 
 491         /* Wait for locking. */
 492         start = ktime_get();
 493         while (!(readl_relaxed(pll->con_reg) & PLL45XX_LOCKED)) {
 494                 ktime_t delta = ktime_sub(ktime_get(), start);
 495 
 496                 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
 497                         pr_err("%s: could not lock PLL %s\n",
 498                                         __func__, clk_hw_get_name(hw));
 499                         return -EFAULT;
 500                 }
 501 
 502                 cpu_relax();
 503         }
 504 
 505         return 0;
 506 }
 507 
 508 static const struct clk_ops samsung_pll45xx_clk_ops = {
 509         .recalc_rate = samsung_pll45xx_recalc_rate,
 510         .round_rate = samsung_pll_round_rate,
 511         .set_rate = samsung_pll45xx_set_rate,
 512 };
 513 
 514 static const struct clk_ops samsung_pll45xx_clk_min_ops = {
 515         .recalc_rate = samsung_pll45xx_recalc_rate,
 516 };
 517 
 518 /*
 519  * PLL46xx Clock Type
 520  */
 521 #define PLL46XX_LOCK_FACTOR     3000
 522 
 523 #define PLL46XX_VSEL_MASK       (1)
 524 #define PLL46XX_MDIV_MASK       (0x1FF)
 525 #define PLL1460X_MDIV_MASK      (0x3FF)
 526 
 527 #define PLL46XX_PDIV_MASK       (0x3F)
 528 #define PLL46XX_SDIV_MASK       (0x7)
 529 #define PLL46XX_VSEL_SHIFT      (27)
 530 #define PLL46XX_MDIV_SHIFT      (16)
 531 #define PLL46XX_PDIV_SHIFT      (8)
 532 #define PLL46XX_SDIV_SHIFT      (0)
 533 
 534 #define PLL46XX_KDIV_MASK       (0xFFFF)
 535 #define PLL4650C_KDIV_MASK      (0xFFF)
 536 #define PLL46XX_KDIV_SHIFT      (0)
 537 #define PLL46XX_MFR_MASK        (0x3F)
 538 #define PLL46XX_MRR_MASK        (0x1F)
 539 #define PLL46XX_KDIV_SHIFT      (0)
 540 #define PLL46XX_MFR_SHIFT       (16)
 541 #define PLL46XX_MRR_SHIFT       (24)
 542 
 543 #define PLL46XX_ENABLE          BIT(31)
 544 #define PLL46XX_LOCKED          BIT(29)
 545 #define PLL46XX_VSEL            BIT(27)
 546 
 547 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
 548                                 unsigned long parent_rate)
 549 {
 550         struct samsung_clk_pll *pll = to_clk_pll(hw);
 551         u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
 552         u64 fvco = parent_rate;
 553 
 554         pll_con0 = readl_relaxed(pll->con_reg);
 555         pll_con1 = readl_relaxed(pll->con_reg + 4);
 556         mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
 557                                 PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
 558         pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
 559         sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
 560         kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
 561                                         pll_con1 & PLL46XX_KDIV_MASK;
 562 
 563         shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
 564 
 565         fvco *= (mdiv << shift) + kdiv;
 566         do_div(fvco, (pdiv << sdiv));
 567         fvco >>= shift;
 568 
 569         return (unsigned long)fvco;
 570 }
 571 
 572 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
 573                                 const struct samsung_pll_rate_table *rate)
 574 {
 575         u32 old_mdiv, old_pdiv, old_kdiv;
 576 
 577         old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
 578         old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
 579         old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
 580 
 581         return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
 582                 || old_kdiv != rate->kdiv);
 583 }
 584 
 585 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
 586                                         unsigned long prate)
 587 {
 588         struct samsung_clk_pll *pll = to_clk_pll(hw);
 589         const struct samsung_pll_rate_table *rate;
 590         u32 con0, con1, lock;
 591         ktime_t start;
 592 
 593         /* Get required rate settings from table */
 594         rate = samsung_get_pll_settings(pll, drate);
 595         if (!rate) {
 596                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 597                         drate, clk_hw_get_name(hw));
 598                 return -EINVAL;
 599         }
 600 
 601         con0 = readl_relaxed(pll->con_reg);
 602         con1 = readl_relaxed(pll->con_reg + 0x4);
 603 
 604         if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
 605                 /* If only s change, change just s value only*/
 606                 con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
 607                 con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
 608                 writel_relaxed(con0, pll->con_reg);
 609 
 610                 return 0;
 611         }
 612 
 613         /* Set PLL lock time. */
 614         lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
 615         if (lock > 0xffff)
 616                 /* Maximum lock time bitfield is 16-bit. */
 617                 lock = 0xffff;
 618 
 619         /* Set PLL PMS and VSEL values. */
 620         if (pll->type == pll_1460x) {
 621                 con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
 622                         (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
 623                         (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
 624         } else {
 625                 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
 626                         (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
 627                         (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
 628                         (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
 629                 con0 |= rate->vsel << PLL46XX_VSEL_SHIFT;
 630         }
 631 
 632         con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
 633                         (rate->pdiv << PLL46XX_PDIV_SHIFT) |
 634                         (rate->sdiv << PLL46XX_SDIV_SHIFT);
 635 
 636         /* Set PLL K, MFR and MRR values. */
 637         con1 = readl_relaxed(pll->con_reg + 0x4);
 638         con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
 639                         (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
 640                         (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
 641         con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
 642                         (rate->mfr << PLL46XX_MFR_SHIFT) |
 643                         (rate->mrr << PLL46XX_MRR_SHIFT);
 644 
 645         /* Write configuration to PLL */
 646         writel_relaxed(lock, pll->lock_reg);
 647         writel_relaxed(con0, pll->con_reg);
 648         writel_relaxed(con1, pll->con_reg + 0x4);
 649 
 650         /* Wait for locking. */
 651         start = ktime_get();
 652         while (!(readl_relaxed(pll->con_reg) & PLL46XX_LOCKED)) {
 653                 ktime_t delta = ktime_sub(ktime_get(), start);
 654 
 655                 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
 656                         pr_err("%s: could not lock PLL %s\n",
 657                                         __func__, clk_hw_get_name(hw));
 658                         return -EFAULT;
 659                 }
 660 
 661                 cpu_relax();
 662         }
 663 
 664         return 0;
 665 }
 666 
 667 static const struct clk_ops samsung_pll46xx_clk_ops = {
 668         .recalc_rate = samsung_pll46xx_recalc_rate,
 669         .round_rate = samsung_pll_round_rate,
 670         .set_rate = samsung_pll46xx_set_rate,
 671 };
 672 
 673 static const struct clk_ops samsung_pll46xx_clk_min_ops = {
 674         .recalc_rate = samsung_pll46xx_recalc_rate,
 675 };
 676 
 677 /*
 678  * PLL6552 Clock Type
 679  */
 680 
 681 #define PLL6552_MDIV_MASK       0x3ff
 682 #define PLL6552_PDIV_MASK       0x3f
 683 #define PLL6552_SDIV_MASK       0x7
 684 #define PLL6552_MDIV_SHIFT      16
 685 #define PLL6552_MDIV_SHIFT_2416 14
 686 #define PLL6552_PDIV_SHIFT      8
 687 #define PLL6552_PDIV_SHIFT_2416 5
 688 #define PLL6552_SDIV_SHIFT      0
 689 
 690 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
 691                                                 unsigned long parent_rate)
 692 {
 693         struct samsung_clk_pll *pll = to_clk_pll(hw);
 694         u32 mdiv, pdiv, sdiv, pll_con;
 695         u64 fvco = parent_rate;
 696 
 697         pll_con = readl_relaxed(pll->con_reg);
 698         if (pll->type == pll_6552_s3c2416) {
 699                 mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
 700                 pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
 701         } else {
 702                 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
 703                 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
 704         }
 705         sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
 706 
 707         fvco *= mdiv;
 708         do_div(fvco, (pdiv << sdiv));
 709 
 710         return (unsigned long)fvco;
 711 }
 712 
 713 static const struct clk_ops samsung_pll6552_clk_ops = {
 714         .recalc_rate = samsung_pll6552_recalc_rate,
 715 };
 716 
 717 /*
 718  * PLL6553 Clock Type
 719  */
 720 
 721 #define PLL6553_MDIV_MASK       0xff
 722 #define PLL6553_PDIV_MASK       0x3f
 723 #define PLL6553_SDIV_MASK       0x7
 724 #define PLL6553_KDIV_MASK       0xffff
 725 #define PLL6553_MDIV_SHIFT      16
 726 #define PLL6553_PDIV_SHIFT      8
 727 #define PLL6553_SDIV_SHIFT      0
 728 #define PLL6553_KDIV_SHIFT      0
 729 
 730 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
 731                                                 unsigned long parent_rate)
 732 {
 733         struct samsung_clk_pll *pll = to_clk_pll(hw);
 734         u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
 735         u64 fvco = parent_rate;
 736 
 737         pll_con0 = readl_relaxed(pll->con_reg);
 738         pll_con1 = readl_relaxed(pll->con_reg + 0x4);
 739         mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
 740         pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
 741         sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
 742         kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
 743 
 744         fvco *= (mdiv << 16) + kdiv;
 745         do_div(fvco, (pdiv << sdiv));
 746         fvco >>= 16;
 747 
 748         return (unsigned long)fvco;
 749 }
 750 
 751 static const struct clk_ops samsung_pll6553_clk_ops = {
 752         .recalc_rate = samsung_pll6553_recalc_rate,
 753 };
 754 
 755 /*
 756  * PLL Clock Type of S3C24XX before S3C2443
 757  */
 758 
 759 #define PLLS3C2410_MDIV_MASK            (0xff)
 760 #define PLLS3C2410_PDIV_MASK            (0x1f)
 761 #define PLLS3C2410_SDIV_MASK            (0x3)
 762 #define PLLS3C2410_MDIV_SHIFT           (12)
 763 #define PLLS3C2410_PDIV_SHIFT           (4)
 764 #define PLLS3C2410_SDIV_SHIFT           (0)
 765 
 766 #define PLLS3C2410_ENABLE_REG_OFFSET    0x10
 767 
 768 static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
 769                                         unsigned long parent_rate)
 770 {
 771         struct samsung_clk_pll *pll = to_clk_pll(hw);
 772         u32 pll_con, mdiv, pdiv, sdiv;
 773         u64 fvco = parent_rate;
 774 
 775         pll_con = readl_relaxed(pll->con_reg);
 776         mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
 777         pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
 778         sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
 779 
 780         fvco *= (mdiv + 8);
 781         do_div(fvco, (pdiv + 2) << sdiv);
 782 
 783         return (unsigned int)fvco;
 784 }
 785 
 786 static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
 787                                         unsigned long parent_rate)
 788 {
 789         struct samsung_clk_pll *pll = to_clk_pll(hw);
 790         u32 pll_con, mdiv, pdiv, sdiv;
 791         u64 fvco = parent_rate;
 792 
 793         pll_con = readl_relaxed(pll->con_reg);
 794         mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
 795         pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
 796         sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
 797 
 798         fvco *= (2 * (mdiv + 8));
 799         do_div(fvco, (pdiv + 2) << sdiv);
 800 
 801         return (unsigned int)fvco;
 802 }
 803 
 804 static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 805                                         unsigned long prate)
 806 {
 807         struct samsung_clk_pll *pll = to_clk_pll(hw);
 808         const struct samsung_pll_rate_table *rate;
 809         u32 tmp;
 810 
 811         /* Get required rate settings from table */
 812         rate = samsung_get_pll_settings(pll, drate);
 813         if (!rate) {
 814                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 815                         drate, clk_hw_get_name(hw));
 816                 return -EINVAL;
 817         }
 818 
 819         tmp = readl_relaxed(pll->con_reg);
 820 
 821         /* Change PLL PMS values */
 822         tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
 823                         (PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
 824                         (PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
 825         tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
 826                         (rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
 827                         (rate->sdiv << PLLS3C2410_SDIV_SHIFT);
 828         writel_relaxed(tmp, pll->con_reg);
 829 
 830         /* Time to settle according to the manual */
 831         udelay(300);
 832 
 833         return 0;
 834 }
 835 
 836 static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
 837 {
 838         struct samsung_clk_pll *pll = to_clk_pll(hw);
 839         u32 pll_en = readl_relaxed(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
 840         u32 pll_en_orig = pll_en;
 841 
 842         if (enable)
 843                 pll_en &= ~BIT(bit);
 844         else
 845                 pll_en |= BIT(bit);
 846 
 847         writel_relaxed(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
 848 
 849         /* if we started the UPLL, then allow to settle */
 850         if (enable && (pll_en_orig & BIT(bit)))
 851                 udelay(300);
 852 
 853         return 0;
 854 }
 855 
 856 static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
 857 {
 858         return samsung_s3c2410_pll_enable(hw, 5, true);
 859 }
 860 
 861 static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
 862 {
 863         samsung_s3c2410_pll_enable(hw, 5, false);
 864 }
 865 
 866 static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
 867 {
 868         return samsung_s3c2410_pll_enable(hw, 7, true);
 869 }
 870 
 871 static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
 872 {
 873         samsung_s3c2410_pll_enable(hw, 7, false);
 874 }
 875 
 876 static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
 877         .recalc_rate = samsung_s3c2410_pll_recalc_rate,
 878         .enable = samsung_s3c2410_mpll_enable,
 879         .disable = samsung_s3c2410_mpll_disable,
 880 };
 881 
 882 static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
 883         .recalc_rate = samsung_s3c2410_pll_recalc_rate,
 884         .enable = samsung_s3c2410_upll_enable,
 885         .disable = samsung_s3c2410_upll_disable,
 886 };
 887 
 888 static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
 889         .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
 890         .enable = samsung_s3c2410_mpll_enable,
 891         .disable = samsung_s3c2410_mpll_disable,
 892 };
 893 
 894 static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
 895         .recalc_rate = samsung_s3c2410_pll_recalc_rate,
 896         .enable = samsung_s3c2410_mpll_enable,
 897         .disable = samsung_s3c2410_mpll_disable,
 898         .round_rate = samsung_pll_round_rate,
 899         .set_rate = samsung_s3c2410_pll_set_rate,
 900 };
 901 
 902 static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
 903         .recalc_rate = samsung_s3c2410_pll_recalc_rate,
 904         .enable = samsung_s3c2410_upll_enable,
 905         .disable = samsung_s3c2410_upll_disable,
 906         .round_rate = samsung_pll_round_rate,
 907         .set_rate = samsung_s3c2410_pll_set_rate,
 908 };
 909 
 910 static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
 911         .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
 912         .enable = samsung_s3c2410_mpll_enable,
 913         .disable = samsung_s3c2410_mpll_disable,
 914         .round_rate = samsung_pll_round_rate,
 915         .set_rate = samsung_s3c2410_pll_set_rate,
 916 };
 917 
 918 /*
 919  * PLL2550x Clock Type
 920  */
 921 
 922 #define PLL2550X_R_MASK       (0x1)
 923 #define PLL2550X_P_MASK       (0x3F)
 924 #define PLL2550X_M_MASK       (0x3FF)
 925 #define PLL2550X_S_MASK       (0x7)
 926 #define PLL2550X_R_SHIFT      (20)
 927 #define PLL2550X_P_SHIFT      (14)
 928 #define PLL2550X_M_SHIFT      (4)
 929 #define PLL2550X_S_SHIFT      (0)
 930 
 931 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
 932                                 unsigned long parent_rate)
 933 {
 934         struct samsung_clk_pll *pll = to_clk_pll(hw);
 935         u32 r, p, m, s, pll_stat;
 936         u64 fvco = parent_rate;
 937 
 938         pll_stat = readl_relaxed(pll->con_reg);
 939         r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
 940         if (!r)
 941                 return 0;
 942         p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
 943         m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
 944         s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
 945 
 946         fvco *= m;
 947         do_div(fvco, (p << s));
 948 
 949         return (unsigned long)fvco;
 950 }
 951 
 952 static const struct clk_ops samsung_pll2550x_clk_ops = {
 953         .recalc_rate = samsung_pll2550x_recalc_rate,
 954 };
 955 
 956 /*
 957  * PLL2550xx Clock Type
 958  */
 959 
 960 /* Maximum lock time can be 270 * PDIV cycles */
 961 #define PLL2550XX_LOCK_FACTOR 270
 962 
 963 #define PLL2550XX_M_MASK                0x3FF
 964 #define PLL2550XX_P_MASK                0x3F
 965 #define PLL2550XX_S_MASK                0x7
 966 #define PLL2550XX_LOCK_STAT_MASK        0x1
 967 #define PLL2550XX_M_SHIFT               9
 968 #define PLL2550XX_P_SHIFT               3
 969 #define PLL2550XX_S_SHIFT               0
 970 #define PLL2550XX_LOCK_STAT_SHIFT       21
 971 
 972 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
 973                                 unsigned long parent_rate)
 974 {
 975         struct samsung_clk_pll *pll = to_clk_pll(hw);
 976         u32 mdiv, pdiv, sdiv, pll_con;
 977         u64 fvco = parent_rate;
 978 
 979         pll_con = readl_relaxed(pll->con_reg);
 980         mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
 981         pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
 982         sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
 983 
 984         fvco *= mdiv;
 985         do_div(fvco, (pdiv << sdiv));
 986 
 987         return (unsigned long)fvco;
 988 }
 989 
 990 static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
 991 {
 992         u32 old_mdiv, old_pdiv;
 993 
 994         old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
 995         old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
 996 
 997         return mdiv != old_mdiv || pdiv != old_pdiv;
 998 }
 999 
1000 static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
1001                                         unsigned long prate)
1002 {
1003         struct samsung_clk_pll *pll = to_clk_pll(hw);
1004         const struct samsung_pll_rate_table *rate;
1005         u32 tmp;
1006 
1007         /* Get required rate settings from table */
1008         rate = samsung_get_pll_settings(pll, drate);
1009         if (!rate) {
1010                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1011                         drate, clk_hw_get_name(hw));
1012                 return -EINVAL;
1013         }
1014 
1015         tmp = readl_relaxed(pll->con_reg);
1016 
1017         if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
1018                 /* If only s change, change just s value only*/
1019                 tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
1020                 tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
1021                 writel_relaxed(tmp, pll->con_reg);
1022 
1023                 return 0;
1024         }
1025 
1026         /* Set PLL lock time. */
1027         writel_relaxed(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
1028 
1029         /* Change PLL PMS values */
1030         tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
1031                         (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) |
1032                         (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT));
1033         tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
1034                         (rate->pdiv << PLL2550XX_P_SHIFT) |
1035                         (rate->sdiv << PLL2550XX_S_SHIFT);
1036         writel_relaxed(tmp, pll->con_reg);
1037 
1038         /* wait_lock_time */
1039         do {
1040                 cpu_relax();
1041                 tmp = readl_relaxed(pll->con_reg);
1042         } while (!(tmp & (PLL2550XX_LOCK_STAT_MASK
1043                         << PLL2550XX_LOCK_STAT_SHIFT)));
1044 
1045         return 0;
1046 }
1047 
1048 static const struct clk_ops samsung_pll2550xx_clk_ops = {
1049         .recalc_rate = samsung_pll2550xx_recalc_rate,
1050         .round_rate = samsung_pll_round_rate,
1051         .set_rate = samsung_pll2550xx_set_rate,
1052 };
1053 
1054 static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
1055         .recalc_rate = samsung_pll2550xx_recalc_rate,
1056 };
1057 
1058 /*
1059  * PLL2650x Clock Type
1060  */
1061 
1062 /* Maximum lock time can be 3000 * PDIV cycles */
1063 #define PLL2650X_LOCK_FACTOR            3000
1064 
1065 #define PLL2650X_M_MASK                 0x1ff
1066 #define PLL2650X_P_MASK                 0x3f
1067 #define PLL2650X_S_MASK                 0x7
1068 #define PLL2650X_K_MASK                 0xffff
1069 #define PLL2650X_LOCK_STAT_MASK         0x1
1070 #define PLL2650X_M_SHIFT                16
1071 #define PLL2650X_P_SHIFT                8
1072 #define PLL2650X_S_SHIFT                0
1073 #define PLL2650X_K_SHIFT                0
1074 #define PLL2650X_LOCK_STAT_SHIFT        29
1075 #define PLL2650X_PLL_ENABLE_SHIFT       31
1076 
1077 static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw *hw,
1078                                 unsigned long parent_rate)
1079 {
1080         struct samsung_clk_pll *pll = to_clk_pll(hw);
1081         u64 fout = parent_rate;
1082         u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
1083         s16 kdiv;
1084 
1085         pll_con0 = readl_relaxed(pll->con_reg);
1086         mdiv = (pll_con0 >> PLL2650X_M_SHIFT) & PLL2650X_M_MASK;
1087         pdiv = (pll_con0 >> PLL2650X_P_SHIFT) & PLL2650X_P_MASK;
1088         sdiv = (pll_con0 >> PLL2650X_S_SHIFT) & PLL2650X_S_MASK;
1089 
1090         pll_con1 = readl_relaxed(pll->con_reg + 4);
1091         kdiv = (s16)((pll_con1 >> PLL2650X_K_SHIFT) & PLL2650X_K_MASK);
1092 
1093         fout *= (mdiv << 16) + kdiv;
1094         do_div(fout, (pdiv << sdiv));
1095         fout >>= 16;
1096 
1097         return (unsigned long)fout;
1098 }
1099 
1100 static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
1101                                         unsigned long prate)
1102 {
1103         struct samsung_clk_pll *pll = to_clk_pll(hw);
1104         const struct samsung_pll_rate_table *rate;
1105         u32 con0, con1;
1106 
1107         /* Get required rate settings from table */
1108         rate = samsung_get_pll_settings(pll, drate);
1109         if (!rate) {
1110                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1111                         drate, clk_hw_get_name(hw));
1112                 return -EINVAL;
1113         }
1114 
1115         con0 = readl_relaxed(pll->con_reg);
1116         con1 = readl_relaxed(pll->con_reg + 4);
1117 
1118         /* Set PLL lock time. */
1119         writel_relaxed(rate->pdiv * PLL2650X_LOCK_FACTOR, pll->lock_reg);
1120 
1121         /* Change PLL PMS values */
1122         con0 &= ~((PLL2650X_M_MASK << PLL2650X_M_SHIFT) |
1123                         (PLL2650X_P_MASK << PLL2650X_P_SHIFT) |
1124                         (PLL2650X_S_MASK << PLL2650X_S_SHIFT));
1125         con0 |= (rate->mdiv << PLL2650X_M_SHIFT) |
1126                         (rate->pdiv << PLL2650X_P_SHIFT) |
1127                         (rate->sdiv << PLL2650X_S_SHIFT);
1128         con0 |= (1 << PLL2650X_PLL_ENABLE_SHIFT);
1129         writel_relaxed(con0, pll->con_reg);
1130 
1131         con1 &= ~(PLL2650X_K_MASK << PLL2650X_K_SHIFT);
1132         con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
1133         writel_relaxed(con1, pll->con_reg + 4);
1134 
1135         do {
1136                 cpu_relax();
1137                 con0 = readl_relaxed(pll->con_reg);
1138         } while (!(con0 & (PLL2650X_LOCK_STAT_MASK
1139                         << PLL2650X_LOCK_STAT_SHIFT)));
1140 
1141         return 0;
1142 }
1143 
1144 static const struct clk_ops samsung_pll2650x_clk_ops = {
1145         .recalc_rate = samsung_pll2650x_recalc_rate,
1146         .round_rate = samsung_pll_round_rate,
1147         .set_rate = samsung_pll2650x_set_rate,
1148 };
1149 
1150 static const struct clk_ops samsung_pll2650x_clk_min_ops = {
1151         .recalc_rate = samsung_pll2650x_recalc_rate,
1152 };
1153 
1154 /*
1155  * PLL2650XX Clock Type
1156  */
1157 
1158 /* Maximum lock time can be 3000 * PDIV cycles */
1159 #define PLL2650XX_LOCK_FACTOR 3000
1160 
1161 #define PLL2650XX_MDIV_SHIFT            9
1162 #define PLL2650XX_PDIV_SHIFT            3
1163 #define PLL2650XX_SDIV_SHIFT            0
1164 #define PLL2650XX_KDIV_SHIFT            0
1165 #define PLL2650XX_MDIV_MASK             0x1ff
1166 #define PLL2650XX_PDIV_MASK             0x3f
1167 #define PLL2650XX_SDIV_MASK             0x7
1168 #define PLL2650XX_KDIV_MASK             0xffff
1169 #define PLL2650XX_PLL_ENABLE_SHIFT      23
1170 #define PLL2650XX_PLL_LOCKTIME_SHIFT    21
1171 #define PLL2650XX_PLL_FOUTMASK_SHIFT    31
1172 
1173 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
1174                                 unsigned long parent_rate)
1175 {
1176         struct samsung_clk_pll *pll = to_clk_pll(hw);
1177         u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
1178         s16 kdiv;
1179         u64 fvco = parent_rate;
1180 
1181         pll_con0 = readl_relaxed(pll->con_reg);
1182         pll_con2 = readl_relaxed(pll->con_reg + 8);
1183         mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
1184         pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
1185         sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
1186         kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK);
1187 
1188         fvco *= (mdiv << 16) + kdiv;
1189         do_div(fvco, (pdiv << sdiv));
1190         fvco >>= 16;
1191 
1192         return (unsigned long)fvco;
1193 }
1194 
1195 static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
1196                                         unsigned long parent_rate)
1197 {
1198         struct samsung_clk_pll *pll = to_clk_pll(hw);
1199         u32 tmp, pll_con0, pll_con2;
1200         const struct samsung_pll_rate_table *rate;
1201 
1202         rate = samsung_get_pll_settings(pll, drate);
1203         if (!rate) {
1204                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1205                         drate, clk_hw_get_name(hw));
1206                 return -EINVAL;
1207         }
1208 
1209         pll_con0 = readl_relaxed(pll->con_reg);
1210         pll_con2 = readl_relaxed(pll->con_reg + 8);
1211 
1212          /* Change PLL PMS values */
1213         pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
1214                         PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT |
1215                         PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT);
1216         pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT;
1217         pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT;
1218         pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT;
1219         pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT;
1220         pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT;
1221 
1222         pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
1223         pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
1224                         << PLL2650XX_KDIV_SHIFT;
1225 
1226         /* Set PLL lock time. */
1227         writel_relaxed(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
1228 
1229         writel_relaxed(pll_con0, pll->con_reg);
1230         writel_relaxed(pll_con2, pll->con_reg + 8);
1231 
1232         do {
1233                 tmp = readl_relaxed(pll->con_reg);
1234         } while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT)));
1235 
1236         return 0;
1237 }
1238 
1239 static const struct clk_ops samsung_pll2650xx_clk_ops = {
1240         .recalc_rate = samsung_pll2650xx_recalc_rate,
1241         .set_rate = samsung_pll2650xx_set_rate,
1242         .round_rate = samsung_pll_round_rate,
1243 };
1244 
1245 static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
1246         .recalc_rate = samsung_pll2650xx_recalc_rate,
1247 };
1248 
1249 static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1250                                 const struct samsung_pll_clock *pll_clk,
1251                                 void __iomem *base)
1252 {
1253         struct samsung_clk_pll *pll;
1254         struct clk_init_data init;
1255         int ret, len;
1256 
1257         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
1258         if (!pll) {
1259                 pr_err("%s: could not allocate pll clk %s\n",
1260                         __func__, pll_clk->name);
1261                 return;
1262         }
1263 
1264         init.name = pll_clk->name;
1265         init.flags = pll_clk->flags;
1266         init.parent_names = &pll_clk->parent_name;
1267         init.num_parents = 1;
1268 
1269         if (pll_clk->rate_table) {
1270                 /* find count of rates in rate_table */
1271                 for (len = 0; pll_clk->rate_table[len].rate != 0; )
1272                         len++;
1273 
1274                 pll->rate_count = len;
1275                 pll->rate_table = kmemdup(pll_clk->rate_table,
1276                                         pll->rate_count *
1277                                         sizeof(struct samsung_pll_rate_table),
1278                                         GFP_KERNEL);
1279                 WARN(!pll->rate_table,
1280                         "%s: could not allocate rate table for %s\n",
1281                         __func__, pll_clk->name);
1282         }
1283 
1284         switch (pll_clk->type) {
1285         case pll_2126:
1286                 init.ops = &samsung_pll2126_clk_ops;
1287                 break;
1288         case pll_3000:
1289                 init.ops = &samsung_pll3000_clk_ops;
1290                 break;
1291         /* clk_ops for 35xx and 2550 are similar */
1292         case pll_35xx:
1293         case pll_2550:
1294         case pll_1450x:
1295         case pll_1451x:
1296         case pll_1452x:
1297                 pll->enable_offs = PLL35XX_ENABLE_SHIFT;
1298                 pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
1299                 if (!pll->rate_table)
1300                         init.ops = &samsung_pll35xx_clk_min_ops;
1301                 else
1302                         init.ops = &samsung_pll35xx_clk_ops;
1303                 break;
1304         case pll_4500:
1305                 init.ops = &samsung_pll45xx_clk_min_ops;
1306                 break;
1307         case pll_4502:
1308         case pll_4508:
1309                 if (!pll->rate_table)
1310                         init.ops = &samsung_pll45xx_clk_min_ops;
1311                 else
1312                         init.ops = &samsung_pll45xx_clk_ops;
1313                 break;
1314         /* clk_ops for 36xx and 2650 are similar */
1315         case pll_36xx:
1316         case pll_2650:
1317                 pll->enable_offs = PLL36XX_ENABLE_SHIFT;
1318                 pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
1319                 if (!pll->rate_table)
1320                         init.ops = &samsung_pll36xx_clk_min_ops;
1321                 else
1322                         init.ops = &samsung_pll36xx_clk_ops;
1323                 break;
1324         case pll_6552:
1325         case pll_6552_s3c2416:
1326                 init.ops = &samsung_pll6552_clk_ops;
1327                 break;
1328         case pll_6553:
1329                 init.ops = &samsung_pll6553_clk_ops;
1330                 break;
1331         case pll_4600:
1332         case pll_4650:
1333         case pll_4650c:
1334         case pll_1460x:
1335                 if (!pll->rate_table)
1336                         init.ops = &samsung_pll46xx_clk_min_ops;
1337                 else
1338                         init.ops = &samsung_pll46xx_clk_ops;
1339                 break;
1340         case pll_s3c2410_mpll:
1341                 if (!pll->rate_table)
1342                         init.ops = &samsung_s3c2410_mpll_clk_min_ops;
1343                 else
1344                         init.ops = &samsung_s3c2410_mpll_clk_ops;
1345                 break;
1346         case pll_s3c2410_upll:
1347                 if (!pll->rate_table)
1348                         init.ops = &samsung_s3c2410_upll_clk_min_ops;
1349                 else
1350                         init.ops = &samsung_s3c2410_upll_clk_ops;
1351                 break;
1352         case pll_s3c2440_mpll:
1353                 if (!pll->rate_table)
1354                         init.ops = &samsung_s3c2440_mpll_clk_min_ops;
1355                 else
1356                         init.ops = &samsung_s3c2440_mpll_clk_ops;
1357                 break;
1358         case pll_2550x:
1359                 init.ops = &samsung_pll2550x_clk_ops;
1360                 break;
1361         case pll_2550xx:
1362                 if (!pll->rate_table)
1363                         init.ops = &samsung_pll2550xx_clk_min_ops;
1364                 else
1365                         init.ops = &samsung_pll2550xx_clk_ops;
1366                 break;
1367         case pll_2650x:
1368                 if (!pll->rate_table)
1369                         init.ops = &samsung_pll2650x_clk_min_ops;
1370                 else
1371                         init.ops = &samsung_pll2650x_clk_ops;
1372                 break;
1373         case pll_2650xx:
1374                 if (!pll->rate_table)
1375                         init.ops = &samsung_pll2650xx_clk_min_ops;
1376                 else
1377                         init.ops = &samsung_pll2650xx_clk_ops;
1378                 break;
1379         default:
1380                 pr_warn("%s: Unknown pll type for pll clk %s\n",
1381                         __func__, pll_clk->name);
1382         }
1383 
1384         pll->hw.init = &init;
1385         pll->type = pll_clk->type;
1386         pll->lock_reg = base + pll_clk->lock_offset;
1387         pll->con_reg = base + pll_clk->con_offset;
1388 
1389         ret = clk_hw_register(ctx->dev, &pll->hw);
1390         if (ret) {
1391                 pr_err("%s: failed to register pll clock %s : %d\n",
1392                         __func__, pll_clk->name, ret);
1393                 kfree(pll);
1394                 return;
1395         }
1396 
1397         samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
1398 }
1399 
1400 void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1401                         const struct samsung_pll_clock *pll_list,
1402                         unsigned int nr_pll, void __iomem *base)
1403 {
1404         int cnt;
1405 
1406         for (cnt = 0; cnt < nr_pll; cnt++)
1407                 _samsung_clk_register_pll(ctx, &pll_list[cnt], base);
1408 }

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