1 /* 2 * linux/arch/arm/mach-omap2/clock.c 3 * 4 * Copyright (C) 2005-2008 Texas Instruments, Inc. 5 * Copyright (C) 2004-2008 Nokia Corporation 6 * 7 * Contacts: 8 * Richard Woodruff <r-woodruff2@ti.com> 9 * Paul Walmsley 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15 #undef DEBUG 16 17 #include <linux/module.h> 18 #include <linux/kernel.h> 19 #include <linux/device.h> 20 #include <linux/list.h> 21 #include <linux/errno.h> 22 #include <linux/delay.h> 23 #include <linux/clk.h> 24 #include <linux/io.h> 25 #include <linux/bitops.h> 26 27 #include <plat/clock.h> 28 #include <plat/clockdomain.h> 29 #include <plat/cpu.h> 30 #include <plat/prcm.h> 31 32 #include "clock.h" 33 #include "prm.h" 34 #include "prm-regbits-24xx.h" 35 #include "cm.h" 36 #include "cm-regbits-24xx.h" 37 #include "cm-regbits-34xx.h" 38 39 u8 cpu_mask; 40 41 /*------------------------------------------------------------------------- 42 * OMAP2/3/4 specific clock functions 43 *-------------------------------------------------------------------------*/ 44 45 /** 46 * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware 47 * @clk: struct clk * 48 * 49 * If @clk has the DELAYED_APP flag set, meaning that parent/rate changes 50 * don't take effect until the VALID_CONFIG bit is written, write the 51 * VALID_CONFIG bit and wait for the write to complete. No return value. 52 */ 53 static void _omap2xxx_clk_commit(struct clk *clk) 54 { 55 if (!cpu_is_omap24xx()) 56 return; 57 58 if (!(clk->flags & DELAYED_APP)) 59 return; 60 61 prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD, 62 OMAP2_PRCM_CLKCFG_CTRL_OFFSET); 63 /* OCP barrier */ 64 prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET); 65 } 66 67 /** 68 * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk 69 * @clk: OMAP clock struct ptr to use 70 * 71 * Convert a clockdomain name stored in a struct clk 'clk' into a 72 * clockdomain pointer, and save it into the struct clk. Intended to be 73 * called during clk_register(). No return value. 74 */ 75 void omap2_init_clk_clkdm(struct clk *clk) 76 { 77 struct clockdomain *clkdm; 78 79 if (!clk->clkdm_name) 80 return; 81 82 clkdm = clkdm_lookup(clk->clkdm_name); 83 if (clkdm) { 84 pr_debug("clock: associated clk %s to clkdm %s\n", 85 clk->name, clk->clkdm_name); 86 clk->clkdm = clkdm; 87 } else { 88 pr_debug("clock: could not associate clk %s to " 89 "clkdm %s\n", clk->name, clk->clkdm_name); 90 } 91 } 92 93 /** 94 * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware 95 * @clk: OMAP clock struct ptr to use 96 * 97 * Given a pointer to a source-selectable struct clk, read the hardware 98 * register and determine what its parent is currently set to. Update the 99 * clk->parent field with the appropriate clk ptr. 100 */ 101 void omap2_init_clksel_parent(struct clk *clk) 102 { 103 const struct clksel *clks; 104 const struct clksel_rate *clkr; 105 u32 r, found = 0; 106 107 if (!clk->clksel) 108 return; 109 110 r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; 111 r >>= __ffs(clk->clksel_mask); 112 113 for (clks = clk->clksel; clks->parent && !found; clks++) { 114 for (clkr = clks->rates; clkr->div && !found; clkr++) { 115 if ((clkr->flags & cpu_mask) && (clkr->val == r)) { 116 if (clk->parent != clks->parent) { 117 pr_debug("clock: inited %s parent " 118 "to %s (was %s)\n", 119 clk->name, clks->parent->name, 120 ((clk->parent) ? 121 clk->parent->name : "NULL")); 122 clk_reparent(clk, clks->parent); 123 }; 124 found = 1; 125 } 126 } 127 } 128 129 if (!found) 130 printk(KERN_ERR "clock: init parent: could not find " 131 "regval %0x for clock %s\n", r, clk->name); 132 133 return; 134 } 135 136 /** 137 * omap2_clk_dflt_find_companion - find companion clock to @clk 138 * @clk: struct clk * to find the companion clock of 139 * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in 140 * @other_bit: u8 ** to return the companion clock bit shift in 141 * 142 * Note: We don't need special code here for INVERT_ENABLE for the 143 * time being since INVERT_ENABLE only applies to clocks enabled by 144 * CM_CLKEN_PLL 145 * 146 * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's 147 * just a matter of XORing the bits. 148 * 149 * Some clocks don't have companion clocks. For example, modules with 150 * only an interface clock (such as MAILBOXES) don't have a companion 151 * clock. Right now, this code relies on the hardware exporting a bit 152 * in the correct companion register that indicates that the 153 * nonexistent 'companion clock' is active. Future patches will 154 * associate this type of code with per-module data structures to 155 * avoid this issue, and remove the casts. No return value. 156 */ 157 void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg, 158 u8 *other_bit) 159 { 160 u32 r; 161 162 /* 163 * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes 164 * it's just a matter of XORing the bits. 165 */ 166 r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN)); 167 168 *other_reg = (__force void __iomem *)r; 169 *other_bit = clk->enable_bit; 170 } 171 172 /** 173 * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk 174 * @clk: struct clk * to find IDLEST info for 175 * @idlest_reg: void __iomem ** to return the CM_IDLEST va in 176 * @idlest_bit: u8 ** to return the CM_IDLEST bit shift in 177 * 178 * Return the CM_IDLEST register address and bit shift corresponding 179 * to the module that "owns" this clock. This default code assumes 180 * that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that 181 * the IDLEST register address ID corresponds to the CM_*CLKEN 182 * register address ID (e.g., that CM_FCLKEN2 corresponds to 183 * CM_IDLEST2). This is not true for all modules. No return value. 184 */ 185 void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg, 186 u8 *idlest_bit) 187 { 188 u32 r; 189 190 r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); 191 *idlest_reg = (__force void __iomem *)r; 192 *idlest_bit = clk->enable_bit; 193 } 194 195 /** 196 * omap2_module_wait_ready - wait for an OMAP module to leave IDLE 197 * @clk: struct clk * belonging to the module 198 * 199 * If the necessary clocks for the OMAP hardware IP block that 200 * corresponds to clock @clk are enabled, then wait for the module to 201 * indicate readiness (i.e., to leave IDLE). This code does not 202 * belong in the clock code and will be moved in the medium term to 203 * module-dependent code. No return value. 204 */ 205 static void omap2_module_wait_ready(struct clk *clk) 206 { 207 void __iomem *companion_reg, *idlest_reg; 208 u8 other_bit, idlest_bit; 209 210 /* Not all modules have multiple clocks that their IDLEST depends on */ 211 if (clk->ops->find_companion) { 212 clk->ops->find_companion(clk, &companion_reg, &other_bit); 213 if (!(__raw_readl(companion_reg) & (1 << other_bit))) 214 return; 215 } 216 217 clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit); 218 219 omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name); 220 } 221 222 int omap2_dflt_clk_enable(struct clk *clk) 223 { 224 u32 v; 225 226 if (unlikely(clk->enable_reg == NULL)) { 227 pr_err("clock.c: Enable for %s without enable code\n", 228 clk->name); 229 return 0; /* REVISIT: -EINVAL */ 230 } 231 232 v = __raw_readl(clk->enable_reg); 233 if (clk->flags & INVERT_ENABLE) 234 v &= ~(1 << clk->enable_bit); 235 else 236 v |= (1 << clk->enable_bit); 237 __raw_writel(v, clk->enable_reg); 238 v = __raw_readl(clk->enable_reg); /* OCP barrier */ 239 240 if (clk->ops->find_idlest) 241 omap2_module_wait_ready(clk); 242 243 return 0; 244 } 245 246 void omap2_dflt_clk_disable(struct clk *clk) 247 { 248 u32 v; 249 250 if (!clk->enable_reg) { 251 /* 252 * 'Independent' here refers to a clock which is not 253 * controlled by its parent. 254 */ 255 printk(KERN_ERR "clock: clk_disable called on independent " 256 "clock %s which has no enable_reg\n", clk->name); 257 return; 258 } 259 260 v = __raw_readl(clk->enable_reg); 261 if (clk->flags & INVERT_ENABLE) 262 v |= (1 << clk->enable_bit); 263 else 264 v &= ~(1 << clk->enable_bit); 265 __raw_writel(v, clk->enable_reg); 266 /* No OCP barrier needed here since it is a disable operation */ 267 } 268 269 const struct clkops clkops_omap2_dflt_wait = { 270 .enable = omap2_dflt_clk_enable, 271 .disable = omap2_dflt_clk_disable, 272 .find_companion = omap2_clk_dflt_find_companion, 273 .find_idlest = omap2_clk_dflt_find_idlest, 274 }; 275 276 const struct clkops clkops_omap2_dflt = { 277 .enable = omap2_dflt_clk_enable, 278 .disable = omap2_dflt_clk_disable, 279 }; 280 281 /* Enables clock without considering parent dependencies or use count 282 * REVISIT: Maybe change this to use clk->enable like on omap1? 283 */ 284 static int _omap2_clk_enable(struct clk *clk) 285 { 286 return clk->ops->enable(clk); 287 } 288 289 /* Disables clock without considering parent dependencies or use count */ 290 static void _omap2_clk_disable(struct clk *clk) 291 { 292 clk->ops->disable(clk); 293 } 294 295 void omap2_clk_disable(struct clk *clk) 296 { 297 if (clk->usecount > 0 && !(--clk->usecount)) { 298 _omap2_clk_disable(clk); 299 if (clk->parent) 300 omap2_clk_disable(clk->parent); 301 if (clk->clkdm) 302 omap2_clkdm_clk_disable(clk->clkdm, clk); 303 304 } 305 } 306 307 int omap2_clk_enable(struct clk *clk) 308 { 309 int ret = 0; 310 311 if (clk->usecount++ == 0) { 312 if (clk->clkdm) 313 omap2_clkdm_clk_enable(clk->clkdm, clk); 314 315 if (clk->parent) { 316 ret = omap2_clk_enable(clk->parent); 317 if (ret) 318 goto err; 319 } 320 321 ret = _omap2_clk_enable(clk); 322 if (ret) { 323 if (clk->parent) 324 omap2_clk_disable(clk->parent); 325 326 goto err; 327 } 328 } 329 return ret; 330 331 err: 332 if (clk->clkdm) 333 omap2_clkdm_clk_disable(clk->clkdm, clk); 334 clk->usecount--; 335 return ret; 336 } 337 338 /* 339 * Used for clocks that are part of CLKSEL_xyz governed clocks. 340 * REVISIT: Maybe change to use clk->enable() functions like on omap1? 341 */ 342 unsigned long omap2_clksel_recalc(struct clk *clk) 343 { 344 unsigned long rate; 345 u32 div = 0; 346 347 pr_debug("clock: recalc'ing clksel clk %s\n", clk->name); 348 349 div = omap2_clksel_get_divisor(clk); 350 if (div == 0) 351 return clk->rate; 352 353 rate = clk->parent->rate / div; 354 355 pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div); 356 357 return rate; 358 } 359 360 /** 361 * omap2_get_clksel_by_parent - return clksel struct for a given clk & parent 362 * @clk: OMAP struct clk ptr to inspect 363 * @src_clk: OMAP struct clk ptr of the parent clk to search for 364 * 365 * Scan the struct clksel array associated with the clock to find 366 * the element associated with the supplied parent clock address. 367 * Returns a pointer to the struct clksel on success or NULL on error. 368 */ 369 static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk, 370 struct clk *src_clk) 371 { 372 const struct clksel *clks; 373 374 if (!clk->clksel) 375 return NULL; 376 377 for (clks = clk->clksel; clks->parent; clks++) { 378 if (clks->parent == src_clk) 379 break; /* Found the requested parent */ 380 } 381 382 if (!clks->parent) { 383 printk(KERN_ERR "clock: Could not find parent clock %s in " 384 "clksel array of clock %s\n", src_clk->name, 385 clk->name); 386 return NULL; 387 } 388 389 return clks; 390 } 391 392 /** 393 * omap2_clksel_round_rate_div - find divisor for the given clock and rate 394 * @clk: OMAP struct clk to use 395 * @target_rate: desired clock rate 396 * @new_div: ptr to where we should store the divisor 397 * 398 * Finds 'best' divider value in an array based on the source and target 399 * rates. The divider array must be sorted with smallest divider first. 400 * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT, 401 * they are only settable as part of virtual_prcm set. 402 * 403 * Returns the rounded clock rate or returns 0xffffffff on error. 404 */ 405 u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, 406 u32 *new_div) 407 { 408 unsigned long test_rate; 409 const struct clksel *clks; 410 const struct clksel_rate *clkr; 411 u32 last_div = 0; 412 413 pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n", 414 clk->name, target_rate); 415 416 *new_div = 1; 417 418 clks = omap2_get_clksel_by_parent(clk, clk->parent); 419 if (!clks) 420 return ~0; 421 422 for (clkr = clks->rates; clkr->div; clkr++) { 423 if (!(clkr->flags & cpu_mask)) 424 continue; 425 426 /* Sanity check */ 427 if (clkr->div <= last_div) 428 pr_err("clock: clksel_rate table not sorted " 429 "for clock %s", clk->name); 430 431 last_div = clkr->div; 432 433 test_rate = clk->parent->rate / clkr->div; 434 435 if (test_rate <= target_rate) 436 break; /* found it */ 437 } 438 439 if (!clkr->div) { 440 pr_err("clock: Could not find divisor for target " 441 "rate %ld for clock %s parent %s\n", target_rate, 442 clk->name, clk->parent->name); 443 return ~0; 444 } 445 446 *new_div = clkr->div; 447 448 pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div, 449 (clk->parent->rate / clkr->div)); 450 451 return (clk->parent->rate / clkr->div); 452 } 453 454 /** 455 * omap2_clksel_round_rate - find rounded rate for the given clock and rate 456 * @clk: OMAP struct clk to use 457 * @target_rate: desired clock rate 458 * 459 * Compatibility wrapper for OMAP clock framework 460 * Finds best target rate based on the source clock and possible dividers. 461 * rates. The divider array must be sorted with smallest divider first. 462 * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT, 463 * they are only settable as part of virtual_prcm set. 464 * 465 * Returns the rounded clock rate or returns 0xffffffff on error. 466 */ 467 long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) 468 { 469 u32 new_div; 470 471 return omap2_clksel_round_rate_div(clk, target_rate, &new_div); 472 } 473 474 475 /* Given a clock and a rate apply a clock specific rounding function */ 476 long omap2_clk_round_rate(struct clk *clk, unsigned long rate) 477 { 478 if (clk->round_rate) 479 return clk->round_rate(clk, rate); 480 481 if (clk->flags & RATE_FIXED) 482 printk(KERN_ERR "clock: generic omap2_clk_round_rate called " 483 "on fixed-rate clock %s\n", clk->name); 484 485 return clk->rate; 486 } 487 488 /** 489 * omap2_clksel_to_divisor() - turn clksel field value into integer divider 490 * @clk: OMAP struct clk to use 491 * @field_val: register field value to find 492 * 493 * Given a struct clk of a rate-selectable clksel clock, and a register field 494 * value to search for, find the corresponding clock divisor. The register 495 * field value should be pre-masked and shifted down so the LSB is at bit 0 496 * before calling. Returns 0 on error 497 */ 498 u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val) 499 { 500 const struct clksel *clks; 501 const struct clksel_rate *clkr; 502 503 clks = omap2_get_clksel_by_parent(clk, clk->parent); 504 if (!clks) 505 return 0; 506 507 for (clkr = clks->rates; clkr->div; clkr++) { 508 if ((clkr->flags & cpu_mask) && (clkr->val == field_val)) 509 break; 510 } 511 512 if (!clkr->div) { 513 printk(KERN_ERR "clock: Could not find fieldval %d for " 514 "clock %s parent %s\n", field_val, clk->name, 515 clk->parent->name); 516 return 0; 517 } 518 519 return clkr->div; 520 } 521 522 /** 523 * omap2_divisor_to_clksel() - turn clksel integer divisor into a field value 524 * @clk: OMAP struct clk to use 525 * @div: integer divisor to search for 526 * 527 * Given a struct clk of a rate-selectable clksel clock, and a clock divisor, 528 * find the corresponding register field value. The return register value is 529 * the value before left-shifting. Returns ~0 on error 530 */ 531 u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) 532 { 533 const struct clksel *clks; 534 const struct clksel_rate *clkr; 535 536 /* should never happen */ 537 WARN_ON(div == 0); 538 539 clks = omap2_get_clksel_by_parent(clk, clk->parent); 540 if (!clks) 541 return ~0; 542 543 for (clkr = clks->rates; clkr->div; clkr++) { 544 if ((clkr->flags & cpu_mask) && (clkr->div == div)) 545 break; 546 } 547 548 if (!clkr->div) { 549 printk(KERN_ERR "clock: Could not find divisor %d for " 550 "clock %s parent %s\n", div, clk->name, 551 clk->parent->name); 552 return ~0; 553 } 554 555 return clkr->val; 556 } 557 558 /** 559 * omap2_clksel_get_divisor - get current divider applied to parent clock. 560 * @clk: OMAP struct clk to use. 561 * 562 * Returns the integer divisor upon success or 0 on error. 563 */ 564 u32 omap2_clksel_get_divisor(struct clk *clk) 565 { 566 u32 v; 567 568 if (!clk->clksel_mask) 569 return 0; 570 571 v = __raw_readl(clk->clksel_reg) & clk->clksel_mask; 572 v >>= __ffs(clk->clksel_mask); 573 574 return omap2_clksel_to_divisor(clk, v); 575 } 576 577 int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) 578 { 579 u32 v, field_val, validrate, new_div = 0; 580 581 if (!clk->clksel_mask) 582 return -EINVAL; 583 584 validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); 585 if (validrate != rate) 586 return -EINVAL; 587 588 field_val = omap2_divisor_to_clksel(clk, new_div); 589 if (field_val == ~0) 590 return -EINVAL; 591 592 v = __raw_readl(clk->clksel_reg); 593 v &= ~clk->clksel_mask; 594 v |= field_val << __ffs(clk->clksel_mask); 595 __raw_writel(v, clk->clksel_reg); 596 v = __raw_readl(clk->clksel_reg); /* OCP barrier */ 597 598 clk->rate = clk->parent->rate / new_div; 599 600 _omap2xxx_clk_commit(clk); 601 602 return 0; 603 } 604 605 606 /* Set the clock rate for a clock source */ 607 int omap2_clk_set_rate(struct clk *clk, unsigned long rate) 608 { 609 int ret = -EINVAL; 610 611 pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate); 612 613 /* CONFIG_PARTICIPANT clocks are changed only in sets via the 614 rate table mechanism, driven by mpu_speed */ 615 if (clk->flags & CONFIG_PARTICIPANT) 616 return -EINVAL; 617 618 /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ 619 if (clk->set_rate) 620 ret = clk->set_rate(clk, rate); 621 622 return ret; 623 } 624 625 /* 626 * Converts encoded control register address into a full address 627 * On error, the return value (parent_div) will be 0. 628 */ 629 static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk, 630 u32 *field_val) 631 { 632 const struct clksel *clks; 633 const struct clksel_rate *clkr; 634 635 clks = omap2_get_clksel_by_parent(clk, src_clk); 636 if (!clks) 637 return 0; 638 639 for (clkr = clks->rates; clkr->div; clkr++) { 640 if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE) 641 break; /* Found the default rate for this platform */ 642 } 643 644 if (!clkr->div) { 645 printk(KERN_ERR "clock: Could not find default rate for " 646 "clock %s parent %s\n", clk->name, 647 src_clk->parent->name); 648 return 0; 649 } 650 651 /* Should never happen. Add a clksel mask to the struct clk. */ 652 WARN_ON(clk->clksel_mask == 0); 653 654 *field_val = clkr->val; 655 656 return clkr->div; 657 } 658 659 int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) 660 { 661 u32 field_val, v, parent_div; 662 663 if (clk->flags & CONFIG_PARTICIPANT) 664 return -EINVAL; 665 666 if (!clk->clksel) 667 return -EINVAL; 668 669 parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val); 670 if (!parent_div) 671 return -EINVAL; 672 673 /* Set new source value (previous dividers if any in effect) */ 674 v = __raw_readl(clk->clksel_reg); 675 v &= ~clk->clksel_mask; 676 v |= field_val << __ffs(clk->clksel_mask); 677 __raw_writel(v, clk->clksel_reg); 678 v = __raw_readl(clk->clksel_reg); /* OCP barrier */ 679 680 _omap2xxx_clk_commit(clk); 681 682 clk_reparent(clk, new_parent); 683 684 /* CLKSEL clocks follow their parents' rates, divided by a divisor */ 685 clk->rate = new_parent->rate; 686 687 if (parent_div > 0) 688 clk->rate /= parent_div; 689 690 pr_debug("clock: set parent of %s to %s (new rate %ld)\n", 691 clk->name, clk->parent->name, clk->rate); 692 693 return 0; 694 } 695 696 /*------------------------------------------------------------------------- 697 * Omap2 clock reset and init functions 698 *-------------------------------------------------------------------------*/ 699 700 #ifdef CONFIG_OMAP_RESET_CLOCKS 701 void omap2_clk_disable_unused(struct clk *clk) 702 { 703 u32 regval32, v; 704 705 v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0; 706 707 regval32 = __raw_readl(clk->enable_reg); 708 if ((regval32 & (1 << clk->enable_bit)) == v) 709 return; 710 711 printk(KERN_DEBUG "Disabling unused clock \"%s\"\n", clk->name); 712 if (cpu_is_omap34xx()) { 713 omap2_clk_enable(clk); 714 omap2_clk_disable(clk); 715 } else 716 _omap2_clk_disable(clk); 717 if (clk->clkdm != NULL) 718 pwrdm_clkdm_state_switch(clk->clkdm); 719 } 720 #endif 721