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 "clk.h" 15 #include "clk-pll.h" 16 17 #define PLL_TIMEOUT_MS 10 18 19 struct samsung_clk_pll { 20 struct clk_hw hw; 21 void __iomem *lock_reg; 22 void __iomem *con_reg; 23 enum samsung_pll_type type; 24 unsigned int rate_count; 25 const struct samsung_pll_rate_table *rate_table; 26 }; 27 28 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw) 29 30 static const struct samsung_pll_rate_table *samsung_get_pll_settings( 31 struct samsung_clk_pll *pll, unsigned long rate) 32 { 33 const struct samsung_pll_rate_table *rate_table = pll->rate_table; 34 int i; 35 36 for (i = 0; i < pll->rate_count; i++) { 37 if (rate == rate_table[i].rate) 38 return &rate_table[i]; 39 } 40 41 return NULL; 42 } 43 44 static long samsung_pll_round_rate(struct clk_hw *hw, 45 unsigned long drate, unsigned long *prate) 46 { 47 struct samsung_clk_pll *pll = to_clk_pll(hw); 48 const struct samsung_pll_rate_table *rate_table = pll->rate_table; 49 int i; 50 51 /* Assumming rate_table is in descending order */ 52 for (i = 0; i < pll->rate_count; i++) { 53 if (drate >= rate_table[i].rate) 54 return rate_table[i].rate; 55 } 56 57 /* return minimum supported value */ 58 return rate_table[i - 1].rate; 59 } 60 61 /* 62 * PLL35xx Clock Type 63 */ 64 /* Maximum lock time can be 270 * PDIV cycles */ 65 #define PLL35XX_LOCK_FACTOR (270) 66 67 #define PLL35XX_MDIV_MASK (0x3FF) 68 #define PLL35XX_PDIV_MASK (0x3F) 69 #define PLL35XX_SDIV_MASK (0x7) 70 #define PLL35XX_LOCK_STAT_MASK (0x1) 71 #define PLL35XX_MDIV_SHIFT (16) 72 #define PLL35XX_PDIV_SHIFT (8) 73 #define PLL35XX_SDIV_SHIFT (0) 74 #define PLL35XX_LOCK_STAT_SHIFT (29) 75 76 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, 77 unsigned long parent_rate) 78 { 79 struct samsung_clk_pll *pll = to_clk_pll(hw); 80 u32 mdiv, pdiv, sdiv, pll_con; 81 u64 fvco = parent_rate; 82 83 pll_con = __raw_readl(pll->con_reg); 84 mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK; 85 pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK; 86 sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK; 87 88 fvco *= mdiv; 89 do_div(fvco, (pdiv << sdiv)); 90 91 return (unsigned long)fvco; 92 } 93 94 static inline bool samsung_pll35xx_mp_change( 95 const struct samsung_pll_rate_table *rate, u32 pll_con) 96 { 97 u32 old_mdiv, old_pdiv; 98 99 old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK; 100 old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK; 101 102 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv); 103 } 104 105 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, 106 unsigned long prate) 107 { 108 struct samsung_clk_pll *pll = to_clk_pll(hw); 109 const struct samsung_pll_rate_table *rate; 110 u32 tmp; 111 112 /* Get required rate settings from table */ 113 rate = samsung_get_pll_settings(pll, drate); 114 if (!rate) { 115 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 116 drate, __clk_get_name(hw->clk)); 117 return -EINVAL; 118 } 119 120 tmp = __raw_readl(pll->con_reg); 121 122 if (!(samsung_pll35xx_mp_change(rate, tmp))) { 123 /* If only s change, change just s value only*/ 124 tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT); 125 tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT; 126 __raw_writel(tmp, pll->con_reg); 127 128 return 0; 129 } 130 131 /* Set PLL lock time. */ 132 __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR, 133 pll->lock_reg); 134 135 /* Change PLL PMS values */ 136 tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) | 137 (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) | 138 (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT)); 139 tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) | 140 (rate->pdiv << PLL35XX_PDIV_SHIFT) | 141 (rate->sdiv << PLL35XX_SDIV_SHIFT); 142 __raw_writel(tmp, pll->con_reg); 143 144 /* wait_lock_time */ 145 do { 146 cpu_relax(); 147 tmp = __raw_readl(pll->con_reg); 148 } while (!(tmp & (PLL35XX_LOCK_STAT_MASK 149 << PLL35XX_LOCK_STAT_SHIFT))); 150 return 0; 151 } 152 153 static const struct clk_ops samsung_pll35xx_clk_ops = { 154 .recalc_rate = samsung_pll35xx_recalc_rate, 155 .round_rate = samsung_pll_round_rate, 156 .set_rate = samsung_pll35xx_set_rate, 157 }; 158 159 static const struct clk_ops samsung_pll35xx_clk_min_ops = { 160 .recalc_rate = samsung_pll35xx_recalc_rate, 161 }; 162 163 /* 164 * PLL36xx Clock Type 165 */ 166 /* Maximum lock time can be 3000 * PDIV cycles */ 167 #define PLL36XX_LOCK_FACTOR (3000) 168 169 #define PLL36XX_KDIV_MASK (0xFFFF) 170 #define PLL36XX_MDIV_MASK (0x1FF) 171 #define PLL36XX_PDIV_MASK (0x3F) 172 #define PLL36XX_SDIV_MASK (0x7) 173 #define PLL36XX_MDIV_SHIFT (16) 174 #define PLL36XX_PDIV_SHIFT (8) 175 #define PLL36XX_SDIV_SHIFT (0) 176 #define PLL36XX_KDIV_SHIFT (0) 177 #define PLL36XX_LOCK_STAT_SHIFT (29) 178 179 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, 180 unsigned long parent_rate) 181 { 182 struct samsung_clk_pll *pll = to_clk_pll(hw); 183 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1; 184 s16 kdiv; 185 u64 fvco = parent_rate; 186 187 pll_con0 = __raw_readl(pll->con_reg); 188 pll_con1 = __raw_readl(pll->con_reg + 4); 189 mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK; 190 pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK; 191 sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK; 192 kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK); 193 194 fvco *= (mdiv << 16) + kdiv; 195 do_div(fvco, (pdiv << sdiv)); 196 fvco >>= 16; 197 198 return (unsigned long)fvco; 199 } 200 201 static inline bool samsung_pll36xx_mpk_change( 202 const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1) 203 { 204 u32 old_mdiv, old_pdiv, old_kdiv; 205 206 old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK; 207 old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK; 208 old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK; 209 210 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || 211 rate->kdiv != old_kdiv); 212 } 213 214 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate, 215 unsigned long parent_rate) 216 { 217 struct samsung_clk_pll *pll = to_clk_pll(hw); 218 u32 tmp, pll_con0, pll_con1; 219 const struct samsung_pll_rate_table *rate; 220 221 rate = samsung_get_pll_settings(pll, drate); 222 if (!rate) { 223 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 224 drate, __clk_get_name(hw->clk)); 225 return -EINVAL; 226 } 227 228 pll_con0 = __raw_readl(pll->con_reg); 229 pll_con1 = __raw_readl(pll->con_reg + 4); 230 231 if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) { 232 /* If only s change, change just s value only*/ 233 pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT); 234 pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT); 235 __raw_writel(pll_con0, pll->con_reg); 236 237 return 0; 238 } 239 240 /* Set PLL lock time. */ 241 __raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg); 242 243 /* Change PLL PMS values */ 244 pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) | 245 (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) | 246 (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT)); 247 pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) | 248 (rate->pdiv << PLL36XX_PDIV_SHIFT) | 249 (rate->sdiv << PLL36XX_SDIV_SHIFT); 250 __raw_writel(pll_con0, pll->con_reg); 251 252 pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT); 253 pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT; 254 __raw_writel(pll_con1, pll->con_reg + 4); 255 256 /* wait_lock_time */ 257 do { 258 cpu_relax(); 259 tmp = __raw_readl(pll->con_reg); 260 } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT))); 261 262 return 0; 263 } 264 265 static const struct clk_ops samsung_pll36xx_clk_ops = { 266 .recalc_rate = samsung_pll36xx_recalc_rate, 267 .set_rate = samsung_pll36xx_set_rate, 268 .round_rate = samsung_pll_round_rate, 269 }; 270 271 static const struct clk_ops samsung_pll36xx_clk_min_ops = { 272 .recalc_rate = samsung_pll36xx_recalc_rate, 273 }; 274 275 /* 276 * PLL45xx Clock Type 277 */ 278 #define PLL4502_LOCK_FACTOR 400 279 #define PLL4508_LOCK_FACTOR 240 280 281 #define PLL45XX_MDIV_MASK (0x3FF) 282 #define PLL45XX_PDIV_MASK (0x3F) 283 #define PLL45XX_SDIV_MASK (0x7) 284 #define PLL45XX_AFC_MASK (0x1F) 285 #define PLL45XX_MDIV_SHIFT (16) 286 #define PLL45XX_PDIV_SHIFT (8) 287 #define PLL45XX_SDIV_SHIFT (0) 288 #define PLL45XX_AFC_SHIFT (0) 289 290 #define PLL45XX_ENABLE BIT(31) 291 #define PLL45XX_LOCKED BIT(29) 292 293 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw, 294 unsigned long parent_rate) 295 { 296 struct samsung_clk_pll *pll = to_clk_pll(hw); 297 u32 mdiv, pdiv, sdiv, pll_con; 298 u64 fvco = parent_rate; 299 300 pll_con = __raw_readl(pll->con_reg); 301 mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK; 302 pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK; 303 sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK; 304 305 if (pll->type == pll_4508) 306 sdiv = sdiv - 1; 307 308 fvco *= mdiv; 309 do_div(fvco, (pdiv << sdiv)); 310 311 return (unsigned long)fvco; 312 } 313 314 static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1, 315 const struct samsung_pll_rate_table *rate) 316 { 317 u32 old_mdiv, old_pdiv, old_afc; 318 319 old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK; 320 old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK; 321 old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK; 322 323 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv 324 || old_afc != rate->afc); 325 } 326 327 static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate, 328 unsigned long prate) 329 { 330 struct samsung_clk_pll *pll = to_clk_pll(hw); 331 const struct samsung_pll_rate_table *rate; 332 u32 con0, con1; 333 ktime_t start; 334 335 /* Get required rate settings from table */ 336 rate = samsung_get_pll_settings(pll, drate); 337 if (!rate) { 338 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 339 drate, __clk_get_name(hw->clk)); 340 return -EINVAL; 341 } 342 343 con0 = __raw_readl(pll->con_reg); 344 con1 = __raw_readl(pll->con_reg + 0x4); 345 346 if (!(samsung_pll45xx_mp_change(con0, con1, rate))) { 347 /* If only s change, change just s value only*/ 348 con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT); 349 con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT; 350 __raw_writel(con0, pll->con_reg); 351 352 return 0; 353 } 354 355 /* Set PLL PMS values. */ 356 con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) | 357 (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) | 358 (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT)); 359 con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) | 360 (rate->pdiv << PLL45XX_PDIV_SHIFT) | 361 (rate->sdiv << PLL45XX_SDIV_SHIFT); 362 363 /* Set PLL AFC value. */ 364 con1 = __raw_readl(pll->con_reg + 0x4); 365 con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT); 366 con1 |= (rate->afc << PLL45XX_AFC_SHIFT); 367 368 /* Set PLL lock time. */ 369 switch (pll->type) { 370 case pll_4502: 371 __raw_writel(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg); 372 break; 373 case pll_4508: 374 __raw_writel(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg); 375 break; 376 default: 377 break; 378 }; 379 380 /* Set new configuration. */ 381 __raw_writel(con1, pll->con_reg + 0x4); 382 __raw_writel(con0, pll->con_reg); 383 384 /* Wait for locking. */ 385 start = ktime_get(); 386 while (!(__raw_readl(pll->con_reg) & PLL45XX_LOCKED)) { 387 ktime_t delta = ktime_sub(ktime_get(), start); 388 389 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) { 390 pr_err("%s: could not lock PLL %s\n", 391 __func__, __clk_get_name(hw->clk)); 392 return -EFAULT; 393 } 394 395 cpu_relax(); 396 } 397 398 return 0; 399 } 400 401 static const struct clk_ops samsung_pll45xx_clk_ops = { 402 .recalc_rate = samsung_pll45xx_recalc_rate, 403 .round_rate = samsung_pll_round_rate, 404 .set_rate = samsung_pll45xx_set_rate, 405 }; 406 407 static const struct clk_ops samsung_pll45xx_clk_min_ops = { 408 .recalc_rate = samsung_pll45xx_recalc_rate, 409 }; 410 411 /* 412 * PLL46xx Clock Type 413 */ 414 #define PLL46XX_LOCK_FACTOR 3000 415 416 #define PLL46XX_VSEL_MASK (1) 417 #define PLL46XX_MDIV_MASK (0x1FF) 418 #define PLL46XX_PDIV_MASK (0x3F) 419 #define PLL46XX_SDIV_MASK (0x7) 420 #define PLL46XX_VSEL_SHIFT (27) 421 #define PLL46XX_MDIV_SHIFT (16) 422 #define PLL46XX_PDIV_SHIFT (8) 423 #define PLL46XX_SDIV_SHIFT (0) 424 425 #define PLL46XX_KDIV_MASK (0xFFFF) 426 #define PLL4650C_KDIV_MASK (0xFFF) 427 #define PLL46XX_KDIV_SHIFT (0) 428 #define PLL46XX_MFR_MASK (0x3F) 429 #define PLL46XX_MRR_MASK (0x1F) 430 #define PLL46XX_KDIV_SHIFT (0) 431 #define PLL46XX_MFR_SHIFT (16) 432 #define PLL46XX_MRR_SHIFT (24) 433 434 #define PLL46XX_ENABLE BIT(31) 435 #define PLL46XX_LOCKED BIT(29) 436 #define PLL46XX_VSEL BIT(27) 437 438 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, 439 unsigned long parent_rate) 440 { 441 struct samsung_clk_pll *pll = to_clk_pll(hw); 442 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift; 443 u64 fvco = parent_rate; 444 445 pll_con0 = __raw_readl(pll->con_reg); 446 pll_con1 = __raw_readl(pll->con_reg + 4); 447 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; 448 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; 449 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; 450 kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK : 451 pll_con1 & PLL46XX_KDIV_MASK; 452 453 shift = pll->type == pll_4600 ? 16 : 10; 454 fvco *= (mdiv << shift) + kdiv; 455 do_div(fvco, (pdiv << sdiv)); 456 fvco >>= shift; 457 458 return (unsigned long)fvco; 459 } 460 461 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1, 462 const struct samsung_pll_rate_table *rate) 463 { 464 u32 old_mdiv, old_pdiv, old_kdiv; 465 466 old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; 467 old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; 468 old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK; 469 470 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv 471 || old_kdiv != rate->kdiv); 472 } 473 474 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, 475 unsigned long prate) 476 { 477 struct samsung_clk_pll *pll = to_clk_pll(hw); 478 const struct samsung_pll_rate_table *rate; 479 u32 con0, con1, lock; 480 ktime_t start; 481 482 /* Get required rate settings from table */ 483 rate = samsung_get_pll_settings(pll, drate); 484 if (!rate) { 485 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 486 drate, __clk_get_name(hw->clk)); 487 return -EINVAL; 488 } 489 490 con0 = __raw_readl(pll->con_reg); 491 con1 = __raw_readl(pll->con_reg + 0x4); 492 493 if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) { 494 /* If only s change, change just s value only*/ 495 con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); 496 con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT; 497 __raw_writel(con0, pll->con_reg); 498 499 return 0; 500 } 501 502 /* Set PLL lock time. */ 503 lock = rate->pdiv * PLL46XX_LOCK_FACTOR; 504 if (lock > 0xffff) 505 /* Maximum lock time bitfield is 16-bit. */ 506 lock = 0xffff; 507 508 /* Set PLL PMS and VSEL values. */ 509 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) | 510 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) | 511 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) | 512 (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT)); 513 con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) | 514 (rate->pdiv << PLL46XX_PDIV_SHIFT) | 515 (rate->sdiv << PLL46XX_SDIV_SHIFT) | 516 (rate->vsel << PLL46XX_VSEL_SHIFT); 517 518 /* Set PLL K, MFR and MRR values. */ 519 con1 = __raw_readl(pll->con_reg + 0x4); 520 con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) | 521 (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) | 522 (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT)); 523 con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) | 524 (rate->mfr << PLL46XX_MFR_SHIFT) | 525 (rate->mrr << PLL46XX_MRR_SHIFT); 526 527 /* Write configuration to PLL */ 528 __raw_writel(lock, pll->lock_reg); 529 __raw_writel(con0, pll->con_reg); 530 __raw_writel(con1, pll->con_reg + 0x4); 531 532 /* Wait for locking. */ 533 start = ktime_get(); 534 while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) { 535 ktime_t delta = ktime_sub(ktime_get(), start); 536 537 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) { 538 pr_err("%s: could not lock PLL %s\n", 539 __func__, __clk_get_name(hw->clk)); 540 return -EFAULT; 541 } 542 543 cpu_relax(); 544 } 545 546 return 0; 547 } 548 549 static const struct clk_ops samsung_pll46xx_clk_ops = { 550 .recalc_rate = samsung_pll46xx_recalc_rate, 551 .round_rate = samsung_pll_round_rate, 552 .set_rate = samsung_pll46xx_set_rate, 553 }; 554 555 static const struct clk_ops samsung_pll46xx_clk_min_ops = { 556 .recalc_rate = samsung_pll46xx_recalc_rate, 557 }; 558 559 /* 560 * PLL6552 Clock Type 561 */ 562 563 #define PLL6552_MDIV_MASK 0x3ff 564 #define PLL6552_PDIV_MASK 0x3f 565 #define PLL6552_SDIV_MASK 0x7 566 #define PLL6552_MDIV_SHIFT 16 567 #define PLL6552_PDIV_SHIFT 8 568 #define PLL6552_SDIV_SHIFT 0 569 570 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw, 571 unsigned long parent_rate) 572 { 573 struct samsung_clk_pll *pll = to_clk_pll(hw); 574 u32 mdiv, pdiv, sdiv, pll_con; 575 u64 fvco = parent_rate; 576 577 pll_con = __raw_readl(pll->con_reg); 578 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK; 579 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK; 580 sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK; 581 582 fvco *= mdiv; 583 do_div(fvco, (pdiv << sdiv)); 584 585 return (unsigned long)fvco; 586 } 587 588 static const struct clk_ops samsung_pll6552_clk_ops = { 589 .recalc_rate = samsung_pll6552_recalc_rate, 590 }; 591 592 /* 593 * PLL6553 Clock Type 594 */ 595 596 #define PLL6553_MDIV_MASK 0xff 597 #define PLL6553_PDIV_MASK 0x3f 598 #define PLL6553_SDIV_MASK 0x7 599 #define PLL6553_KDIV_MASK 0xffff 600 #define PLL6553_MDIV_SHIFT 16 601 #define PLL6553_PDIV_SHIFT 8 602 #define PLL6553_SDIV_SHIFT 0 603 #define PLL6553_KDIV_SHIFT 0 604 605 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw, 606 unsigned long parent_rate) 607 { 608 struct samsung_clk_pll *pll = to_clk_pll(hw); 609 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1; 610 u64 fvco = parent_rate; 611 612 pll_con0 = __raw_readl(pll->con_reg); 613 pll_con1 = __raw_readl(pll->con_reg + 0x4); 614 mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK; 615 pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK; 616 sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK; 617 kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK; 618 619 fvco *= (mdiv << 16) + kdiv; 620 do_div(fvco, (pdiv << sdiv)); 621 fvco >>= 16; 622 623 return (unsigned long)fvco; 624 } 625 626 static const struct clk_ops samsung_pll6553_clk_ops = { 627 .recalc_rate = samsung_pll6553_recalc_rate, 628 }; 629 630 /* 631 * PLL2550x Clock Type 632 */ 633 634 #define PLL2550X_R_MASK (0x1) 635 #define PLL2550X_P_MASK (0x3F) 636 #define PLL2550X_M_MASK (0x3FF) 637 #define PLL2550X_S_MASK (0x7) 638 #define PLL2550X_R_SHIFT (20) 639 #define PLL2550X_P_SHIFT (14) 640 #define PLL2550X_M_SHIFT (4) 641 #define PLL2550X_S_SHIFT (0) 642 643 struct samsung_clk_pll2550x { 644 struct clk_hw hw; 645 const void __iomem *reg_base; 646 unsigned long offset; 647 }; 648 649 #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw) 650 651 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw, 652 unsigned long parent_rate) 653 { 654 struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw); 655 u32 r, p, m, s, pll_stat; 656 u64 fvco = parent_rate; 657 658 pll_stat = __raw_readl(pll->reg_base + pll->offset * 3); 659 r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK; 660 if (!r) 661 return 0; 662 p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK; 663 m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK; 664 s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK; 665 666 fvco *= m; 667 do_div(fvco, (p << s)); 668 669 return (unsigned long)fvco; 670 } 671 672 static const struct clk_ops samsung_pll2550x_clk_ops = { 673 .recalc_rate = samsung_pll2550x_recalc_rate, 674 }; 675 676 struct clk * __init samsung_clk_register_pll2550x(const char *name, 677 const char *pname, const void __iomem *reg_base, 678 const unsigned long offset) 679 { 680 struct samsung_clk_pll2550x *pll; 681 struct clk *clk; 682 struct clk_init_data init; 683 684 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 685 if (!pll) { 686 pr_err("%s: could not allocate pll clk %s\n", __func__, name); 687 return NULL; 688 } 689 690 init.name = name; 691 init.ops = &samsung_pll2550x_clk_ops; 692 init.flags = CLK_GET_RATE_NOCACHE; 693 init.parent_names = &pname; 694 init.num_parents = 1; 695 696 pll->hw.init = &init; 697 pll->reg_base = reg_base; 698 pll->offset = offset; 699 700 clk = clk_register(NULL, &pll->hw); 701 if (IS_ERR(clk)) { 702 pr_err("%s: failed to register pll clock %s\n", __func__, 703 name); 704 kfree(pll); 705 } 706 707 if (clk_register_clkdev(clk, name, NULL)) 708 pr_err("%s: failed to register lookup for %s", __func__, name); 709 710 return clk; 711 } 712 713 static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk, 714 void __iomem *base) 715 { 716 struct samsung_clk_pll *pll; 717 struct clk *clk; 718 struct clk_init_data init; 719 int ret, len; 720 721 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 722 if (!pll) { 723 pr_err("%s: could not allocate pll clk %s\n", 724 __func__, pll_clk->name); 725 return; 726 } 727 728 init.name = pll_clk->name; 729 init.flags = pll_clk->flags; 730 init.parent_names = &pll_clk->parent_name; 731 init.num_parents = 1; 732 733 if (pll_clk->rate_table) { 734 /* find count of rates in rate_table */ 735 for (len = 0; pll_clk->rate_table[len].rate != 0; ) 736 len++; 737 738 pll->rate_count = len; 739 pll->rate_table = kmemdup(pll_clk->rate_table, 740 pll->rate_count * 741 sizeof(struct samsung_pll_rate_table), 742 GFP_KERNEL); 743 WARN(!pll->rate_table, 744 "%s: could not allocate rate table for %s\n", 745 __func__, pll_clk->name); 746 } 747 748 switch (pll_clk->type) { 749 /* clk_ops for 35xx and 2550 are similar */ 750 case pll_35xx: 751 case pll_2550: 752 if (!pll->rate_table) 753 init.ops = &samsung_pll35xx_clk_min_ops; 754 else 755 init.ops = &samsung_pll35xx_clk_ops; 756 break; 757 case pll_4500: 758 init.ops = &samsung_pll45xx_clk_min_ops; 759 break; 760 case pll_4502: 761 case pll_4508: 762 if (!pll->rate_table) 763 init.ops = &samsung_pll45xx_clk_min_ops; 764 else 765 init.ops = &samsung_pll45xx_clk_ops; 766 break; 767 /* clk_ops for 36xx and 2650 are similar */ 768 case pll_36xx: 769 case pll_2650: 770 if (!pll->rate_table) 771 init.ops = &samsung_pll36xx_clk_min_ops; 772 else 773 init.ops = &samsung_pll36xx_clk_ops; 774 break; 775 case pll_6552: 776 init.ops = &samsung_pll6552_clk_ops; 777 break; 778 case pll_6553: 779 init.ops = &samsung_pll6553_clk_ops; 780 break; 781 case pll_4600: 782 case pll_4650: 783 case pll_4650c: 784 if (!pll->rate_table) 785 init.ops = &samsung_pll46xx_clk_min_ops; 786 else 787 init.ops = &samsung_pll46xx_clk_ops; 788 break; 789 default: 790 pr_warn("%s: Unknown pll type for pll clk %s\n", 791 __func__, pll_clk->name); 792 } 793 794 pll->hw.init = &init; 795 pll->type = pll_clk->type; 796 pll->lock_reg = base + pll_clk->lock_offset; 797 pll->con_reg = base + pll_clk->con_offset; 798 799 clk = clk_register(NULL, &pll->hw); 800 if (IS_ERR(clk)) { 801 pr_err("%s: failed to register pll clock %s : %ld\n", 802 __func__, pll_clk->name, PTR_ERR(clk)); 803 kfree(pll); 804 return; 805 } 806 807 samsung_clk_add_lookup(clk, pll_clk->id); 808 809 if (!pll_clk->alias) 810 return; 811 812 ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name); 813 if (ret) 814 pr_err("%s: failed to register lookup for %s : %d", 815 __func__, pll_clk->name, ret); 816 } 817 818 void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list, 819 unsigned int nr_pll, void __iomem *base) 820 { 821 int cnt; 822 823 for (cnt = 0; cnt < nr_pll; cnt++) 824 _samsung_clk_register_pll(&pll_list[cnt], base); 825 } 826