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 PLL46XX_PDIV_MASK (0x3F) 486 #define PLL46XX_SDIV_MASK (0x7) 487 #define PLL46XX_VSEL_SHIFT (27) 488 #define PLL46XX_MDIV_SHIFT (16) 489 #define PLL46XX_PDIV_SHIFT (8) 490 #define PLL46XX_SDIV_SHIFT (0) 491 492 #define PLL46XX_KDIV_MASK (0xFFFF) 493 #define PLL4650C_KDIV_MASK (0xFFF) 494 #define PLL46XX_KDIV_SHIFT (0) 495 #define PLL46XX_MFR_MASK (0x3F) 496 #define PLL46XX_MRR_MASK (0x1F) 497 #define PLL46XX_KDIV_SHIFT (0) 498 #define PLL46XX_MFR_SHIFT (16) 499 #define PLL46XX_MRR_SHIFT (24) 500 501 #define PLL46XX_ENABLE BIT(31) 502 #define PLL46XX_LOCKED BIT(29) 503 #define PLL46XX_VSEL BIT(27) 504 505 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, 506 unsigned long parent_rate) 507 { 508 struct samsung_clk_pll *pll = to_clk_pll(hw); 509 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift; 510 u64 fvco = parent_rate; 511 512 pll_con0 = __raw_readl(pll->con_reg); 513 pll_con1 = __raw_readl(pll->con_reg + 4); 514 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; 515 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; 516 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; 517 kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK : 518 pll_con1 & PLL46XX_KDIV_MASK; 519 520 shift = pll->type == pll_4600 ? 16 : 10; 521 fvco *= (mdiv << shift) + kdiv; 522 do_div(fvco, (pdiv << sdiv)); 523 fvco >>= shift; 524 525 return (unsigned long)fvco; 526 } 527 528 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1, 529 const struct samsung_pll_rate_table *rate) 530 { 531 u32 old_mdiv, old_pdiv, old_kdiv; 532 533 old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; 534 old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; 535 old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK; 536 537 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv 538 || old_kdiv != rate->kdiv); 539 } 540 541 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, 542 unsigned long prate) 543 { 544 struct samsung_clk_pll *pll = to_clk_pll(hw); 545 const struct samsung_pll_rate_table *rate; 546 u32 con0, con1, lock; 547 ktime_t start; 548 549 /* Get required rate settings from table */ 550 rate = samsung_get_pll_settings(pll, drate); 551 if (!rate) { 552 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 553 drate, __clk_get_name(hw->clk)); 554 return -EINVAL; 555 } 556 557 con0 = __raw_readl(pll->con_reg); 558 con1 = __raw_readl(pll->con_reg + 0x4); 559 560 if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) { 561 /* If only s change, change just s value only*/ 562 con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); 563 con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT; 564 __raw_writel(con0, pll->con_reg); 565 566 return 0; 567 } 568 569 /* Set PLL lock time. */ 570 lock = rate->pdiv * PLL46XX_LOCK_FACTOR; 571 if (lock > 0xffff) 572 /* Maximum lock time bitfield is 16-bit. */ 573 lock = 0xffff; 574 575 /* Set PLL PMS and VSEL values. */ 576 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) | 577 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) | 578 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) | 579 (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT)); 580 con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) | 581 (rate->pdiv << PLL46XX_PDIV_SHIFT) | 582 (rate->sdiv << PLL46XX_SDIV_SHIFT) | 583 (rate->vsel << PLL46XX_VSEL_SHIFT); 584 585 /* Set PLL K, MFR and MRR values. */ 586 con1 = __raw_readl(pll->con_reg + 0x4); 587 con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) | 588 (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) | 589 (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT)); 590 con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) | 591 (rate->mfr << PLL46XX_MFR_SHIFT) | 592 (rate->mrr << PLL46XX_MRR_SHIFT); 593 594 /* Write configuration to PLL */ 595 __raw_writel(lock, pll->lock_reg); 596 __raw_writel(con0, pll->con_reg); 597 __raw_writel(con1, pll->con_reg + 0x4); 598 599 /* Wait for locking. */ 600 start = ktime_get(); 601 while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) { 602 ktime_t delta = ktime_sub(ktime_get(), start); 603 604 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) { 605 pr_err("%s: could not lock PLL %s\n", 606 __func__, __clk_get_name(hw->clk)); 607 return -EFAULT; 608 } 609 610 cpu_relax(); 611 } 612 613 return 0; 614 } 615 616 static const struct clk_ops samsung_pll46xx_clk_ops = { 617 .recalc_rate = samsung_pll46xx_recalc_rate, 618 .round_rate = samsung_pll_round_rate, 619 .set_rate = samsung_pll46xx_set_rate, 620 }; 621 622 static const struct clk_ops samsung_pll46xx_clk_min_ops = { 623 .recalc_rate = samsung_pll46xx_recalc_rate, 624 }; 625 626 /* 627 * PLL6552 Clock Type 628 */ 629 630 #define PLL6552_MDIV_MASK 0x3ff 631 #define PLL6552_PDIV_MASK 0x3f 632 #define PLL6552_SDIV_MASK 0x7 633 #define PLL6552_MDIV_SHIFT 16 634 #define PLL6552_MDIV_SHIFT_2416 14 635 #define PLL6552_PDIV_SHIFT 8 636 #define PLL6552_PDIV_SHIFT_2416 5 637 #define PLL6552_SDIV_SHIFT 0 638 639 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw, 640 unsigned long parent_rate) 641 { 642 struct samsung_clk_pll *pll = to_clk_pll(hw); 643 u32 mdiv, pdiv, sdiv, pll_con; 644 u64 fvco = parent_rate; 645 646 pll_con = __raw_readl(pll->con_reg); 647 if (pll->type == pll_6552_s3c2416) { 648 mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK; 649 pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK; 650 } else { 651 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK; 652 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK; 653 } 654 sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK; 655 656 fvco *= mdiv; 657 do_div(fvco, (pdiv << sdiv)); 658 659 return (unsigned long)fvco; 660 } 661 662 static const struct clk_ops samsung_pll6552_clk_ops = { 663 .recalc_rate = samsung_pll6552_recalc_rate, 664 }; 665 666 /* 667 * PLL6553 Clock Type 668 */ 669 670 #define PLL6553_MDIV_MASK 0xff 671 #define PLL6553_PDIV_MASK 0x3f 672 #define PLL6553_SDIV_MASK 0x7 673 #define PLL6553_KDIV_MASK 0xffff 674 #define PLL6553_MDIV_SHIFT 16 675 #define PLL6553_PDIV_SHIFT 8 676 #define PLL6553_SDIV_SHIFT 0 677 #define PLL6553_KDIV_SHIFT 0 678 679 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw, 680 unsigned long parent_rate) 681 { 682 struct samsung_clk_pll *pll = to_clk_pll(hw); 683 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1; 684 u64 fvco = parent_rate; 685 686 pll_con0 = __raw_readl(pll->con_reg); 687 pll_con1 = __raw_readl(pll->con_reg + 0x4); 688 mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK; 689 pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK; 690 sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK; 691 kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK; 692 693 fvco *= (mdiv << 16) + kdiv; 694 do_div(fvco, (pdiv << sdiv)); 695 fvco >>= 16; 696 697 return (unsigned long)fvco; 698 } 699 700 static const struct clk_ops samsung_pll6553_clk_ops = { 701 .recalc_rate = samsung_pll6553_recalc_rate, 702 }; 703 704 /* 705 * PLL Clock Type of S3C24XX before S3C2443 706 */ 707 708 #define PLLS3C2410_MDIV_MASK (0xff) 709 #define PLLS3C2410_PDIV_MASK (0x1f) 710 #define PLLS3C2410_SDIV_MASK (0x3) 711 #define PLLS3C2410_MDIV_SHIFT (12) 712 #define PLLS3C2410_PDIV_SHIFT (4) 713 #define PLLS3C2410_SDIV_SHIFT (0) 714 715 #define PLLS3C2410_ENABLE_REG_OFFSET 0x10 716 717 static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw, 718 unsigned long parent_rate) 719 { 720 struct samsung_clk_pll *pll = to_clk_pll(hw); 721 u32 pll_con, mdiv, pdiv, sdiv; 722 u64 fvco = parent_rate; 723 724 pll_con = __raw_readl(pll->con_reg); 725 mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK; 726 pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK; 727 sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK; 728 729 fvco *= (mdiv + 8); 730 do_div(fvco, (pdiv + 2) << sdiv); 731 732 return (unsigned int)fvco; 733 } 734 735 static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw, 736 unsigned long parent_rate) 737 { 738 struct samsung_clk_pll *pll = to_clk_pll(hw); 739 u32 pll_con, mdiv, pdiv, sdiv; 740 u64 fvco = parent_rate; 741 742 pll_con = __raw_readl(pll->con_reg); 743 mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK; 744 pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK; 745 sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK; 746 747 fvco *= (2 * (mdiv + 8)); 748 do_div(fvco, (pdiv + 2) << sdiv); 749 750 return (unsigned int)fvco; 751 } 752 753 static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate, 754 unsigned long prate) 755 { 756 struct samsung_clk_pll *pll = to_clk_pll(hw); 757 const struct samsung_pll_rate_table *rate; 758 u32 tmp; 759 760 /* Get required rate settings from table */ 761 rate = samsung_get_pll_settings(pll, drate); 762 if (!rate) { 763 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 764 drate, __clk_get_name(hw->clk)); 765 return -EINVAL; 766 } 767 768 tmp = __raw_readl(pll->con_reg); 769 770 /* Change PLL PMS values */ 771 tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) | 772 (PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) | 773 (PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT)); 774 tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) | 775 (rate->pdiv << PLLS3C2410_PDIV_SHIFT) | 776 (rate->sdiv << PLLS3C2410_SDIV_SHIFT); 777 __raw_writel(tmp, pll->con_reg); 778 779 /* Time to settle according to the manual */ 780 udelay(300); 781 782 return 0; 783 } 784 785 static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable) 786 { 787 struct samsung_clk_pll *pll = to_clk_pll(hw); 788 u32 pll_en = __raw_readl(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET); 789 u32 pll_en_orig = pll_en; 790 791 if (enable) 792 pll_en &= ~BIT(bit); 793 else 794 pll_en |= BIT(bit); 795 796 __raw_writel(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET); 797 798 /* if we started the UPLL, then allow to settle */ 799 if (enable && (pll_en_orig & BIT(bit))) 800 udelay(300); 801 802 return 0; 803 } 804 805 static int samsung_s3c2410_mpll_enable(struct clk_hw *hw) 806 { 807 return samsung_s3c2410_pll_enable(hw, 5, true); 808 } 809 810 static void samsung_s3c2410_mpll_disable(struct clk_hw *hw) 811 { 812 samsung_s3c2410_pll_enable(hw, 5, false); 813 } 814 815 static int samsung_s3c2410_upll_enable(struct clk_hw *hw) 816 { 817 return samsung_s3c2410_pll_enable(hw, 7, true); 818 } 819 820 static void samsung_s3c2410_upll_disable(struct clk_hw *hw) 821 { 822 samsung_s3c2410_pll_enable(hw, 7, false); 823 } 824 825 static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = { 826 .recalc_rate = samsung_s3c2410_pll_recalc_rate, 827 .enable = samsung_s3c2410_mpll_enable, 828 .disable = samsung_s3c2410_mpll_disable, 829 }; 830 831 static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = { 832 .recalc_rate = samsung_s3c2410_pll_recalc_rate, 833 .enable = samsung_s3c2410_upll_enable, 834 .disable = samsung_s3c2410_upll_disable, 835 }; 836 837 static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = { 838 .recalc_rate = samsung_s3c2440_mpll_recalc_rate, 839 .enable = samsung_s3c2410_mpll_enable, 840 .disable = samsung_s3c2410_mpll_disable, 841 }; 842 843 static const struct clk_ops samsung_s3c2410_mpll_clk_ops = { 844 .recalc_rate = samsung_s3c2410_pll_recalc_rate, 845 .enable = samsung_s3c2410_mpll_enable, 846 .disable = samsung_s3c2410_mpll_disable, 847 .round_rate = samsung_pll_round_rate, 848 .set_rate = samsung_s3c2410_pll_set_rate, 849 }; 850 851 static const struct clk_ops samsung_s3c2410_upll_clk_ops = { 852 .recalc_rate = samsung_s3c2410_pll_recalc_rate, 853 .enable = samsung_s3c2410_upll_enable, 854 .disable = samsung_s3c2410_upll_disable, 855 .round_rate = samsung_pll_round_rate, 856 .set_rate = samsung_s3c2410_pll_set_rate, 857 }; 858 859 static const struct clk_ops samsung_s3c2440_mpll_clk_ops = { 860 .recalc_rate = samsung_s3c2440_mpll_recalc_rate, 861 .enable = samsung_s3c2410_mpll_enable, 862 .disable = samsung_s3c2410_mpll_disable, 863 .round_rate = samsung_pll_round_rate, 864 .set_rate = samsung_s3c2410_pll_set_rate, 865 }; 866 867 /* 868 * PLL2550x Clock Type 869 */ 870 871 #define PLL2550X_R_MASK (0x1) 872 #define PLL2550X_P_MASK (0x3F) 873 #define PLL2550X_M_MASK (0x3FF) 874 #define PLL2550X_S_MASK (0x7) 875 #define PLL2550X_R_SHIFT (20) 876 #define PLL2550X_P_SHIFT (14) 877 #define PLL2550X_M_SHIFT (4) 878 #define PLL2550X_S_SHIFT (0) 879 880 struct samsung_clk_pll2550x { 881 struct clk_hw hw; 882 const void __iomem *reg_base; 883 unsigned long offset; 884 }; 885 886 #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw) 887 888 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw, 889 unsigned long parent_rate) 890 { 891 struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw); 892 u32 r, p, m, s, pll_stat; 893 u64 fvco = parent_rate; 894 895 pll_stat = __raw_readl(pll->reg_base + pll->offset * 3); 896 r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK; 897 if (!r) 898 return 0; 899 p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK; 900 m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK; 901 s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK; 902 903 fvco *= m; 904 do_div(fvco, (p << s)); 905 906 return (unsigned long)fvco; 907 } 908 909 static const struct clk_ops samsung_pll2550x_clk_ops = { 910 .recalc_rate = samsung_pll2550x_recalc_rate, 911 }; 912 913 struct clk * __init samsung_clk_register_pll2550x(const char *name, 914 const char *pname, const void __iomem *reg_base, 915 const unsigned long offset) 916 { 917 struct samsung_clk_pll2550x *pll; 918 struct clk *clk; 919 struct clk_init_data init; 920 921 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 922 if (!pll) { 923 pr_err("%s: could not allocate pll clk %s\n", __func__, name); 924 return NULL; 925 } 926 927 init.name = name; 928 init.ops = &samsung_pll2550x_clk_ops; 929 init.flags = CLK_GET_RATE_NOCACHE; 930 init.parent_names = &pname; 931 init.num_parents = 1; 932 933 pll->hw.init = &init; 934 pll->reg_base = reg_base; 935 pll->offset = offset; 936 937 clk = clk_register(NULL, &pll->hw); 938 if (IS_ERR(clk)) { 939 pr_err("%s: failed to register pll clock %s\n", __func__, 940 name); 941 kfree(pll); 942 } 943 944 if (clk_register_clkdev(clk, name, NULL)) 945 pr_err("%s: failed to register lookup for %s", __func__, name); 946 947 return clk; 948 } 949 950 /* 951 * PLL2550xx Clock Type 952 */ 953 954 /* Maximum lock time can be 270 * PDIV cycles */ 955 #define PLL2550XX_LOCK_FACTOR 270 956 957 #define PLL2550XX_M_MASK 0x3FF 958 #define PLL2550XX_P_MASK 0x3F 959 #define PLL2550XX_S_MASK 0x7 960 #define PLL2550XX_LOCK_STAT_MASK 0x1 961 #define PLL2550XX_M_SHIFT 9 962 #define PLL2550XX_P_SHIFT 3 963 #define PLL2550XX_S_SHIFT 0 964 #define PLL2550XX_LOCK_STAT_SHIFT 21 965 966 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw, 967 unsigned long parent_rate) 968 { 969 struct samsung_clk_pll *pll = to_clk_pll(hw); 970 u32 mdiv, pdiv, sdiv, pll_con; 971 u64 fvco = parent_rate; 972 973 pll_con = __raw_readl(pll->con_reg); 974 mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK; 975 pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK; 976 sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK; 977 978 fvco *= mdiv; 979 do_div(fvco, (pdiv << sdiv)); 980 981 return (unsigned long)fvco; 982 } 983 984 static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con) 985 { 986 u32 old_mdiv, old_pdiv; 987 988 old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK; 989 old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK; 990 991 return mdiv != old_mdiv || pdiv != old_pdiv; 992 } 993 994 static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate, 995 unsigned long prate) 996 { 997 struct samsung_clk_pll *pll = to_clk_pll(hw); 998 const struct samsung_pll_rate_table *rate; 999 u32 tmp; 1000 1001 /* Get required rate settings from table */ 1002 rate = samsung_get_pll_settings(pll, drate); 1003 if (!rate) { 1004 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 1005 drate, __clk_get_name(hw->clk)); 1006 return -EINVAL; 1007 } 1008 1009 tmp = __raw_readl(pll->con_reg); 1010 1011 if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) { 1012 /* If only s change, change just s value only*/ 1013 tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT); 1014 tmp |= rate->sdiv << PLL2550XX_S_SHIFT; 1015 __raw_writel(tmp, pll->con_reg); 1016 1017 return 0; 1018 } 1019 1020 /* Set PLL lock time. */ 1021 __raw_writel(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg); 1022 1023 /* Change PLL PMS values */ 1024 tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) | 1025 (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) | 1026 (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT)); 1027 tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) | 1028 (rate->pdiv << PLL2550XX_P_SHIFT) | 1029 (rate->sdiv << PLL2550XX_S_SHIFT); 1030 __raw_writel(tmp, pll->con_reg); 1031 1032 /* wait_lock_time */ 1033 do { 1034 cpu_relax(); 1035 tmp = __raw_readl(pll->con_reg); 1036 } while (!(tmp & (PLL2550XX_LOCK_STAT_MASK 1037 << PLL2550XX_LOCK_STAT_SHIFT))); 1038 1039 return 0; 1040 } 1041 1042 static const struct clk_ops samsung_pll2550xx_clk_ops = { 1043 .recalc_rate = samsung_pll2550xx_recalc_rate, 1044 .round_rate = samsung_pll_round_rate, 1045 .set_rate = samsung_pll2550xx_set_rate, 1046 }; 1047 1048 static const struct clk_ops samsung_pll2550xx_clk_min_ops = { 1049 .recalc_rate = samsung_pll2550xx_recalc_rate, 1050 }; 1051 1052 /* 1053 * PLL2650XX Clock Type 1054 */ 1055 1056 /* Maximum lock time can be 3000 * PDIV cycles */ 1057 #define PLL2650XX_LOCK_FACTOR 3000 1058 1059 #define PLL2650XX_MDIV_SHIFT 9 1060 #define PLL2650XX_PDIV_SHIFT 3 1061 #define PLL2650XX_SDIV_SHIFT 0 1062 #define PLL2650XX_KDIV_SHIFT 0 1063 #define PLL2650XX_MDIV_MASK 0x1ff 1064 #define PLL2650XX_PDIV_MASK 0x3f 1065 #define PLL2650XX_SDIV_MASK 0x7 1066 #define PLL2650XX_KDIV_MASK 0xffff 1067 #define PLL2650XX_PLL_ENABLE_SHIFT 23 1068 #define PLL2650XX_PLL_LOCKTIME_SHIFT 21 1069 #define PLL2650XX_PLL_FOUTMASK_SHIFT 31 1070 1071 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw, 1072 unsigned long parent_rate) 1073 { 1074 struct samsung_clk_pll *pll = to_clk_pll(hw); 1075 u32 mdiv, pdiv, sdiv, pll_con0, pll_con2; 1076 s16 kdiv; 1077 u64 fvco = parent_rate; 1078 1079 pll_con0 = __raw_readl(pll->con_reg); 1080 pll_con2 = __raw_readl(pll->con_reg + 8); 1081 mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK; 1082 pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK; 1083 sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK; 1084 kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK); 1085 1086 fvco *= (mdiv << 16) + kdiv; 1087 do_div(fvco, (pdiv << sdiv)); 1088 fvco >>= 16; 1089 1090 return (unsigned long)fvco; 1091 } 1092 1093 static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate, 1094 unsigned long parent_rate) 1095 { 1096 struct samsung_clk_pll *pll = to_clk_pll(hw); 1097 u32 tmp, pll_con0, pll_con2; 1098 const struct samsung_pll_rate_table *rate; 1099 1100 rate = samsung_get_pll_settings(pll, drate); 1101 if (!rate) { 1102 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 1103 drate, __clk_get_name(hw->clk)); 1104 return -EINVAL; 1105 } 1106 1107 pll_con0 = __raw_readl(pll->con_reg); 1108 pll_con2 = __raw_readl(pll->con_reg + 8); 1109 1110 /* Change PLL PMS values */ 1111 pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT | 1112 PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT | 1113 PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT); 1114 pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT; 1115 pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT; 1116 pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT; 1117 pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT; 1118 pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT; 1119 1120 pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT); 1121 pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK) 1122 << PLL2650XX_KDIV_SHIFT; 1123 1124 /* Set PLL lock time. */ 1125 __raw_writel(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg); 1126 1127 __raw_writel(pll_con0, pll->con_reg); 1128 __raw_writel(pll_con2, pll->con_reg + 8); 1129 1130 do { 1131 tmp = __raw_readl(pll->con_reg); 1132 } while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT))); 1133 1134 return 0; 1135 } 1136 1137 static const struct clk_ops samsung_pll2650xx_clk_ops = { 1138 .recalc_rate = samsung_pll2650xx_recalc_rate, 1139 .set_rate = samsung_pll2650xx_set_rate, 1140 .round_rate = samsung_pll_round_rate, 1141 }; 1142 1143 static const struct clk_ops samsung_pll2650xx_clk_min_ops = { 1144 .recalc_rate = samsung_pll2650xx_recalc_rate, 1145 }; 1146 1147 static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, 1148 struct samsung_pll_clock *pll_clk, 1149 void __iomem *base) 1150 { 1151 struct samsung_clk_pll *pll; 1152 struct clk *clk; 1153 struct clk_init_data init; 1154 int ret, len; 1155 1156 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 1157 if (!pll) { 1158 pr_err("%s: could not allocate pll clk %s\n", 1159 __func__, pll_clk->name); 1160 return; 1161 } 1162 1163 init.name = pll_clk->name; 1164 init.flags = pll_clk->flags; 1165 init.parent_names = &pll_clk->parent_name; 1166 init.num_parents = 1; 1167 1168 if (pll_clk->rate_table) { 1169 /* find count of rates in rate_table */ 1170 for (len = 0; pll_clk->rate_table[len].rate != 0; ) 1171 len++; 1172 1173 pll->rate_count = len; 1174 pll->rate_table = kmemdup(pll_clk->rate_table, 1175 pll->rate_count * 1176 sizeof(struct samsung_pll_rate_table), 1177 GFP_KERNEL); 1178 WARN(!pll->rate_table, 1179 "%s: could not allocate rate table for %s\n", 1180 __func__, pll_clk->name); 1181 } 1182 1183 switch (pll_clk->type) { 1184 case pll_2126: 1185 init.ops = &samsung_pll2126_clk_ops; 1186 break; 1187 case pll_3000: 1188 init.ops = &samsung_pll3000_clk_ops; 1189 break; 1190 /* clk_ops for 35xx and 2550 are similar */ 1191 case pll_35xx: 1192 case pll_2550: 1193 if (!pll->rate_table) 1194 init.ops = &samsung_pll35xx_clk_min_ops; 1195 else 1196 init.ops = &samsung_pll35xx_clk_ops; 1197 break; 1198 case pll_4500: 1199 init.ops = &samsung_pll45xx_clk_min_ops; 1200 break; 1201 case pll_4502: 1202 case pll_4508: 1203 if (!pll->rate_table) 1204 init.ops = &samsung_pll45xx_clk_min_ops; 1205 else 1206 init.ops = &samsung_pll45xx_clk_ops; 1207 break; 1208 /* clk_ops for 36xx and 2650 are similar */ 1209 case pll_36xx: 1210 case pll_2650: 1211 if (!pll->rate_table) 1212 init.ops = &samsung_pll36xx_clk_min_ops; 1213 else 1214 init.ops = &samsung_pll36xx_clk_ops; 1215 break; 1216 case pll_6552: 1217 case pll_6552_s3c2416: 1218 init.ops = &samsung_pll6552_clk_ops; 1219 break; 1220 case pll_6553: 1221 init.ops = &samsung_pll6553_clk_ops; 1222 break; 1223 case pll_4600: 1224 case pll_4650: 1225 case pll_4650c: 1226 if (!pll->rate_table) 1227 init.ops = &samsung_pll46xx_clk_min_ops; 1228 else 1229 init.ops = &samsung_pll46xx_clk_ops; 1230 break; 1231 case pll_s3c2410_mpll: 1232 if (!pll->rate_table) 1233 init.ops = &samsung_s3c2410_mpll_clk_min_ops; 1234 else 1235 init.ops = &samsung_s3c2410_mpll_clk_ops; 1236 break; 1237 case pll_s3c2410_upll: 1238 if (!pll->rate_table) 1239 init.ops = &samsung_s3c2410_upll_clk_min_ops; 1240 else 1241 init.ops = &samsung_s3c2410_upll_clk_ops; 1242 break; 1243 case pll_s3c2440_mpll: 1244 if (!pll->rate_table) 1245 init.ops = &samsung_s3c2440_mpll_clk_min_ops; 1246 else 1247 init.ops = &samsung_s3c2440_mpll_clk_ops; 1248 break; 1249 case pll_2550xx: 1250 if (!pll->rate_table) 1251 init.ops = &samsung_pll2550xx_clk_min_ops; 1252 else 1253 init.ops = &samsung_pll2550xx_clk_ops; 1254 break; 1255 case pll_2650xx: 1256 if (!pll->rate_table) 1257 init.ops = &samsung_pll2650xx_clk_min_ops; 1258 else 1259 init.ops = &samsung_pll2650xx_clk_ops; 1260 break; 1261 default: 1262 pr_warn("%s: Unknown pll type for pll clk %s\n", 1263 __func__, pll_clk->name); 1264 } 1265 1266 pll->hw.init = &init; 1267 pll->type = pll_clk->type; 1268 pll->lock_reg = base + pll_clk->lock_offset; 1269 pll->con_reg = base + pll_clk->con_offset; 1270 1271 clk = clk_register(NULL, &pll->hw); 1272 if (IS_ERR(clk)) { 1273 pr_err("%s: failed to register pll clock %s : %ld\n", 1274 __func__, pll_clk->name, PTR_ERR(clk)); 1275 kfree(pll); 1276 return; 1277 } 1278 1279 samsung_clk_add_lookup(ctx, clk, pll_clk->id); 1280 1281 if (!pll_clk->alias) 1282 return; 1283 1284 ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name); 1285 if (ret) 1286 pr_err("%s: failed to register lookup for %s : %d", 1287 __func__, pll_clk->name, ret); 1288 } 1289 1290 void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, 1291 struct samsung_pll_clock *pll_list, 1292 unsigned int nr_pll, void __iomem *base) 1293 { 1294 int cnt; 1295 1296 for (cnt = 0; cnt < nr_pll; cnt++) 1297 _samsung_clk_register_pll(ctx, &pll_list[cnt], base); 1298 } 1299