1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/clkdev.h> 8 #include <linux/clk/at91_pmc.h> 9 #include <linux/of.h> 10 #include <linux/mfd/syscon.h> 11 #include <linux/regmap.h> 12 13 #include "pmc.h" 14 15 #define MASTER_PRES_MASK 0x7 16 #define MASTER_PRES_MAX MASTER_PRES_MASK 17 #define MASTER_DIV_SHIFT 8 18 #define MASTER_DIV_MASK 0x7 19 20 #define PMC_MCR 0x30 21 #define PMC_MCR_ID_MSK GENMASK(3, 0) 22 #define PMC_MCR_CMD BIT(7) 23 #define PMC_MCR_DIV GENMASK(10, 8) 24 #define PMC_MCR_CSS GENMASK(20, 16) 25 #define PMC_MCR_CSS_SHIFT (16) 26 #define PMC_MCR_EN BIT(28) 27 28 #define PMC_MCR_ID(x) ((x) & PMC_MCR_ID_MSK) 29 30 #define MASTER_MAX_ID 4 31 32 #define to_clk_master(hw) container_of(hw, struct clk_master, hw) 33 34 struct clk_master { 35 struct clk_hw hw; 36 struct regmap *regmap; 37 spinlock_t *lock; 38 const struct clk_master_layout *layout; 39 const struct clk_master_characteristics *characteristics; 40 u32 *mux_table; 41 u32 mckr; 42 int chg_pid; 43 u8 id; 44 u8 parent; 45 u8 div; 46 }; 47 48 static inline bool clk_master_ready(struct clk_master *master) 49 { 50 unsigned int bit = master->id ? AT91_PMC_MCKXRDY : AT91_PMC_MCKRDY; 51 unsigned int status; 52 53 regmap_read(master->regmap, AT91_PMC_SR, &status); 54 55 return !!(status & bit); 56 } 57 58 static int clk_master_prepare(struct clk_hw *hw) 59 { 60 struct clk_master *master = to_clk_master(hw); 61 unsigned long flags; 62 63 spin_lock_irqsave(master->lock, flags); 64 65 while (!clk_master_ready(master)) 66 cpu_relax(); 67 68 spin_unlock_irqrestore(master->lock, flags); 69 70 return 0; 71 } 72 73 static int clk_master_is_prepared(struct clk_hw *hw) 74 { 75 struct clk_master *master = to_clk_master(hw); 76 unsigned long flags; 77 bool status; 78 79 spin_lock_irqsave(master->lock, flags); 80 status = clk_master_ready(master); 81 spin_unlock_irqrestore(master->lock, flags); 82 83 return status; 84 } 85 86 static unsigned long clk_master_div_recalc_rate(struct clk_hw *hw, 87 unsigned long parent_rate) 88 { 89 u8 div; 90 unsigned long flags, rate = parent_rate; 91 struct clk_master *master = to_clk_master(hw); 92 const struct clk_master_layout *layout = master->layout; 93 const struct clk_master_characteristics *characteristics = 94 master->characteristics; 95 unsigned int mckr; 96 97 spin_lock_irqsave(master->lock, flags); 98 regmap_read(master->regmap, master->layout->offset, &mckr); 99 spin_unlock_irqrestore(master->lock, flags); 100 101 mckr &= layout->mask; 102 103 div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; 104 105 rate /= characteristics->divisors[div]; 106 107 if (rate < characteristics->output.min) 108 pr_warn("master clk div is underclocked"); 109 else if (rate > characteristics->output.max) 110 pr_warn("master clk div is overclocked"); 111 112 return rate; 113 } 114 115 static const struct clk_ops master_div_ops = { 116 .prepare = clk_master_prepare, 117 .is_prepared = clk_master_is_prepared, 118 .recalc_rate = clk_master_div_recalc_rate, 119 }; 120 121 static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, 122 unsigned long parent_rate) 123 { 124 struct clk_master *master = to_clk_master(hw); 125 const struct clk_master_characteristics *characteristics = 126 master->characteristics; 127 unsigned long flags; 128 int div, i; 129 130 div = DIV_ROUND_CLOSEST(parent_rate, rate); 131 if (div > ARRAY_SIZE(characteristics->divisors)) 132 return -EINVAL; 133 134 for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { 135 if (!characteristics->divisors[i]) 136 break; 137 138 if (div == characteristics->divisors[i]) { 139 div = i; 140 break; 141 } 142 } 143 144 if (i == ARRAY_SIZE(characteristics->divisors)) 145 return -EINVAL; 146 147 spin_lock_irqsave(master->lock, flags); 148 regmap_update_bits(master->regmap, master->layout->offset, 149 (MASTER_DIV_MASK << MASTER_DIV_SHIFT), 150 (div << MASTER_DIV_SHIFT)); 151 while (!clk_master_ready(master)) 152 cpu_relax(); 153 spin_unlock_irqrestore(master->lock, flags); 154 155 return 0; 156 } 157 158 static int clk_master_div_determine_rate(struct clk_hw *hw, 159 struct clk_rate_request *req) 160 { 161 struct clk_master *master = to_clk_master(hw); 162 const struct clk_master_characteristics *characteristics = 163 master->characteristics; 164 struct clk_hw *parent; 165 unsigned long parent_rate, tmp_rate, best_rate = 0; 166 int i, best_diff = INT_MIN, tmp_diff; 167 168 parent = clk_hw_get_parent(hw); 169 if (!parent) 170 return -EINVAL; 171 172 parent_rate = clk_hw_get_rate(parent); 173 if (!parent_rate) 174 return -EINVAL; 175 176 for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { 177 if (!characteristics->divisors[i]) 178 break; 179 180 tmp_rate = DIV_ROUND_CLOSEST_ULL(parent_rate, 181 characteristics->divisors[i]); 182 tmp_diff = abs(tmp_rate - req->rate); 183 184 if (!best_rate || best_diff > tmp_diff) { 185 best_diff = tmp_diff; 186 best_rate = tmp_rate; 187 } 188 189 if (!best_diff) 190 break; 191 } 192 193 req->best_parent_rate = best_rate; 194 req->best_parent_hw = parent; 195 req->rate = best_rate; 196 197 return 0; 198 } 199 200 static const struct clk_ops master_div_ops_chg = { 201 .prepare = clk_master_prepare, 202 .is_prepared = clk_master_is_prepared, 203 .recalc_rate = clk_master_div_recalc_rate, 204 .determine_rate = clk_master_div_determine_rate, 205 .set_rate = clk_master_div_set_rate, 206 }; 207 208 static void clk_sama7g5_master_best_diff(struct clk_rate_request *req, 209 struct clk_hw *parent, 210 unsigned long parent_rate, 211 long *best_rate, 212 long *best_diff, 213 u32 div) 214 { 215 unsigned long tmp_rate, tmp_diff; 216 217 if (div == MASTER_PRES_MAX) 218 tmp_rate = parent_rate / 3; 219 else 220 tmp_rate = parent_rate >> div; 221 222 tmp_diff = abs(req->rate - tmp_rate); 223 224 if (*best_diff < 0 || *best_diff >= tmp_diff) { 225 *best_rate = tmp_rate; 226 *best_diff = tmp_diff; 227 req->best_parent_rate = parent_rate; 228 req->best_parent_hw = parent; 229 } 230 } 231 232 static int clk_master_pres_determine_rate(struct clk_hw *hw, 233 struct clk_rate_request *req) 234 { 235 struct clk_master *master = to_clk_master(hw); 236 struct clk_rate_request req_parent = *req; 237 const struct clk_master_characteristics *characteristics = 238 master->characteristics; 239 struct clk_hw *parent; 240 long best_rate = LONG_MIN, best_diff = LONG_MIN; 241 u32 pres; 242 int i; 243 244 if (master->chg_pid < 0) 245 return -EOPNOTSUPP; 246 247 parent = clk_hw_get_parent_by_index(hw, master->chg_pid); 248 if (!parent) 249 return -EOPNOTSUPP; 250 251 for (i = 0; i <= MASTER_PRES_MAX; i++) { 252 if (characteristics->have_div3_pres && i == MASTER_PRES_MAX) 253 pres = 3; 254 else 255 pres = 1 << i; 256 257 req_parent.rate = req->rate * pres; 258 if (__clk_determine_rate(parent, &req_parent)) 259 continue; 260 261 clk_sama7g5_master_best_diff(req, parent, req_parent.rate, 262 &best_diff, &best_rate, pres); 263 if (!best_diff) 264 break; 265 } 266 267 return 0; 268 } 269 270 static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, 271 unsigned long parent_rate) 272 { 273 struct clk_master *master = to_clk_master(hw); 274 unsigned long flags; 275 unsigned int pres; 276 277 pres = DIV_ROUND_CLOSEST(parent_rate, rate); 278 if (pres > MASTER_PRES_MAX) 279 return -EINVAL; 280 281 else if (pres == 3) 282 pres = MASTER_PRES_MAX; 283 else 284 pres = ffs(pres) - 1; 285 286 spin_lock_irqsave(master->lock, flags); 287 regmap_update_bits(master->regmap, master->layout->offset, 288 (MASTER_PRES_MASK << master->layout->pres_shift), 289 (pres << master->layout->pres_shift)); 290 291 while (!clk_master_ready(master)) 292 cpu_relax(); 293 spin_unlock_irqrestore(master->lock, flags); 294 295 return 0; 296 } 297 298 static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, 299 unsigned long parent_rate) 300 { 301 struct clk_master *master = to_clk_master(hw); 302 const struct clk_master_characteristics *characteristics = 303 master->characteristics; 304 unsigned long flags; 305 unsigned int val, pres; 306 307 spin_lock_irqsave(master->lock, flags); 308 regmap_read(master->regmap, master->layout->offset, &val); 309 spin_unlock_irqrestore(master->lock, flags); 310 311 pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; 312 if (pres == 3 && characteristics->have_div3_pres) 313 pres = 3; 314 else 315 pres = (1 << pres); 316 317 return DIV_ROUND_CLOSEST_ULL(parent_rate, pres); 318 } 319 320 static u8 clk_master_pres_get_parent(struct clk_hw *hw) 321 { 322 struct clk_master *master = to_clk_master(hw); 323 unsigned long flags; 324 unsigned int mckr; 325 326 spin_lock_irqsave(master->lock, flags); 327 regmap_read(master->regmap, master->layout->offset, &mckr); 328 spin_unlock_irqrestore(master->lock, flags); 329 330 return mckr & AT91_PMC_CSS; 331 } 332 333 static const struct clk_ops master_pres_ops = { 334 .prepare = clk_master_prepare, 335 .is_prepared = clk_master_is_prepared, 336 .recalc_rate = clk_master_pres_recalc_rate, 337 .get_parent = clk_master_pres_get_parent, 338 }; 339 340 static const struct clk_ops master_pres_ops_chg = { 341 .prepare = clk_master_prepare, 342 .is_prepared = clk_master_is_prepared, 343 .determine_rate = clk_master_pres_determine_rate, 344 .recalc_rate = clk_master_pres_recalc_rate, 345 .get_parent = clk_master_pres_get_parent, 346 .set_rate = clk_master_pres_set_rate, 347 }; 348 349 static struct clk_hw * __init 350 at91_clk_register_master_internal(struct regmap *regmap, 351 const char *name, int num_parents, 352 const char **parent_names, 353 const struct clk_master_layout *layout, 354 const struct clk_master_characteristics *characteristics, 355 const struct clk_ops *ops, spinlock_t *lock, u32 flags, 356 int chg_pid) 357 { 358 struct clk_master *master; 359 struct clk_init_data init; 360 struct clk_hw *hw; 361 int ret; 362 363 if (!name || !num_parents || !parent_names || !lock) 364 return ERR_PTR(-EINVAL); 365 366 master = kzalloc(sizeof(*master), GFP_KERNEL); 367 if (!master) 368 return ERR_PTR(-ENOMEM); 369 370 init.name = name; 371 init.ops = ops; 372 init.parent_names = parent_names; 373 init.num_parents = num_parents; 374 init.flags = flags; 375 376 master->hw.init = &init; 377 master->layout = layout; 378 master->characteristics = characteristics; 379 master->regmap = regmap; 380 master->chg_pid = chg_pid; 381 master->lock = lock; 382 383 hw = &master->hw; 384 ret = clk_hw_register(NULL, &master->hw); 385 if (ret) { 386 kfree(master); 387 hw = ERR_PTR(ret); 388 } 389 390 return hw; 391 } 392 393 struct clk_hw * __init 394 at91_clk_register_master_pres(struct regmap *regmap, 395 const char *name, int num_parents, 396 const char **parent_names, 397 const struct clk_master_layout *layout, 398 const struct clk_master_characteristics *characteristics, 399 spinlock_t *lock, u32 flags, int chg_pid) 400 { 401 const struct clk_ops *ops; 402 403 if (flags & CLK_SET_RATE_GATE) 404 ops = &master_pres_ops; 405 else 406 ops = &master_pres_ops_chg; 407 408 return at91_clk_register_master_internal(regmap, name, num_parents, 409 parent_names, layout, 410 characteristics, ops, 411 lock, flags, chg_pid); 412 } 413 414 struct clk_hw * __init 415 at91_clk_register_master_div(struct regmap *regmap, 416 const char *name, const char *parent_name, 417 const struct clk_master_layout *layout, 418 const struct clk_master_characteristics *characteristics, 419 spinlock_t *lock, u32 flags) 420 { 421 const struct clk_ops *ops; 422 423 if (flags & CLK_SET_RATE_GATE) 424 ops = &master_div_ops; 425 else 426 ops = &master_div_ops_chg; 427 428 return at91_clk_register_master_internal(regmap, name, 1, 429 &parent_name, layout, 430 characteristics, ops, 431 lock, flags, -EINVAL); 432 } 433 434 static unsigned long 435 clk_sama7g5_master_recalc_rate(struct clk_hw *hw, 436 unsigned long parent_rate) 437 { 438 struct clk_master *master = to_clk_master(hw); 439 440 return DIV_ROUND_CLOSEST_ULL(parent_rate, (1 << master->div)); 441 } 442 443 static int clk_sama7g5_master_determine_rate(struct clk_hw *hw, 444 struct clk_rate_request *req) 445 { 446 struct clk_master *master = to_clk_master(hw); 447 struct clk_rate_request req_parent = *req; 448 struct clk_hw *parent; 449 long best_rate = LONG_MIN, best_diff = LONG_MIN; 450 unsigned long parent_rate; 451 unsigned int div, i; 452 453 /* First: check the dividers of MCR. */ 454 for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 455 parent = clk_hw_get_parent_by_index(hw, i); 456 if (!parent) 457 continue; 458 459 parent_rate = clk_hw_get_rate(parent); 460 if (!parent_rate) 461 continue; 462 463 for (div = 0; div < MASTER_PRES_MAX + 1; div++) { 464 clk_sama7g5_master_best_diff(req, parent, parent_rate, 465 &best_rate, &best_diff, 466 div); 467 if (!best_diff) 468 break; 469 } 470 471 if (!best_diff) 472 break; 473 } 474 475 /* Second: try to request rate form changeable parent. */ 476 if (master->chg_pid < 0) 477 goto end; 478 479 parent = clk_hw_get_parent_by_index(hw, master->chg_pid); 480 if (!parent) 481 goto end; 482 483 for (div = 0; div < MASTER_PRES_MAX + 1; div++) { 484 if (div == MASTER_PRES_MAX) 485 req_parent.rate = req->rate * 3; 486 else 487 req_parent.rate = req->rate << div; 488 489 if (__clk_determine_rate(parent, &req_parent)) 490 continue; 491 492 clk_sama7g5_master_best_diff(req, parent, req_parent.rate, 493 &best_rate, &best_diff, div); 494 495 if (!best_diff) 496 break; 497 } 498 499 end: 500 pr_debug("MCK: %s, best_rate = %ld, parent clk: %s @ %ld\n", 501 __func__, best_rate, 502 __clk_get_name((req->best_parent_hw)->clk), 503 req->best_parent_rate); 504 505 if (best_rate < 0) 506 return -EINVAL; 507 508 req->rate = best_rate; 509 510 return 0; 511 } 512 513 static u8 clk_sama7g5_master_get_parent(struct clk_hw *hw) 514 { 515 struct clk_master *master = to_clk_master(hw); 516 unsigned long flags; 517 u8 index; 518 519 spin_lock_irqsave(master->lock, flags); 520 index = clk_mux_val_to_index(&master->hw, master->mux_table, 0, 521 master->parent); 522 spin_unlock_irqrestore(master->lock, flags); 523 524 return index; 525 } 526 527 static int clk_sama7g5_master_set_parent(struct clk_hw *hw, u8 index) 528 { 529 struct clk_master *master = to_clk_master(hw); 530 unsigned long flags; 531 532 if (index >= clk_hw_get_num_parents(hw)) 533 return -EINVAL; 534 535 spin_lock_irqsave(master->lock, flags); 536 master->parent = clk_mux_index_to_val(master->mux_table, 0, index); 537 spin_unlock_irqrestore(master->lock, flags); 538 539 return 0; 540 } 541 542 static int clk_sama7g5_master_enable(struct clk_hw *hw) 543 { 544 struct clk_master *master = to_clk_master(hw); 545 unsigned long flags; 546 unsigned int val, cparent; 547 548 spin_lock_irqsave(master->lock, flags); 549 550 regmap_write(master->regmap, PMC_MCR, PMC_MCR_ID(master->id)); 551 regmap_read(master->regmap, PMC_MCR, &val); 552 regmap_update_bits(master->regmap, PMC_MCR, 553 PMC_MCR_EN | PMC_MCR_CSS | PMC_MCR_DIV | 554 PMC_MCR_CMD | PMC_MCR_ID_MSK, 555 PMC_MCR_EN | (master->parent << PMC_MCR_CSS_SHIFT) | 556 (master->div << MASTER_DIV_SHIFT) | 557 PMC_MCR_CMD | PMC_MCR_ID(master->id)); 558 559 cparent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT; 560 561 /* Wait here only if parent is being changed. */ 562 while ((cparent != master->parent) && !clk_master_ready(master)) 563 cpu_relax(); 564 565 spin_unlock_irqrestore(master->lock, flags); 566 567 return 0; 568 } 569 570 static void clk_sama7g5_master_disable(struct clk_hw *hw) 571 { 572 struct clk_master *master = to_clk_master(hw); 573 unsigned long flags; 574 575 spin_lock_irqsave(master->lock, flags); 576 577 regmap_write(master->regmap, PMC_MCR, master->id); 578 regmap_update_bits(master->regmap, PMC_MCR, 579 PMC_MCR_EN | PMC_MCR_CMD | PMC_MCR_ID_MSK, 580 PMC_MCR_CMD | PMC_MCR_ID(master->id)); 581 582 spin_unlock_irqrestore(master->lock, flags); 583 } 584 585 static int clk_sama7g5_master_is_enabled(struct clk_hw *hw) 586 { 587 struct clk_master *master = to_clk_master(hw); 588 unsigned long flags; 589 unsigned int val; 590 591 spin_lock_irqsave(master->lock, flags); 592 593 regmap_write(master->regmap, PMC_MCR, master->id); 594 regmap_read(master->regmap, PMC_MCR, &val); 595 596 spin_unlock_irqrestore(master->lock, flags); 597 598 return !!(val & PMC_MCR_EN); 599 } 600 601 static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate, 602 unsigned long parent_rate) 603 { 604 struct clk_master *master = to_clk_master(hw); 605 unsigned long div, flags; 606 607 div = DIV_ROUND_CLOSEST(parent_rate, rate); 608 if ((div > (1 << (MASTER_PRES_MAX - 1))) || (div & (div - 1))) 609 return -EINVAL; 610 611 if (div == 3) 612 div = MASTER_PRES_MAX; 613 else 614 div = ffs(div) - 1; 615 616 spin_lock_irqsave(master->lock, flags); 617 master->div = div; 618 spin_unlock_irqrestore(master->lock, flags); 619 620 return 0; 621 } 622 623 static const struct clk_ops sama7g5_master_ops = { 624 .enable = clk_sama7g5_master_enable, 625 .disable = clk_sama7g5_master_disable, 626 .is_enabled = clk_sama7g5_master_is_enabled, 627 .recalc_rate = clk_sama7g5_master_recalc_rate, 628 .determine_rate = clk_sama7g5_master_determine_rate, 629 .set_rate = clk_sama7g5_master_set_rate, 630 .get_parent = clk_sama7g5_master_get_parent, 631 .set_parent = clk_sama7g5_master_set_parent, 632 }; 633 634 struct clk_hw * __init 635 at91_clk_sama7g5_register_master(struct regmap *regmap, 636 const char *name, int num_parents, 637 const char **parent_names, 638 u32 *mux_table, 639 spinlock_t *lock, u8 id, 640 bool critical, int chg_pid) 641 { 642 struct clk_master *master; 643 struct clk_hw *hw; 644 struct clk_init_data init; 645 unsigned long flags; 646 unsigned int val; 647 int ret; 648 649 if (!name || !num_parents || !parent_names || !mux_table || 650 !lock || id > MASTER_MAX_ID) 651 return ERR_PTR(-EINVAL); 652 653 master = kzalloc(sizeof(*master), GFP_KERNEL); 654 if (!master) 655 return ERR_PTR(-ENOMEM); 656 657 init.name = name; 658 init.ops = &sama7g5_master_ops; 659 init.parent_names = parent_names; 660 init.num_parents = num_parents; 661 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 662 if (chg_pid >= 0) 663 init.flags |= CLK_SET_RATE_PARENT; 664 if (critical) 665 init.flags |= CLK_IS_CRITICAL; 666 667 master->hw.init = &init; 668 master->regmap = regmap; 669 master->id = id; 670 master->chg_pid = chg_pid; 671 master->lock = lock; 672 master->mux_table = mux_table; 673 674 spin_lock_irqsave(master->lock, flags); 675 regmap_write(master->regmap, PMC_MCR, master->id); 676 regmap_read(master->regmap, PMC_MCR, &val); 677 master->parent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT; 678 master->div = (val & PMC_MCR_DIV) >> MASTER_DIV_SHIFT; 679 spin_unlock_irqrestore(master->lock, flags); 680 681 hw = &master->hw; 682 ret = clk_hw_register(NULL, &master->hw); 683 if (ret) { 684 kfree(master); 685 hw = ERR_PTR(ret); 686 } 687 688 return hw; 689 } 690 691 const struct clk_master_layout at91rm9200_master_layout = { 692 .mask = 0x31F, 693 .pres_shift = 2, 694 .offset = AT91_PMC_MCKR, 695 }; 696 697 const struct clk_master_layout at91sam9x5_master_layout = { 698 .mask = 0x373, 699 .pres_shift = 4, 700 .offset = AT91_PMC_MCKR, 701 }; 702