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