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