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