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