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