Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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