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; 437 unsigned int idx; 438 unsigned long flags; 439 440 for (idx = 0; idx < nr_clk; idx++, list++) { 441 flags = list->flags; 442 clk = NULL; 443 444 /* catch simple muxes */ 445 switch (list->branch_type) { 446 case branch_mux: 447 if (list->mux_table) 448 clk = clk_register_mux_table(NULL, list->name, 449 list->parent_names, list->num_parents, 450 flags, 451 ctx->reg_base + list->muxdiv_offset, 452 list->mux_shift, list->mux_width, 453 list->mux_flags, list->mux_table, 454 &ctx->lock); 455 else 456 clk = clk_register_mux(NULL, list->name, 457 list->parent_names, list->num_parents, 458 flags, 459 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->mux_table, list->div_offset, 520 list->div_shift, list->div_width, 521 list->div_flags, list->div_table, 522 list->gate_offset, list->gate_shift, 523 list->gate_flags, flags, &ctx->lock); 524 break; 525 case branch_mmc: 526 clk = rockchip_clk_register_mmc( 527 list->name, 528 list->parent_names, list->num_parents, 529 ctx->reg_base + list->muxdiv_offset, 530 list->div_shift 531 ); 532 break; 533 case branch_inverter: 534 clk = rockchip_clk_register_inverter( 535 list->name, list->parent_names, 536 list->num_parents, 537 ctx->reg_base + list->muxdiv_offset, 538 list->div_shift, list->div_flags, &ctx->lock); 539 break; 540 case branch_factor: 541 clk = rockchip_clk_register_factor_branch( 542 list->name, list->parent_names, 543 list->num_parents, ctx->reg_base, 544 list->div_shift, list->div_width, 545 list->gate_offset, list->gate_shift, 546 list->gate_flags, flags, &ctx->lock); 547 break; 548 case branch_ddrclk: 549 clk = rockchip_clk_register_ddrclk( 550 list->name, list->flags, 551 list->parent_names, list->num_parents, 552 list->muxdiv_offset, list->mux_shift, 553 list->mux_width, list->div_shift, 554 list->div_width, list->div_flags, 555 ctx->reg_base, &ctx->lock); 556 break; 557 } 558 559 /* none of the cases above matched */ 560 if (!clk) { 561 pr_err("%s: unknown clock type %d\n", 562 __func__, list->branch_type); 563 continue; 564 } 565 566 if (IS_ERR(clk)) { 567 pr_err("%s: failed to register clock %s: %ld\n", 568 __func__, list->name, PTR_ERR(clk)); 569 continue; 570 } 571 572 rockchip_clk_add_lookup(ctx, clk, list->id); 573 } 574 } 575 EXPORT_SYMBOL_GPL(rockchip_clk_register_branches); 576 577 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, 578 unsigned int lookup_id, 579 const char *name, const char *const *parent_names, 580 u8 num_parents, 581 const struct rockchip_cpuclk_reg_data *reg_data, 582 const struct rockchip_cpuclk_rate_table *rates, 583 int nrates) 584 { 585 struct clk *clk; 586 587 clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents, 588 reg_data, rates, nrates, 589 ctx->reg_base, &ctx->lock); 590 if (IS_ERR(clk)) { 591 pr_err("%s: failed to register clock %s: %ld\n", 592 __func__, name, PTR_ERR(clk)); 593 return; 594 } 595 596 rockchip_clk_add_lookup(ctx, clk, lookup_id); 597 } 598 EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk); 599 600 void rockchip_clk_protect_critical(const char *const clocks[], 601 int nclocks) 602 { 603 int i; 604 605 /* Protect the clocks that needs to stay on */ 606 for (i = 0; i < nclocks; i++) { 607 struct clk *clk = __clk_lookup(clocks[i]); 608 609 clk_prepare_enable(clk); 610 } 611 } 612 EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical); 613 614 static void __iomem *rst_base; 615 static unsigned int reg_restart; 616 static void (*cb_restart)(void); 617 static int rockchip_restart_notify(struct notifier_block *this, 618 unsigned long mode, void *cmd) 619 { 620 if (cb_restart) 621 cb_restart(); 622 623 writel(0xfdb9, rst_base + reg_restart); 624 return NOTIFY_DONE; 625 } 626 627 static struct notifier_block rockchip_restart_handler = { 628 .notifier_call = rockchip_restart_notify, 629 .priority = 128, 630 }; 631 632 void 633 rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, 634 unsigned int reg, 635 void (*cb)(void)) 636 { 637 int ret; 638 639 rst_base = ctx->reg_base; 640 reg_restart = reg; 641 cb_restart = cb; 642 ret = register_restart_handler(&rockchip_restart_handler); 643 if (ret) 644 pr_err("%s: cannot register restart handler, %d\n", 645 __func__, ret); 646 } 647 EXPORT_SYMBOL_GPL(rockchip_register_restart_notifier); 648