1 /* 2 * Copyright (c) 2014 MundoReader S.L. 3 * Author: Heiko Stuebner <heiko@sntech.de> 4 * 5 * Copyright (c) 2016 Rockchip Electronics Co. Ltd. 6 * Author: Xing Zheng <zhengxing@rock-chips.com> 7 * 8 * based on 9 * 10 * samsung/clk.c 11 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 12 * Copyright (c) 2013 Linaro Ltd. 13 * Author: Thomas Abraham <thomas.ab@samsung.com> 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 */ 25 26 #include <linux/slab.h> 27 #include <linux/clk.h> 28 #include <linux/clk-provider.h> 29 #include <linux/mfd/syscon.h> 30 #include <linux/regmap.h> 31 #include <linux/reboot.h> 32 #include <linux/rational.h> 33 #include "clk.h" 34 35 /** 36 * Register a clock branch. 37 * Most clock branches have a form like 38 * 39 * src1 --|--\ 40 * |M |--[GATE]-[DIV]- 41 * src2 --|--/ 42 * 43 * sometimes without one of those components. 44 */ 45 static struct clk *rockchip_clk_register_branch(const char *name, 46 const char *const *parent_names, u8 num_parents, 47 void __iomem *base, 48 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags, 49 u8 div_shift, u8 div_width, u8 div_flags, 50 struct clk_div_table *div_table, int gate_offset, 51 u8 gate_shift, u8 gate_flags, unsigned long flags, 52 spinlock_t *lock) 53 { 54 struct clk *clk; 55 struct clk_mux *mux = NULL; 56 struct clk_gate *gate = NULL; 57 struct clk_divider *div = NULL; 58 const struct clk_ops *mux_ops = NULL, *div_ops = NULL, 59 *gate_ops = NULL; 60 int ret; 61 62 if (num_parents > 1) { 63 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 64 if (!mux) 65 return ERR_PTR(-ENOMEM); 66 67 mux->reg = base + muxdiv_offset; 68 mux->shift = mux_shift; 69 mux->mask = BIT(mux_width) - 1; 70 mux->flags = mux_flags; 71 mux->lock = lock; 72 mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops 73 : &clk_mux_ops; 74 } 75 76 if (gate_offset >= 0) { 77 gate = kzalloc(sizeof(*gate), GFP_KERNEL); 78 if (!gate) { 79 ret = -ENOMEM; 80 goto err_gate; 81 } 82 83 gate->flags = gate_flags; 84 gate->reg = base + gate_offset; 85 gate->bit_idx = gate_shift; 86 gate->lock = lock; 87 gate_ops = &clk_gate_ops; 88 } 89 90 if (div_width > 0) { 91 div = kzalloc(sizeof(*div), GFP_KERNEL); 92 if (!div) { 93 ret = -ENOMEM; 94 goto err_div; 95 } 96 97 div->flags = div_flags; 98 div->reg = base + muxdiv_offset; 99 div->shift = div_shift; 100 div->width = div_width; 101 div->lock = lock; 102 div->table = div_table; 103 div_ops = (div_flags & CLK_DIVIDER_READ_ONLY) 104 ? &clk_divider_ro_ops 105 : &clk_divider_ops; 106 } 107 108 clk = clk_register_composite(NULL, name, parent_names, num_parents, 109 mux ? &mux->hw : NULL, mux_ops, 110 div ? &div->hw : NULL, div_ops, 111 gate ? &gate->hw : NULL, gate_ops, 112 flags); 113 114 if (IS_ERR(clk)) { 115 ret = PTR_ERR(clk); 116 goto err_composite; 117 } 118 119 return clk; 120 err_composite: 121 kfree(div); 122 err_div: 123 kfree(gate); 124 err_gate: 125 kfree(mux); 126 return ERR_PTR(ret); 127 } 128 129 struct rockchip_clk_frac { 130 struct notifier_block clk_nb; 131 struct clk_fractional_divider div; 132 struct clk_gate gate; 133 134 struct clk_mux mux; 135 const struct clk_ops *mux_ops; 136 int mux_frac_idx; 137 138 bool rate_change_remuxed; 139 int rate_change_idx; 140 }; 141 142 #define to_rockchip_clk_frac_nb(nb) \ 143 container_of(nb, struct rockchip_clk_frac, clk_nb) 144 145 static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb, 146 unsigned long event, void *data) 147 { 148 struct clk_notifier_data *ndata = data; 149 struct rockchip_clk_frac *frac = to_rockchip_clk_frac_nb(nb); 150 struct clk_mux *frac_mux = &frac->mux; 151 int ret = 0; 152 153 pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n", 154 __func__, event, ndata->old_rate, ndata->new_rate); 155 if (event == PRE_RATE_CHANGE) { 156 frac->rate_change_idx = 157 frac->mux_ops->get_parent(&frac_mux->hw); 158 if (frac->rate_change_idx != frac->mux_frac_idx) { 159 frac->mux_ops->set_parent(&frac_mux->hw, 160 frac->mux_frac_idx); 161 frac->rate_change_remuxed = 1; 162 } 163 } else if (event == POST_RATE_CHANGE) { 164 /* 165 * The POST_RATE_CHANGE notifier runs directly after the 166 * divider clock is set in clk_change_rate, so we'll have 167 * remuxed back to the original parent before clk_change_rate 168 * reaches the mux itself. 169 */ 170 if (frac->rate_change_remuxed) { 171 frac->mux_ops->set_parent(&frac_mux->hw, 172 frac->rate_change_idx); 173 frac->rate_change_remuxed = 0; 174 } 175 } 176 177 return notifier_from_errno(ret); 178 } 179 180 /** 181 * fractional divider must set that denominator is 20 times larger than 182 * numerator to generate precise clock frequency. 183 */ 184 static void rockchip_fractional_approximation(struct clk_hw *hw, 185 unsigned long rate, unsigned long *parent_rate, 186 unsigned long *m, unsigned long *n) 187 { 188 struct clk_fractional_divider *fd = to_clk_fd(hw); 189 unsigned long p_rate, p_parent_rate; 190 struct clk_hw *p_parent; 191 unsigned long scale; 192 193 p_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); 194 if ((rate * 20 > p_rate) && (p_rate % rate != 0)) { 195 p_parent = clk_hw_get_parent(clk_hw_get_parent(hw)); 196 p_parent_rate = clk_hw_get_rate(p_parent); 197 *parent_rate = p_parent_rate; 198 } 199 200 /* 201 * Get rate closer to *parent_rate to guarantee there is no overflow 202 * for m and n. In the result it will be the nearest rate left shifted 203 * by (scale - fd->nwidth) bits. 204 */ 205 scale = fls_long(*parent_rate / rate - 1); 206 if (scale > fd->nwidth) 207 rate <<= scale - fd->nwidth; 208 209 rational_best_approximation(rate, *parent_rate, 210 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), 211 m, n); 212 } 213 214 static struct clk *rockchip_clk_register_frac_branch( 215 struct rockchip_clk_provider *ctx, const char *name, 216 const char *const *parent_names, u8 num_parents, 217 void __iomem *base, int muxdiv_offset, u8 div_flags, 218 int gate_offset, u8 gate_shift, u8 gate_flags, 219 unsigned long flags, struct rockchip_clk_branch *child, 220 spinlock_t *lock) 221 { 222 struct rockchip_clk_frac *frac; 223 struct clk *clk; 224 struct clk_gate *gate = NULL; 225 struct clk_fractional_divider *div = NULL; 226 const struct clk_ops *div_ops = NULL, *gate_ops = NULL; 227 228 if (muxdiv_offset < 0) 229 return ERR_PTR(-EINVAL); 230 231 if (child && child->branch_type != branch_mux) { 232 pr_err("%s: fractional child clock for %s can only be a mux\n", 233 __func__, name); 234 return ERR_PTR(-EINVAL); 235 } 236 237 frac = kzalloc(sizeof(*frac), GFP_KERNEL); 238 if (!frac) 239 return ERR_PTR(-ENOMEM); 240 241 if (gate_offset >= 0) { 242 gate = &frac->gate; 243 gate->flags = gate_flags; 244 gate->reg = base + gate_offset; 245 gate->bit_idx = gate_shift; 246 gate->lock = lock; 247 gate_ops = &clk_gate_ops; 248 } 249 250 div = &frac->div; 251 div->flags = div_flags; 252 div->reg = base + muxdiv_offset; 253 div->mshift = 16; 254 div->mwidth = 16; 255 div->mmask = GENMASK(div->mwidth - 1, 0) << div->mshift; 256 div->nshift = 0; 257 div->nwidth = 16; 258 div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift; 259 div->lock = lock; 260 div->approximation = rockchip_fractional_approximation; 261 div_ops = &clk_fractional_divider_ops; 262 263 clk = clk_register_composite(NULL, name, parent_names, num_parents, 264 NULL, NULL, 265 &div->hw, div_ops, 266 gate ? &gate->hw : NULL, gate_ops, 267 flags | CLK_SET_RATE_UNGATE); 268 if (IS_ERR(clk)) { 269 kfree(frac); 270 return clk; 271 } 272 273 if (child) { 274 struct clk_mux *frac_mux = &frac->mux; 275 struct clk_init_data init; 276 struct clk *mux_clk; 277 int ret; 278 279 frac->mux_frac_idx = match_string(child->parent_names, 280 child->num_parents, name); 281 frac->mux_ops = &clk_mux_ops; 282 frac->clk_nb.notifier_call = rockchip_clk_frac_notifier_cb; 283 284 frac_mux->reg = base + child->muxdiv_offset; 285 frac_mux->shift = child->mux_shift; 286 frac_mux->mask = BIT(child->mux_width) - 1; 287 frac_mux->flags = child->mux_flags; 288 frac_mux->lock = lock; 289 frac_mux->hw.init = &init; 290 291 init.name = child->name; 292 init.flags = child->flags | CLK_SET_RATE_PARENT; 293 init.ops = frac->mux_ops; 294 init.parent_names = child->parent_names; 295 init.num_parents = child->num_parents; 296 297 mux_clk = clk_register(NULL, &frac_mux->hw); 298 if (IS_ERR(mux_clk)) { 299 kfree(frac); 300 return clk; 301 } 302 303 rockchip_clk_add_lookup(ctx, mux_clk, child->id); 304 305 /* notifier on the fraction divider to catch rate changes */ 306 if (frac->mux_frac_idx >= 0) { 307 pr_debug("%s: found fractional parent in mux at pos %d\n", 308 __func__, frac->mux_frac_idx); 309 ret = clk_notifier_register(clk, &frac->clk_nb); 310 if (ret) 311 pr_err("%s: failed to register clock notifier for %s\n", 312 __func__, name); 313 } else { 314 pr_warn("%s: could not find %s as parent of %s, rate changes may not work\n", 315 __func__, name, child->name); 316 } 317 } 318 319 return clk; 320 } 321 322 static struct clk *rockchip_clk_register_factor_branch(const char *name, 323 const char *const *parent_names, u8 num_parents, 324 void __iomem *base, unsigned int mult, unsigned int div, 325 int gate_offset, u8 gate_shift, u8 gate_flags, 326 unsigned long flags, spinlock_t *lock) 327 { 328 struct clk *clk; 329 struct clk_gate *gate = NULL; 330 struct clk_fixed_factor *fix = NULL; 331 332 /* without gate, register a simple factor clock */ 333 if (gate_offset == 0) { 334 return clk_register_fixed_factor(NULL, name, 335 parent_names[0], flags, mult, 336 div); 337 } 338 339 gate = kzalloc(sizeof(*gate), GFP_KERNEL); 340 if (!gate) 341 return ERR_PTR(-ENOMEM); 342 343 gate->flags = gate_flags; 344 gate->reg = base + gate_offset; 345 gate->bit_idx = gate_shift; 346 gate->lock = lock; 347 348 fix = kzalloc(sizeof(*fix), GFP_KERNEL); 349 if (!fix) { 350 kfree(gate); 351 return ERR_PTR(-ENOMEM); 352 } 353 354 fix->mult = mult; 355 fix->div = div; 356 357 clk = clk_register_composite(NULL, name, parent_names, num_parents, 358 NULL, NULL, 359 &fix->hw, &clk_fixed_factor_ops, 360 &gate->hw, &clk_gate_ops, flags); 361 if (IS_ERR(clk)) { 362 kfree(fix); 363 kfree(gate); 364 } 365 366 return clk; 367 } 368 369 struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np, 370 void __iomem *base, unsigned long nr_clks) 371 { 372 struct rockchip_clk_provider *ctx; 373 struct clk **clk_table; 374 int i; 375 376 ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL); 377 if (!ctx) 378 return ERR_PTR(-ENOMEM); 379 380 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); 381 if (!clk_table) 382 goto err_free; 383 384 for (i = 0; i < nr_clks; ++i) 385 clk_table[i] = ERR_PTR(-ENOENT); 386 387 ctx->reg_base = base; 388 ctx->clk_data.clks = clk_table; 389 ctx->clk_data.clk_num = nr_clks; 390 ctx->cru_node = np; 391 spin_lock_init(&ctx->lock); 392 393 ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node, 394 "rockchip,grf"); 395 396 return ctx; 397 398 err_free: 399 kfree(ctx); 400 return ERR_PTR(-ENOMEM); 401 } 402 403 void __init rockchip_clk_of_add_provider(struct device_node *np, 404 struct rockchip_clk_provider *ctx) 405 { 406 if (of_clk_add_provider(np, of_clk_src_onecell_get, 407 &ctx->clk_data)) 408 pr_err("%s: could not register clk provider\n", __func__); 409 } 410 411 void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, 412 struct clk *clk, unsigned int id) 413 { 414 if (ctx->clk_data.clks && id) 415 ctx->clk_data.clks[id] = clk; 416 } 417 418 void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, 419 struct rockchip_pll_clock *list, 420 unsigned int nr_pll, int grf_lock_offset) 421 { 422 struct clk *clk; 423 int idx; 424 425 for (idx = 0; idx < nr_pll; idx++, list++) { 426 clk = rockchip_clk_register_pll(ctx, list->type, list->name, 427 list->parent_names, list->num_parents, 428 list->con_offset, grf_lock_offset, 429 list->lock_shift, list->mode_offset, 430 list->mode_shift, list->rate_table, 431 list->flags, list->pll_flags); 432 if (IS_ERR(clk)) { 433 pr_err("%s: failed to register clock %s\n", __func__, 434 list->name); 435 continue; 436 } 437 438 rockchip_clk_add_lookup(ctx, clk, list->id); 439 } 440 } 441 442 void __init rockchip_clk_register_branches( 443 struct rockchip_clk_provider *ctx, 444 struct rockchip_clk_branch *list, 445 unsigned int nr_clk) 446 { 447 struct clk *clk = NULL; 448 unsigned int idx; 449 unsigned long flags; 450 451 for (idx = 0; idx < nr_clk; idx++, list++) { 452 flags = list->flags; 453 454 /* catch simple muxes */ 455 switch (list->branch_type) { 456 case branch_mux: 457 clk = clk_register_mux(NULL, list->name, 458 list->parent_names, list->num_parents, 459 flags, ctx->reg_base + list->muxdiv_offset, 460 list->mux_shift, list->mux_width, 461 list->mux_flags, &ctx->lock); 462 break; 463 case branch_muxgrf: 464 clk = rockchip_clk_register_muxgrf(list->name, 465 list->parent_names, list->num_parents, 466 flags, ctx->grf, list->muxdiv_offset, 467 list->mux_shift, list->mux_width, 468 list->mux_flags); 469 break; 470 case branch_divider: 471 if (list->div_table) 472 clk = clk_register_divider_table(NULL, 473 list->name, list->parent_names[0], 474 flags, 475 ctx->reg_base + list->muxdiv_offset, 476 list->div_shift, list->div_width, 477 list->div_flags, list->div_table, 478 &ctx->lock); 479 else 480 clk = clk_register_divider(NULL, list->name, 481 list->parent_names[0], flags, 482 ctx->reg_base + list->muxdiv_offset, 483 list->div_shift, list->div_width, 484 list->div_flags, &ctx->lock); 485 break; 486 case branch_fraction_divider: 487 clk = rockchip_clk_register_frac_branch(ctx, list->name, 488 list->parent_names, list->num_parents, 489 ctx->reg_base, list->muxdiv_offset, 490 list->div_flags, 491 list->gate_offset, list->gate_shift, 492 list->gate_flags, flags, list->child, 493 &ctx->lock); 494 break; 495 case branch_half_divider: 496 clk = rockchip_clk_register_halfdiv(list->name, 497 list->parent_names, list->num_parents, 498 ctx->reg_base, list->muxdiv_offset, 499 list->mux_shift, list->mux_width, 500 list->mux_flags, list->div_shift, 501 list->div_width, list->div_flags, 502 list->gate_offset, list->gate_shift, 503 list->gate_flags, flags, &ctx->lock); 504 break; 505 case branch_gate: 506 flags |= CLK_SET_RATE_PARENT; 507 508 clk = clk_register_gate(NULL, list->name, 509 list->parent_names[0], flags, 510 ctx->reg_base + list->gate_offset, 511 list->gate_shift, list->gate_flags, &ctx->lock); 512 break; 513 case branch_composite: 514 clk = rockchip_clk_register_branch(list->name, 515 list->parent_names, list->num_parents, 516 ctx->reg_base, list->muxdiv_offset, 517 list->mux_shift, 518 list->mux_width, list->mux_flags, 519 list->div_shift, list->div_width, 520 list->div_flags, list->div_table, 521 list->gate_offset, list->gate_shift, 522 list->gate_flags, flags, &ctx->lock); 523 break; 524 case branch_mmc: 525 clk = rockchip_clk_register_mmc( 526 list->name, 527 list->parent_names, list->num_parents, 528 ctx->reg_base + list->muxdiv_offset, 529 list->div_shift 530 ); 531 break; 532 case branch_inverter: 533 clk = rockchip_clk_register_inverter( 534 list->name, list->parent_names, 535 list->num_parents, 536 ctx->reg_base + list->muxdiv_offset, 537 list->div_shift, list->div_flags, &ctx->lock); 538 break; 539 case branch_factor: 540 clk = rockchip_clk_register_factor_branch( 541 list->name, list->parent_names, 542 list->num_parents, ctx->reg_base, 543 list->div_shift, list->div_width, 544 list->gate_offset, list->gate_shift, 545 list->gate_flags, flags, &ctx->lock); 546 break; 547 case branch_ddrclk: 548 clk = rockchip_clk_register_ddrclk( 549 list->name, list->flags, 550 list->parent_names, list->num_parents, 551 list->muxdiv_offset, list->mux_shift, 552 list->mux_width, list->div_shift, 553 list->div_width, list->div_flags, 554 ctx->reg_base, &ctx->lock); 555 break; 556 } 557 558 /* none of the cases above matched */ 559 if (!clk) { 560 pr_err("%s: unknown clock type %d\n", 561 __func__, list->branch_type); 562 continue; 563 } 564 565 if (IS_ERR(clk)) { 566 pr_err("%s: failed to register clock %s: %ld\n", 567 __func__, list->name, PTR_ERR(clk)); 568 continue; 569 } 570 571 rockchip_clk_add_lookup(ctx, clk, list->id); 572 } 573 } 574 575 void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, 576 unsigned int lookup_id, 577 const char *name, const char *const *parent_names, 578 u8 num_parents, 579 const struct rockchip_cpuclk_reg_data *reg_data, 580 const struct rockchip_cpuclk_rate_table *rates, 581 int nrates) 582 { 583 struct clk *clk; 584 585 clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents, 586 reg_data, rates, nrates, 587 ctx->reg_base, &ctx->lock); 588 if (IS_ERR(clk)) { 589 pr_err("%s: failed to register clock %s: %ld\n", 590 __func__, name, PTR_ERR(clk)); 591 return; 592 } 593 594 rockchip_clk_add_lookup(ctx, clk, lookup_id); 595 } 596 597 void __init rockchip_clk_protect_critical(const char *const clocks[], 598 int nclocks) 599 { 600 int i; 601 602 /* Protect the clocks that needs to stay on */ 603 for (i = 0; i < nclocks; i++) { 604 struct clk *clk = __clk_lookup(clocks[i]); 605 606 if (clk) 607 clk_prepare_enable(clk); 608 } 609 } 610 611 static void __iomem *rst_base; 612 static unsigned int reg_restart; 613 static void (*cb_restart)(void); 614 static int rockchip_restart_notify(struct notifier_block *this, 615 unsigned long mode, void *cmd) 616 { 617 if (cb_restart) 618 cb_restart(); 619 620 writel(0xfdb9, rst_base + reg_restart); 621 return NOTIFY_DONE; 622 } 623 624 static struct notifier_block rockchip_restart_handler = { 625 .notifier_call = rockchip_restart_notify, 626 .priority = 128, 627 }; 628 629 void __init 630 rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, 631 unsigned int reg, 632 void (*cb)(void)) 633 { 634 int ret; 635 636 rst_base = ctx->reg_base; 637 reg_restart = reg; 638 cb_restart = cb; 639 ret = register_restart_handler(&rockchip_restart_handler); 640 if (ret) 641 pr_err("%s: cannot register restart handler, %d\n", 642 __func__, ret); 643 } 644