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