1 /* 2 * Copyright (c) 2014 MundoReader S.L. 3 * Author: Heiko Stuebner <heiko@sntech.de> 4 * 5 * Copyright (c) 2015 Rockchip Electronics Co. Ltd. 6 * Author: Xing Zheng <zhengxing@rock-chips.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #include <asm/div64.h> 20 #include <linux/slab.h> 21 #include <linux/io.h> 22 #include <linux/delay.h> 23 #include <linux/clk-provider.h> 24 #include <linux/regmap.h> 25 #include <linux/clk.h> 26 #include "clk.h" 27 28 #define PLL_MODE_MASK 0x3 29 #define PLL_MODE_SLOW 0x0 30 #define PLL_MODE_NORM 0x1 31 #define PLL_MODE_DEEP 0x2 32 33 struct rockchip_clk_pll { 34 struct clk_hw hw; 35 36 struct clk_mux pll_mux; 37 const struct clk_ops *pll_mux_ops; 38 39 struct notifier_block clk_nb; 40 41 void __iomem *reg_base; 42 int lock_offset; 43 unsigned int lock_shift; 44 enum rockchip_pll_type type; 45 u8 flags; 46 const struct rockchip_pll_rate_table *rate_table; 47 unsigned int rate_count; 48 spinlock_t *lock; 49 50 struct rockchip_clk_provider *ctx; 51 }; 52 53 #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw) 54 #define to_rockchip_clk_pll_nb(nb) \ 55 container_of(nb, struct rockchip_clk_pll, clk_nb) 56 57 static const struct rockchip_pll_rate_table *rockchip_get_pll_settings( 58 struct rockchip_clk_pll *pll, unsigned long rate) 59 { 60 const struct rockchip_pll_rate_table *rate_table = pll->rate_table; 61 int i; 62 63 for (i = 0; i < pll->rate_count; i++) { 64 if (rate == rate_table[i].rate) 65 return &rate_table[i]; 66 } 67 68 return NULL; 69 } 70 71 static long rockchip_pll_round_rate(struct clk_hw *hw, 72 unsigned long drate, unsigned long *prate) 73 { 74 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 75 const struct rockchip_pll_rate_table *rate_table = pll->rate_table; 76 int i; 77 78 /* Assumming rate_table is in descending order */ 79 for (i = 0; i < pll->rate_count; i++) { 80 if (drate >= rate_table[i].rate) 81 return rate_table[i].rate; 82 } 83 84 /* return minimum supported value */ 85 return rate_table[i - 1].rate; 86 } 87 88 /* 89 * Wait for the pll to reach the locked state. 90 * The calling set_rate function is responsible for making sure the 91 * grf regmap is available. 92 */ 93 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) 94 { 95 struct regmap *grf = pll->ctx->grf; 96 unsigned int val; 97 int delay = 24000000, ret; 98 99 while (delay > 0) { 100 ret = regmap_read(grf, pll->lock_offset, &val); 101 if (ret) { 102 pr_err("%s: failed to read pll lock status: %d\n", 103 __func__, ret); 104 return ret; 105 } 106 107 if (val & BIT(pll->lock_shift)) 108 return 0; 109 delay--; 110 } 111 112 pr_err("%s: timeout waiting for pll to lock\n", __func__); 113 return -ETIMEDOUT; 114 } 115 116 /** 117 * PLL used in RK3036 118 */ 119 120 #define RK3036_PLLCON(i) (i * 0x4) 121 #define RK3036_PLLCON0_FBDIV_MASK 0xfff 122 #define RK3036_PLLCON0_FBDIV_SHIFT 0 123 #define RK3036_PLLCON0_POSTDIV1_MASK 0x7 124 #define RK3036_PLLCON0_POSTDIV1_SHIFT 12 125 #define RK3036_PLLCON1_REFDIV_MASK 0x3f 126 #define RK3036_PLLCON1_REFDIV_SHIFT 0 127 #define RK3036_PLLCON1_POSTDIV2_MASK 0x7 128 #define RK3036_PLLCON1_POSTDIV2_SHIFT 6 129 #define RK3036_PLLCON1_DSMPD_MASK 0x1 130 #define RK3036_PLLCON1_DSMPD_SHIFT 12 131 #define RK3036_PLLCON2_FRAC_MASK 0xffffff 132 #define RK3036_PLLCON2_FRAC_SHIFT 0 133 134 #define RK3036_PLLCON1_PWRDOWN (1 << 13) 135 136 static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll, 137 struct rockchip_pll_rate_table *rate) 138 { 139 u32 pllcon; 140 141 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0)); 142 rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT) 143 & RK3036_PLLCON0_FBDIV_MASK); 144 rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT) 145 & RK3036_PLLCON0_POSTDIV1_MASK); 146 147 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1)); 148 rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT) 149 & RK3036_PLLCON1_REFDIV_MASK); 150 rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT) 151 & RK3036_PLLCON1_POSTDIV2_MASK); 152 rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT) 153 & RK3036_PLLCON1_DSMPD_MASK); 154 155 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2)); 156 rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT) 157 & RK3036_PLLCON2_FRAC_MASK); 158 } 159 160 static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw, 161 unsigned long prate) 162 { 163 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 164 struct rockchip_pll_rate_table cur; 165 u64 rate64 = prate; 166 167 rockchip_rk3036_pll_get_params(pll, &cur); 168 169 rate64 *= cur.fbdiv; 170 do_div(rate64, cur.refdiv); 171 172 if (cur.dsmpd == 0) { 173 /* fractional mode */ 174 u64 frac_rate64 = prate * cur.frac; 175 176 do_div(frac_rate64, cur.refdiv); 177 rate64 += frac_rate64 >> 24; 178 } 179 180 do_div(rate64, cur.postdiv1); 181 do_div(rate64, cur.postdiv2); 182 183 return (unsigned long)rate64; 184 } 185 186 static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll, 187 const struct rockchip_pll_rate_table *rate) 188 { 189 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; 190 struct clk_mux *pll_mux = &pll->pll_mux; 191 struct rockchip_pll_rate_table cur; 192 u32 pllcon; 193 int rate_change_remuxed = 0; 194 int cur_parent; 195 int ret; 196 197 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 198 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv, 199 rate->postdiv2, rate->dsmpd, rate->frac); 200 201 rockchip_rk3036_pll_get_params(pll, &cur); 202 cur.rate = 0; 203 204 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); 205 if (cur_parent == PLL_MODE_NORM) { 206 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); 207 rate_change_remuxed = 1; 208 } 209 210 /* update pll values */ 211 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK, 212 RK3036_PLLCON0_FBDIV_SHIFT) | 213 HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK, 214 RK3036_PLLCON0_POSTDIV1_SHIFT), 215 pll->reg_base + RK3036_PLLCON(0)); 216 217 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK, 218 RK3036_PLLCON1_REFDIV_SHIFT) | 219 HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK, 220 RK3036_PLLCON1_POSTDIV2_SHIFT) | 221 HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK, 222 RK3036_PLLCON1_DSMPD_SHIFT), 223 pll->reg_base + RK3036_PLLCON(1)); 224 225 /* GPLL CON2 is not HIWORD_MASK */ 226 pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2)); 227 pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT); 228 pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT; 229 writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2)); 230 231 /* wait for the pll to lock */ 232 ret = rockchip_pll_wait_lock(pll); 233 if (ret) { 234 pr_warn("%s: pll update unsuccessful, trying to restore old params\n", 235 __func__); 236 rockchip_rk3036_pll_set_params(pll, &cur); 237 } 238 239 if (rate_change_remuxed) 240 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); 241 242 return ret; 243 } 244 245 static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate, 246 unsigned long prate) 247 { 248 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 249 const struct rockchip_pll_rate_table *rate; 250 251 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n", 252 __func__, __clk_get_name(hw->clk), drate, prate); 253 254 /* Get required rate settings from table */ 255 rate = rockchip_get_pll_settings(pll, drate); 256 if (!rate) { 257 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 258 drate, __clk_get_name(hw->clk)); 259 return -EINVAL; 260 } 261 262 return rockchip_rk3036_pll_set_params(pll, rate); 263 } 264 265 static int rockchip_rk3036_pll_enable(struct clk_hw *hw) 266 { 267 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 268 269 writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0), 270 pll->reg_base + RK3036_PLLCON(1)); 271 272 return 0; 273 } 274 275 static void rockchip_rk3036_pll_disable(struct clk_hw *hw) 276 { 277 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 278 279 writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN, 280 RK3036_PLLCON1_PWRDOWN, 0), 281 pll->reg_base + RK3036_PLLCON(1)); 282 } 283 284 static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw) 285 { 286 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 287 u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1)); 288 289 return !(pllcon & RK3036_PLLCON1_PWRDOWN); 290 } 291 292 static void rockchip_rk3036_pll_init(struct clk_hw *hw) 293 { 294 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 295 const struct rockchip_pll_rate_table *rate; 296 struct rockchip_pll_rate_table cur; 297 unsigned long drate; 298 299 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) 300 return; 301 302 drate = clk_hw_get_rate(hw); 303 rate = rockchip_get_pll_settings(pll, drate); 304 305 /* when no rate setting for the current rate, rely on clk_set_rate */ 306 if (!rate) 307 return; 308 309 rockchip_rk3036_pll_get_params(pll, &cur); 310 311 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk), 312 drate); 313 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 314 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2, 315 cur.dsmpd, cur.frac); 316 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 317 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, 318 rate->dsmpd, rate->frac); 319 320 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 || 321 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 || 322 rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) { 323 struct clk *parent = clk_get_parent(hw->clk); 324 325 if (!parent) { 326 pr_warn("%s: parent of %s not available\n", 327 __func__, __clk_get_name(hw->clk)); 328 return; 329 } 330 331 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", 332 __func__, __clk_get_name(hw->clk)); 333 rockchip_rk3036_pll_set_params(pll, rate); 334 } 335 } 336 337 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = { 338 .recalc_rate = rockchip_rk3036_pll_recalc_rate, 339 .enable = rockchip_rk3036_pll_enable, 340 .disable = rockchip_rk3036_pll_disable, 341 .is_enabled = rockchip_rk3036_pll_is_enabled, 342 }; 343 344 static const struct clk_ops rockchip_rk3036_pll_clk_ops = { 345 .recalc_rate = rockchip_rk3036_pll_recalc_rate, 346 .round_rate = rockchip_pll_round_rate, 347 .set_rate = rockchip_rk3036_pll_set_rate, 348 .enable = rockchip_rk3036_pll_enable, 349 .disable = rockchip_rk3036_pll_disable, 350 .is_enabled = rockchip_rk3036_pll_is_enabled, 351 .init = rockchip_rk3036_pll_init, 352 }; 353 354 /** 355 * PLL used in RK3066, RK3188 and RK3288 356 */ 357 358 #define RK3066_PLL_RESET_DELAY(nr) ((nr * 500) / 24 + 1) 359 360 #define RK3066_PLLCON(i) (i * 0x4) 361 #define RK3066_PLLCON0_OD_MASK 0xf 362 #define RK3066_PLLCON0_OD_SHIFT 0 363 #define RK3066_PLLCON0_NR_MASK 0x3f 364 #define RK3066_PLLCON0_NR_SHIFT 8 365 #define RK3066_PLLCON1_NF_MASK 0x1fff 366 #define RK3066_PLLCON1_NF_SHIFT 0 367 #define RK3066_PLLCON2_NB_MASK 0xfff 368 #define RK3066_PLLCON2_NB_SHIFT 0 369 #define RK3066_PLLCON3_RESET (1 << 5) 370 #define RK3066_PLLCON3_PWRDOWN (1 << 1) 371 #define RK3066_PLLCON3_BYPASS (1 << 0) 372 373 static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll, 374 struct rockchip_pll_rate_table *rate) 375 { 376 u32 pllcon; 377 378 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); 379 rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) 380 & RK3066_PLLCON0_NR_MASK) + 1; 381 rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) 382 & RK3066_PLLCON0_OD_MASK) + 1; 383 384 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); 385 rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) 386 & RK3066_PLLCON1_NF_MASK) + 1; 387 388 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2)); 389 rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) 390 & RK3066_PLLCON2_NB_MASK) + 1; 391 } 392 393 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw, 394 unsigned long prate) 395 { 396 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 397 struct rockchip_pll_rate_table cur; 398 u64 rate64 = prate; 399 u32 pllcon; 400 401 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3)); 402 if (pllcon & RK3066_PLLCON3_BYPASS) { 403 pr_debug("%s: pll %s is bypassed\n", __func__, 404 clk_hw_get_name(hw)); 405 return prate; 406 } 407 408 rockchip_rk3066_pll_get_params(pll, &cur); 409 410 rate64 *= cur.nf; 411 do_div(rate64, cur.nr); 412 do_div(rate64, cur.no); 413 414 return (unsigned long)rate64; 415 } 416 417 static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll, 418 const struct rockchip_pll_rate_table *rate) 419 { 420 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; 421 struct clk_mux *pll_mux = &pll->pll_mux; 422 struct rockchip_pll_rate_table cur; 423 int rate_change_remuxed = 0; 424 int cur_parent; 425 int ret; 426 427 pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n", 428 __func__, rate->rate, rate->nr, rate->no, rate->nf); 429 430 rockchip_rk3066_pll_get_params(pll, &cur); 431 cur.rate = 0; 432 433 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); 434 if (cur_parent == PLL_MODE_NORM) { 435 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); 436 rate_change_remuxed = 1; 437 } 438 439 /* enter reset mode */ 440 writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0), 441 pll->reg_base + RK3066_PLLCON(3)); 442 443 /* update pll values */ 444 writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK, 445 RK3066_PLLCON0_NR_SHIFT) | 446 HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK, 447 RK3066_PLLCON0_OD_SHIFT), 448 pll->reg_base + RK3066_PLLCON(0)); 449 450 writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK, 451 RK3066_PLLCON1_NF_SHIFT), 452 pll->reg_base + RK3066_PLLCON(1)); 453 writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK, 454 RK3066_PLLCON2_NB_SHIFT), 455 pll->reg_base + RK3066_PLLCON(2)); 456 457 /* leave reset and wait the reset_delay */ 458 writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0), 459 pll->reg_base + RK3066_PLLCON(3)); 460 udelay(RK3066_PLL_RESET_DELAY(rate->nr)); 461 462 /* wait for the pll to lock */ 463 ret = rockchip_pll_wait_lock(pll); 464 if (ret) { 465 pr_warn("%s: pll update unsuccessful, trying to restore old params\n", 466 __func__); 467 rockchip_rk3066_pll_set_params(pll, &cur); 468 } 469 470 if (rate_change_remuxed) 471 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); 472 473 return ret; 474 } 475 476 static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, 477 unsigned long prate) 478 { 479 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 480 const struct rockchip_pll_rate_table *rate; 481 482 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n", 483 __func__, clk_hw_get_name(hw), drate, prate); 484 485 /* Get required rate settings from table */ 486 rate = rockchip_get_pll_settings(pll, drate); 487 if (!rate) { 488 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 489 drate, clk_hw_get_name(hw)); 490 return -EINVAL; 491 } 492 493 return rockchip_rk3066_pll_set_params(pll, rate); 494 } 495 496 static int rockchip_rk3066_pll_enable(struct clk_hw *hw) 497 { 498 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 499 500 writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0), 501 pll->reg_base + RK3066_PLLCON(3)); 502 503 return 0; 504 } 505 506 static void rockchip_rk3066_pll_disable(struct clk_hw *hw) 507 { 508 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 509 510 writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN, 511 RK3066_PLLCON3_PWRDOWN, 0), 512 pll->reg_base + RK3066_PLLCON(3)); 513 } 514 515 static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw) 516 { 517 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 518 u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3)); 519 520 return !(pllcon & RK3066_PLLCON3_PWRDOWN); 521 } 522 523 static void rockchip_rk3066_pll_init(struct clk_hw *hw) 524 { 525 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 526 const struct rockchip_pll_rate_table *rate; 527 struct rockchip_pll_rate_table cur; 528 unsigned long drate; 529 530 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) 531 return; 532 533 drate = clk_hw_get_rate(hw); 534 rate = rockchip_get_pll_settings(pll, drate); 535 536 /* when no rate setting for the current rate, rely on clk_set_rate */ 537 if (!rate) 538 return; 539 540 rockchip_rk3066_pll_get_params(pll, &cur); 541 542 pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n", 543 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr, 544 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb); 545 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf 546 || rate->nb != cur.nb) { 547 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", 548 __func__, clk_hw_get_name(hw)); 549 rockchip_rk3066_pll_set_params(pll, rate); 550 } 551 } 552 553 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { 554 .recalc_rate = rockchip_rk3066_pll_recalc_rate, 555 .enable = rockchip_rk3066_pll_enable, 556 .disable = rockchip_rk3066_pll_disable, 557 .is_enabled = rockchip_rk3066_pll_is_enabled, 558 }; 559 560 static const struct clk_ops rockchip_rk3066_pll_clk_ops = { 561 .recalc_rate = rockchip_rk3066_pll_recalc_rate, 562 .round_rate = rockchip_pll_round_rate, 563 .set_rate = rockchip_rk3066_pll_set_rate, 564 .enable = rockchip_rk3066_pll_enable, 565 .disable = rockchip_rk3066_pll_disable, 566 .is_enabled = rockchip_rk3066_pll_is_enabled, 567 .init = rockchip_rk3066_pll_init, 568 }; 569 570 /** 571 * PLL used in RK3399 572 */ 573 574 #define RK3399_PLLCON(i) (i * 0x4) 575 #define RK3399_PLLCON0_FBDIV_MASK 0xfff 576 #define RK3399_PLLCON0_FBDIV_SHIFT 0 577 #define RK3399_PLLCON1_REFDIV_MASK 0x3f 578 #define RK3399_PLLCON1_REFDIV_SHIFT 0 579 #define RK3399_PLLCON1_POSTDIV1_MASK 0x7 580 #define RK3399_PLLCON1_POSTDIV1_SHIFT 8 581 #define RK3399_PLLCON1_POSTDIV2_MASK 0x7 582 #define RK3399_PLLCON1_POSTDIV2_SHIFT 12 583 #define RK3399_PLLCON2_FRAC_MASK 0xffffff 584 #define RK3399_PLLCON2_FRAC_SHIFT 0 585 #define RK3399_PLLCON2_LOCK_STATUS BIT(31) 586 #define RK3399_PLLCON3_PWRDOWN BIT(0) 587 #define RK3399_PLLCON3_DSMPD_MASK 0x1 588 #define RK3399_PLLCON3_DSMPD_SHIFT 3 589 590 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll) 591 { 592 u32 pllcon; 593 int delay = 24000000; 594 595 /* poll check the lock status in rk3399 xPLLCON2 */ 596 while (delay > 0) { 597 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); 598 if (pllcon & RK3399_PLLCON2_LOCK_STATUS) 599 return 0; 600 601 delay--; 602 } 603 604 pr_err("%s: timeout waiting for pll to lock\n", __func__); 605 return -ETIMEDOUT; 606 } 607 608 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll, 609 struct rockchip_pll_rate_table *rate) 610 { 611 u32 pllcon; 612 613 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0)); 614 rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT) 615 & RK3399_PLLCON0_FBDIV_MASK); 616 617 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1)); 618 rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT) 619 & RK3399_PLLCON1_REFDIV_MASK); 620 rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT) 621 & RK3399_PLLCON1_POSTDIV1_MASK); 622 rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT) 623 & RK3399_PLLCON1_POSTDIV2_MASK); 624 625 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); 626 rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT) 627 & RK3399_PLLCON2_FRAC_MASK); 628 629 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3)); 630 rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT) 631 & RK3399_PLLCON3_DSMPD_MASK); 632 } 633 634 static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw, 635 unsigned long prate) 636 { 637 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 638 struct rockchip_pll_rate_table cur; 639 u64 rate64 = prate; 640 641 rockchip_rk3399_pll_get_params(pll, &cur); 642 643 rate64 *= cur.fbdiv; 644 do_div(rate64, cur.refdiv); 645 646 if (cur.dsmpd == 0) { 647 /* fractional mode */ 648 u64 frac_rate64 = prate * cur.frac; 649 650 do_div(frac_rate64, cur.refdiv); 651 rate64 += frac_rate64 >> 24; 652 } 653 654 do_div(rate64, cur.postdiv1); 655 do_div(rate64, cur.postdiv2); 656 657 return (unsigned long)rate64; 658 } 659 660 static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll, 661 const struct rockchip_pll_rate_table *rate) 662 { 663 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; 664 struct clk_mux *pll_mux = &pll->pll_mux; 665 struct rockchip_pll_rate_table cur; 666 u32 pllcon; 667 int rate_change_remuxed = 0; 668 int cur_parent; 669 int ret; 670 671 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 672 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv, 673 rate->postdiv2, rate->dsmpd, rate->frac); 674 675 rockchip_rk3399_pll_get_params(pll, &cur); 676 cur.rate = 0; 677 678 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); 679 if (cur_parent == PLL_MODE_NORM) { 680 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); 681 rate_change_remuxed = 1; 682 } 683 684 /* update pll values */ 685 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK, 686 RK3399_PLLCON0_FBDIV_SHIFT), 687 pll->reg_base + RK3399_PLLCON(0)); 688 689 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK, 690 RK3399_PLLCON1_REFDIV_SHIFT) | 691 HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK, 692 RK3399_PLLCON1_POSTDIV1_SHIFT) | 693 HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK, 694 RK3399_PLLCON1_POSTDIV2_SHIFT), 695 pll->reg_base + RK3399_PLLCON(1)); 696 697 /* xPLL CON2 is not HIWORD_MASK */ 698 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); 699 pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT); 700 pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT; 701 writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2)); 702 703 writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK, 704 RK3399_PLLCON3_DSMPD_SHIFT), 705 pll->reg_base + RK3399_PLLCON(3)); 706 707 /* wait for the pll to lock */ 708 ret = rockchip_rk3399_pll_wait_lock(pll); 709 if (ret) { 710 pr_warn("%s: pll update unsuccessful, trying to restore old params\n", 711 __func__); 712 rockchip_rk3399_pll_set_params(pll, &cur); 713 } 714 715 if (rate_change_remuxed) 716 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); 717 718 return ret; 719 } 720 721 static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate, 722 unsigned long prate) 723 { 724 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 725 const struct rockchip_pll_rate_table *rate; 726 727 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n", 728 __func__, __clk_get_name(hw->clk), drate, prate); 729 730 /* Get required rate settings from table */ 731 rate = rockchip_get_pll_settings(pll, drate); 732 if (!rate) { 733 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 734 drate, __clk_get_name(hw->clk)); 735 return -EINVAL; 736 } 737 738 return rockchip_rk3399_pll_set_params(pll, rate); 739 } 740 741 static int rockchip_rk3399_pll_enable(struct clk_hw *hw) 742 { 743 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 744 745 writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0), 746 pll->reg_base + RK3399_PLLCON(3)); 747 748 return 0; 749 } 750 751 static void rockchip_rk3399_pll_disable(struct clk_hw *hw) 752 { 753 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 754 755 writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN, 756 RK3399_PLLCON3_PWRDOWN, 0), 757 pll->reg_base + RK3399_PLLCON(3)); 758 } 759 760 static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw) 761 { 762 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 763 u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3)); 764 765 return !(pllcon & RK3399_PLLCON3_PWRDOWN); 766 } 767 768 static void rockchip_rk3399_pll_init(struct clk_hw *hw) 769 { 770 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 771 const struct rockchip_pll_rate_table *rate; 772 struct rockchip_pll_rate_table cur; 773 unsigned long drate; 774 775 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) 776 return; 777 778 drate = clk_hw_get_rate(hw); 779 rate = rockchip_get_pll_settings(pll, drate); 780 781 /* when no rate setting for the current rate, rely on clk_set_rate */ 782 if (!rate) 783 return; 784 785 rockchip_rk3399_pll_get_params(pll, &cur); 786 787 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk), 788 drate); 789 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 790 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2, 791 cur.dsmpd, cur.frac); 792 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 793 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, 794 rate->dsmpd, rate->frac); 795 796 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 || 797 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 || 798 rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) { 799 struct clk *parent = clk_get_parent(hw->clk); 800 801 if (!parent) { 802 pr_warn("%s: parent of %s not available\n", 803 __func__, __clk_get_name(hw->clk)); 804 return; 805 } 806 807 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", 808 __func__, __clk_get_name(hw->clk)); 809 rockchip_rk3399_pll_set_params(pll, rate); 810 } 811 } 812 813 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = { 814 .recalc_rate = rockchip_rk3399_pll_recalc_rate, 815 .enable = rockchip_rk3399_pll_enable, 816 .disable = rockchip_rk3399_pll_disable, 817 .is_enabled = rockchip_rk3399_pll_is_enabled, 818 }; 819 820 static const struct clk_ops rockchip_rk3399_pll_clk_ops = { 821 .recalc_rate = rockchip_rk3399_pll_recalc_rate, 822 .round_rate = rockchip_pll_round_rate, 823 .set_rate = rockchip_rk3399_pll_set_rate, 824 .enable = rockchip_rk3399_pll_enable, 825 .disable = rockchip_rk3399_pll_disable, 826 .is_enabled = rockchip_rk3399_pll_is_enabled, 827 .init = rockchip_rk3399_pll_init, 828 }; 829 830 /* 831 * Common registering of pll clocks 832 */ 833 834 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, 835 enum rockchip_pll_type pll_type, 836 const char *name, const char *const *parent_names, 837 u8 num_parents, int con_offset, int grf_lock_offset, 838 int lock_shift, int mode_offset, int mode_shift, 839 struct rockchip_pll_rate_table *rate_table, 840 u8 clk_pll_flags) 841 { 842 const char *pll_parents[3]; 843 struct clk_init_data init; 844 struct rockchip_clk_pll *pll; 845 struct clk_mux *pll_mux; 846 struct clk *pll_clk, *mux_clk; 847 char pll_name[20]; 848 849 if (num_parents != 2) { 850 pr_err("%s: needs two parent clocks\n", __func__); 851 return ERR_PTR(-EINVAL); 852 } 853 854 /* name the actual pll */ 855 snprintf(pll_name, sizeof(pll_name), "pll_%s", name); 856 857 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 858 if (!pll) 859 return ERR_PTR(-ENOMEM); 860 861 /* create the mux on top of the real pll */ 862 pll->pll_mux_ops = &clk_mux_ops; 863 pll_mux = &pll->pll_mux; 864 pll_mux->reg = ctx->reg_base + mode_offset; 865 pll_mux->shift = mode_shift; 866 pll_mux->mask = PLL_MODE_MASK; 867 pll_mux->flags = 0; 868 pll_mux->lock = &ctx->lock; 869 pll_mux->hw.init = &init; 870 871 if (pll_type == pll_rk3036 || 872 pll_type == pll_rk3066 || 873 pll_type == pll_rk3399) 874 pll_mux->flags |= CLK_MUX_HIWORD_MASK; 875 876 /* the actual muxing is xin24m, pll-output, xin32k */ 877 pll_parents[0] = parent_names[0]; 878 pll_parents[1] = pll_name; 879 pll_parents[2] = parent_names[1]; 880 881 init.name = name; 882 init.flags = CLK_SET_RATE_PARENT; 883 init.ops = pll->pll_mux_ops; 884 init.parent_names = pll_parents; 885 init.num_parents = ARRAY_SIZE(pll_parents); 886 887 mux_clk = clk_register(NULL, &pll_mux->hw); 888 if (IS_ERR(mux_clk)) 889 goto err_mux; 890 891 /* now create the actual pll */ 892 init.name = pll_name; 893 894 /* keep all plls untouched for now */ 895 init.flags = CLK_IGNORE_UNUSED; 896 897 init.parent_names = &parent_names[0]; 898 init.num_parents = 1; 899 900 if (rate_table) { 901 int len; 902 903 /* find count of rates in rate_table */ 904 for (len = 0; rate_table[len].rate != 0; ) 905 len++; 906 907 pll->rate_count = len; 908 pll->rate_table = kmemdup(rate_table, 909 pll->rate_count * 910 sizeof(struct rockchip_pll_rate_table), 911 GFP_KERNEL); 912 WARN(!pll->rate_table, 913 "%s: could not allocate rate table for %s\n", 914 __func__, name); 915 } 916 917 switch (pll_type) { 918 case pll_rk3036: 919 if (!pll->rate_table || IS_ERR(ctx->grf)) 920 init.ops = &rockchip_rk3036_pll_clk_norate_ops; 921 else 922 init.ops = &rockchip_rk3036_pll_clk_ops; 923 break; 924 case pll_rk3066: 925 if (!pll->rate_table || IS_ERR(ctx->grf)) 926 init.ops = &rockchip_rk3066_pll_clk_norate_ops; 927 else 928 init.ops = &rockchip_rk3066_pll_clk_ops; 929 break; 930 case pll_rk3399: 931 if (!pll->rate_table) 932 init.ops = &rockchip_rk3399_pll_clk_norate_ops; 933 else 934 init.ops = &rockchip_rk3399_pll_clk_ops; 935 break; 936 default: 937 pr_warn("%s: Unknown pll type for pll clk %s\n", 938 __func__, name); 939 } 940 941 pll->hw.init = &init; 942 pll->type = pll_type; 943 pll->reg_base = ctx->reg_base + con_offset; 944 pll->lock_offset = grf_lock_offset; 945 pll->lock_shift = lock_shift; 946 pll->flags = clk_pll_flags; 947 pll->lock = &ctx->lock; 948 pll->ctx = ctx; 949 950 pll_clk = clk_register(NULL, &pll->hw); 951 if (IS_ERR(pll_clk)) { 952 pr_err("%s: failed to register pll clock %s : %ld\n", 953 __func__, name, PTR_ERR(pll_clk)); 954 goto err_pll; 955 } 956 957 return mux_clk; 958 959 err_pll: 960 clk_unregister(mux_clk); 961 mux_clk = pll_clk; 962 err_mux: 963 kfree(pll); 964 return mux_clk; 965 } 966