1 /* 2 * linux/arch/arm/mach-omap2/clock.c 3 * 4 * Copyright (C) 2005 Texas Instruments Inc. 5 * Richard Woodruff <r-woodruff2@ti.com> 6 * Created for OMAP2. 7 * 8 * Cleaned up and modified to use omap shared clock framework by 9 * Tony Lindgren <tony@atomide.com> 10 * 11 * Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation 12 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License version 2 as 16 * published by the Free Software Foundation. 17 */ 18 #include <linux/config.h> 19 #include <linux/module.h> 20 #include <linux/kernel.h> 21 #include <linux/device.h> 22 #include <linux/list.h> 23 #include <linux/errno.h> 24 #include <linux/delay.h> 25 #include <linux/clk.h> 26 27 #include <asm/io.h> 28 29 #include <asm/arch/clock.h> 30 #include <asm/arch/sram.h> 31 32 #include "prcm-regs.h" 33 #include "memory.h" 34 #include "clock.h" 35 36 //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ 37 38 static struct prcm_config *curr_prcm_set; 39 static u32 curr_perf_level = PRCM_FULL_SPEED; 40 41 /*------------------------------------------------------------------------- 42 * Omap2 specific clock functions 43 *-------------------------------------------------------------------------*/ 44 45 /* Recalculate SYST_CLK */ 46 static void omap2_sys_clk_recalc(struct clk * clk) 47 { 48 u32 div = PRCM_CLKSRC_CTRL; 49 div &= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */ 50 div >>= clk->rate_offset; 51 clk->rate = (clk->parent->rate / div); 52 propagate_rate(clk); 53 } 54 55 static u32 omap2_get_dpll_rate(struct clk * tclk) 56 { 57 long long dpll_clk; 58 int dpll_mult, dpll_div, amult; 59 60 dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */ 61 dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */ 62 dpll_clk = (long long)tclk->parent->rate * dpll_mult; 63 do_div(dpll_clk, dpll_div + 1); 64 amult = CM_CLKSEL2_PLL & 0x3; 65 dpll_clk *= amult; 66 67 return dpll_clk; 68 } 69 70 static void omap2_followparent_recalc(struct clk *clk) 71 { 72 followparent_recalc(clk); 73 } 74 75 static void omap2_propagate_rate(struct clk * clk) 76 { 77 if (!(clk->flags & RATE_FIXED)) 78 clk->rate = clk->parent->rate; 79 80 propagate_rate(clk); 81 } 82 83 /* Enable an APLL if off */ 84 static void omap2_clk_fixed_enable(struct clk *clk) 85 { 86 u32 cval, i=0; 87 88 if (clk->enable_bit == 0xff) /* Parent will do it */ 89 return; 90 91 cval = CM_CLKEN_PLL; 92 93 if ((cval & (0x3 << clk->enable_bit)) == (0x3 << clk->enable_bit)) 94 return; 95 96 cval &= ~(0x3 << clk->enable_bit); 97 cval |= (0x3 << clk->enable_bit); 98 CM_CLKEN_PLL = cval; 99 100 if (clk == &apll96_ck) 101 cval = (1 << 8); 102 else if (clk == &apll54_ck) 103 cval = (1 << 6); 104 105 while (!CM_IDLEST_CKGEN & cval) { /* Wait for lock */ 106 ++i; 107 udelay(1); 108 if (i == 100000) 109 break; 110 } 111 } 112 113 /* Enables clock without considering parent dependencies or use count 114 * REVISIT: Maybe change this to use clk->enable like on omap1? 115 */ 116 static int _omap2_clk_enable(struct clk * clk) 117 { 118 u32 regval32; 119 120 if (clk->flags & ALWAYS_ENABLED) 121 return 0; 122 123 if (unlikely(clk->enable_reg == 0)) { 124 printk(KERN_ERR "clock.c: Enable for %s without enable code\n", 125 clk->name); 126 return 0; 127 } 128 129 if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) { 130 omap2_clk_fixed_enable(clk); 131 return 0; 132 } 133 134 regval32 = __raw_readl(clk->enable_reg); 135 regval32 |= (1 << clk->enable_bit); 136 __raw_writel(regval32, clk->enable_reg); 137 138 return 0; 139 } 140 141 /* Stop APLL */ 142 static void omap2_clk_fixed_disable(struct clk *clk) 143 { 144 u32 cval; 145 146 if(clk->enable_bit == 0xff) /* let parent off do it */ 147 return; 148 149 cval = CM_CLKEN_PLL; 150 cval &= ~(0x3 << clk->enable_bit); 151 CM_CLKEN_PLL = cval; 152 } 153 154 /* Disables clock without considering parent dependencies or use count */ 155 static void _omap2_clk_disable(struct clk *clk) 156 { 157 u32 regval32; 158 159 if (clk->enable_reg == 0) 160 return; 161 162 if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) { 163 omap2_clk_fixed_disable(clk); 164 return; 165 } 166 167 regval32 = __raw_readl(clk->enable_reg); 168 regval32 &= ~(1 << clk->enable_bit); 169 __raw_writel(regval32, clk->enable_reg); 170 } 171 172 static int omap2_clk_enable(struct clk *clk) 173 { 174 int ret = 0; 175 176 if (clk->usecount++ == 0) { 177 if (likely((u32)clk->parent)) 178 ret = omap2_clk_enable(clk->parent); 179 180 if (unlikely(ret != 0)) { 181 clk->usecount--; 182 return ret; 183 } 184 185 ret = _omap2_clk_enable(clk); 186 187 if (unlikely(ret != 0) && clk->parent) { 188 omap2_clk_disable(clk->parent); 189 clk->usecount--; 190 } 191 } 192 193 return ret; 194 } 195 196 static void omap2_clk_disable(struct clk *clk) 197 { 198 if (clk->usecount > 0 && !(--clk->usecount)) { 199 _omap2_clk_disable(clk); 200 if (likely((u32)clk->parent)) 201 omap2_clk_disable(clk->parent); 202 } 203 } 204 205 /* 206 * Uses the current prcm set to tell if a rate is valid. 207 * You can go slower, but not faster within a given rate set. 208 */ 209 static u32 omap2_dpll_round_rate(unsigned long target_rate) 210 { 211 u32 high, low; 212 213 if ((CM_CLKSEL2_PLL & 0x3) == 1) { /* DPLL clockout */ 214 high = curr_prcm_set->dpll_speed * 2; 215 low = curr_prcm_set->dpll_speed; 216 } else { /* DPLL clockout x 2 */ 217 high = curr_prcm_set->dpll_speed; 218 low = curr_prcm_set->dpll_speed / 2; 219 } 220 221 #ifdef DOWN_VARIABLE_DPLL 222 if (target_rate > high) 223 return high; 224 else 225 return target_rate; 226 #else 227 if (target_rate > low) 228 return high; 229 else 230 return low; 231 #endif 232 233 } 234 235 /* 236 * Used for clocks that are part of CLKSEL_xyz governed clocks. 237 * REVISIT: Maybe change to use clk->enable() functions like on omap1? 238 */ 239 static void omap2_clksel_recalc(struct clk * clk) 240 { 241 u32 fixed = 0, div = 0; 242 243 if (clk == &dpll_ck) { 244 clk->rate = omap2_get_dpll_rate(clk); 245 fixed = 1; 246 div = 0; 247 } 248 249 if (clk == &iva1_mpu_int_ifck) { 250 div = 2; 251 fixed = 1; 252 } 253 254 if ((clk == &dss1_fck) && ((CM_CLKSEL1_CORE & (0x1f << 8)) == 0)) { 255 clk->rate = sys_ck.rate; 256 return; 257 } 258 259 if (!fixed) { 260 div = omap2_clksel_get_divisor(clk); 261 if (div == 0) 262 return; 263 } 264 265 if (div != 0) { 266 if (unlikely(clk->rate == clk->parent->rate / div)) 267 return; 268 clk->rate = clk->parent->rate / div; 269 } 270 271 if (unlikely(clk->flags & RATE_PROPAGATES)) 272 propagate_rate(clk); 273 } 274 275 /* 276 * Finds best divider value in an array based on the source and target 277 * rates. The divider array must be sorted with smallest divider first. 278 */ 279 static inline u32 omap2_divider_from_table(u32 size, u32 *div_array, 280 u32 src_rate, u32 tgt_rate) 281 { 282 int i, test_rate; 283 284 if (div_array == NULL) 285 return ~1; 286 287 for (i=0; i < size; i++) { 288 test_rate = src_rate / *div_array; 289 if (test_rate <= tgt_rate) 290 return *div_array; 291 ++div_array; 292 } 293 294 return ~0; /* No acceptable divider */ 295 } 296 297 /* 298 * Find divisor for the given clock and target rate. 299 * 300 * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT, 301 * they are only settable as part of virtual_prcm set. 302 */ 303 static u32 omap2_clksel_round_rate(struct clk *tclk, u32 target_rate, 304 u32 *new_div) 305 { 306 u32 gfx_div[] = {2, 3, 4}; 307 u32 sysclkout_div[] = {1, 2, 4, 8, 16}; 308 u32 dss1_div[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16}; 309 u32 vylnq_div[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18}; 310 u32 best_div = ~0, asize = 0; 311 u32 *div_array = NULL; 312 313 switch (tclk->flags & SRC_RATE_SEL_MASK) { 314 case CM_GFX_SEL1: 315 asize = 3; 316 div_array = gfx_div; 317 break; 318 case CM_PLL_SEL1: 319 return omap2_dpll_round_rate(target_rate); 320 case CM_SYSCLKOUT_SEL1: 321 asize = 5; 322 div_array = sysclkout_div; 323 break; 324 case CM_CORE_SEL1: 325 if(tclk == &dss1_fck){ 326 if(tclk->parent == &core_ck){ 327 asize = 10; 328 div_array = dss1_div; 329 } else { 330 *new_div = 0; /* fixed clk */ 331 return(tclk->parent->rate); 332 } 333 } else if((tclk == &vlynq_fck) && cpu_is_omap2420()){ 334 if(tclk->parent == &core_ck){ 335 asize = 10; 336 div_array = vylnq_div; 337 } else { 338 *new_div = 0; /* fixed clk */ 339 return(tclk->parent->rate); 340 } 341 } 342 break; 343 } 344 345 best_div = omap2_divider_from_table(asize, div_array, 346 tclk->parent->rate, target_rate); 347 if (best_div == ~0){ 348 *new_div = 1; 349 return best_div; /* signal error */ 350 } 351 352 *new_div = best_div; 353 return (tclk->parent->rate / best_div); 354 } 355 356 /* Given a clock and a rate apply a clock specific rounding function */ 357 static long omap2_clk_round_rate(struct clk *clk, unsigned long rate) 358 { 359 u32 new_div = 0; 360 int valid_rate; 361 362 if (clk->flags & RATE_FIXED) 363 return clk->rate; 364 365 if (clk->flags & RATE_CKCTL) { 366 valid_rate = omap2_clksel_round_rate(clk, rate, &new_div); 367 return valid_rate; 368 } 369 370 if (clk->round_rate != 0) 371 return clk->round_rate(clk, rate); 372 373 return clk->rate; 374 } 375 376 /* 377 * Check the DLL lock state, and return tue if running in unlock mode. 378 * This is needed to compenste for the shifted DLL value in unlock mode. 379 */ 380 static u32 omap2_dll_force_needed(void) 381 { 382 u32 dll_state = SDRC_DLLA_CTRL; /* dlla and dllb are a set */ 383 384 if ((dll_state & (1 << 2)) == (1 << 2)) 385 return 1; 386 else 387 return 0; 388 } 389 390 static u32 omap2_reprogram_sdrc(u32 level, u32 force) 391 { 392 u32 slow_dll_ctrl, fast_dll_ctrl, m_type; 393 u32 prev = curr_perf_level, flags; 394 395 if ((curr_perf_level == level) && !force) 396 return prev; 397 398 m_type = omap2_memory_get_type(); 399 slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl(); 400 fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl(); 401 402 if (level == PRCM_HALF_SPEED) { 403 local_irq_save(flags); 404 PRCM_VOLTSETUP = 0xffff; 405 omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED, 406 slow_dll_ctrl, m_type); 407 curr_perf_level = PRCM_HALF_SPEED; 408 local_irq_restore(flags); 409 } 410 if (level == PRCM_FULL_SPEED) { 411 local_irq_save(flags); 412 PRCM_VOLTSETUP = 0xffff; 413 omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED, 414 fast_dll_ctrl, m_type); 415 curr_perf_level = PRCM_FULL_SPEED; 416 local_irq_restore(flags); 417 } 418 419 return prev; 420 } 421 422 static int omap2_reprogram_dpll(struct clk * clk, unsigned long rate) 423 { 424 u32 flags, cur_rate, low, mult, div, valid_rate, done_rate; 425 u32 bypass = 0; 426 struct prcm_config tmpset; 427 int ret = -EINVAL; 428 429 local_irq_save(flags); 430 cur_rate = omap2_get_dpll_rate(&dpll_ck); 431 mult = CM_CLKSEL2_PLL & 0x3; 432 433 if ((rate == (cur_rate / 2)) && (mult == 2)) { 434 omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1); 435 } else if ((rate == (cur_rate * 2)) && (mult == 1)) { 436 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); 437 } else if (rate != cur_rate) { 438 valid_rate = omap2_dpll_round_rate(rate); 439 if (valid_rate != rate) 440 goto dpll_exit; 441 442 if ((CM_CLKSEL2_PLL & 0x3) == 1) 443 low = curr_prcm_set->dpll_speed; 444 else 445 low = curr_prcm_set->dpll_speed / 2; 446 447 tmpset.cm_clksel1_pll = CM_CLKSEL1_PLL; 448 tmpset.cm_clksel1_pll &= ~(0x3FFF << 8); 449 div = ((curr_prcm_set->xtal_speed / 1000000) - 1); 450 tmpset.cm_clksel2_pll = CM_CLKSEL2_PLL; 451 tmpset.cm_clksel2_pll &= ~0x3; 452 if (rate > low) { 453 tmpset.cm_clksel2_pll |= 0x2; 454 mult = ((rate / 2) / 1000000); 455 done_rate = PRCM_FULL_SPEED; 456 } else { 457 tmpset.cm_clksel2_pll |= 0x1; 458 mult = (rate / 1000000); 459 done_rate = PRCM_HALF_SPEED; 460 } 461 tmpset.cm_clksel1_pll |= ((div << 8) | (mult << 12)); 462 463 /* Worst case */ 464 tmpset.base_sdrc_rfr = V24XX_SDRC_RFR_CTRL_BYPASS; 465 466 if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */ 467 bypass = 1; 468 469 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); /* For init_mem */ 470 471 /* Force dll lock mode */ 472 omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr, 473 bypass); 474 475 /* Errata: ret dll entry state */ 476 omap2_init_memory_params(omap2_dll_force_needed()); 477 omap2_reprogram_sdrc(done_rate, 0); 478 } 479 omap2_clksel_recalc(&dpll_ck); 480 ret = 0; 481 482 dpll_exit: 483 local_irq_restore(flags); 484 return(ret); 485 } 486 487 /* Just return the MPU speed */ 488 static void omap2_mpu_recalc(struct clk * clk) 489 { 490 clk->rate = curr_prcm_set->mpu_speed; 491 } 492 493 /* 494 * Look for a rate equal or less than the target rate given a configuration set. 495 * 496 * What's not entirely clear is "which" field represents the key field. 497 * Some might argue L3-DDR, others ARM, others IVA. This code is simple and 498 * just uses the ARM rates. 499 */ 500 static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate) 501 { 502 struct prcm_config * ptr; 503 long highest_rate; 504 505 if (clk != &virt_prcm_set) 506 return -EINVAL; 507 508 highest_rate = -EINVAL; 509 510 for (ptr = rate_table; ptr->mpu_speed; ptr++) { 511 if (ptr->xtal_speed != sys_ck.rate) 512 continue; 513 514 highest_rate = ptr->mpu_speed; 515 516 /* Can check only after xtal frequency check */ 517 if (ptr->mpu_speed <= rate) 518 break; 519 } 520 return highest_rate; 521 } 522 523 /* 524 * omap2_convert_field_to_div() - turn field value into integer divider 525 */ 526 static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val) 527 { 528 u32 i; 529 u32 clkout_array[] = {1, 2, 4, 8, 16}; 530 531 if ((div_sel & SRC_RATE_SEL_MASK) == CM_SYSCLKOUT_SEL1) { 532 for (i = 0; i < 5; i++) { 533 if (field_val == i) 534 return clkout_array[i]; 535 } 536 return ~0; 537 } else 538 return field_val; 539 } 540 541 /* 542 * Returns the CLKSEL divider register value 543 * REVISIT: This should be cleaned up to work nicely with void __iomem * 544 */ 545 static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask, 546 struct clk *clk) 547 { 548 int ret = ~0; 549 u32 reg_val, div_off; 550 u32 div_addr = 0; 551 u32 mask = ~0; 552 553 div_off = clk->rate_offset; 554 555 switch ((*div_sel & SRC_RATE_SEL_MASK)) { 556 case CM_MPU_SEL1: 557 div_addr = (u32)&CM_CLKSEL_MPU; 558 mask = 0x1f; 559 break; 560 case CM_DSP_SEL1: 561 div_addr = (u32)&CM_CLKSEL_DSP; 562 if (cpu_is_omap2420()) { 563 if ((div_off == 0) || (div_off == 8)) 564 mask = 0x1f; 565 else if (div_off == 5) 566 mask = 0x3; 567 } else if (cpu_is_omap2430()) { 568 if (div_off == 0) 569 mask = 0x1f; 570 else if (div_off == 5) 571 mask = 0x3; 572 } 573 break; 574 case CM_GFX_SEL1: 575 div_addr = (u32)&CM_CLKSEL_GFX; 576 if (div_off == 0) 577 mask = 0x7; 578 break; 579 case CM_MODEM_SEL1: 580 div_addr = (u32)&CM_CLKSEL_MDM; 581 if (div_off == 0) 582 mask = 0xf; 583 break; 584 case CM_SYSCLKOUT_SEL1: 585 div_addr = (u32)&PRCM_CLKOUT_CTRL; 586 if ((div_off == 3) || (div_off = 11)) 587 mask= 0x3; 588 break; 589 case CM_CORE_SEL1: 590 div_addr = (u32)&CM_CLKSEL1_CORE; 591 switch (div_off) { 592 case 0: /* l3 */ 593 case 8: /* dss1 */ 594 case 15: /* vylnc-2420 */ 595 case 20: /* ssi */ 596 mask = 0x1f; break; 597 case 5: /* l4 */ 598 mask = 0x3; break; 599 case 13: /* dss2 */ 600 mask = 0x1; break; 601 case 25: /* usb */ 602 mask = 0x7; break; 603 } 604 } 605 606 *field_mask = mask; 607 608 if (unlikely(mask == ~0)) 609 div_addr = 0; 610 611 *div_sel = div_addr; 612 613 if (unlikely(div_addr == 0)) 614 return ret; 615 616 /* Isolate field */ 617 reg_val = __raw_readl((void __iomem *)div_addr) & (mask << div_off); 618 619 /* Normalize back to divider value */ 620 reg_val >>= div_off; 621 622 return reg_val; 623 } 624 625 /* 626 * Return divider to be applied to parent clock. 627 * Return 0 on error. 628 */ 629 static u32 omap2_clksel_get_divisor(struct clk *clk) 630 { 631 int ret = 0; 632 u32 div, div_sel, div_off, field_mask, field_val; 633 634 /* isolate control register */ 635 div_sel = (SRC_RATE_SEL_MASK & clk->flags); 636 637 div_off = clk->rate_offset; 638 field_val = omap2_get_clksel(&div_sel, &field_mask, clk); 639 if (div_sel == 0) 640 return ret; 641 642 div_sel = (SRC_RATE_SEL_MASK & clk->flags); 643 div = omap2_clksel_to_divisor(div_sel, field_val); 644 645 return div; 646 } 647 648 /* Set the clock rate for a clock source */ 649 static int omap2_clk_set_rate(struct clk *clk, unsigned long rate) 650 651 { 652 int ret = -EINVAL; 653 void __iomem * reg; 654 u32 div_sel, div_off, field_mask, field_val, reg_val, validrate; 655 u32 new_div = 0; 656 657 if (!(clk->flags & CONFIG_PARTICIPANT) && (clk->flags & RATE_CKCTL)) { 658 if (clk == &dpll_ck) 659 return omap2_reprogram_dpll(clk, rate); 660 661 /* Isolate control register */ 662 div_sel = (SRC_RATE_SEL_MASK & clk->flags); 663 div_off = clk->rate_offset; 664 665 validrate = omap2_clksel_round_rate(clk, rate, &new_div); 666 if (validrate != rate) 667 return(ret); 668 669 field_val = omap2_get_clksel(&div_sel, &field_mask, clk); 670 if (div_sel == 0) 671 return ret; 672 673 if (clk->flags & CM_SYSCLKOUT_SEL1) { 674 switch (new_div) { 675 case 16: 676 field_val = 4; 677 break; 678 case 8: 679 field_val = 3; 680 break; 681 case 4: 682 field_val = 2; 683 break; 684 case 2: 685 field_val = 1; 686 break; 687 case 1: 688 field_val = 0; 689 break; 690 } 691 } else 692 field_val = new_div; 693 694 reg = (void __iomem *)div_sel; 695 696 reg_val = __raw_readl(reg); 697 reg_val &= ~(field_mask << div_off); 698 reg_val |= (field_val << div_off); 699 700 __raw_writel(reg_val, reg); 701 clk->rate = clk->parent->rate / field_val; 702 703 if (clk->flags & DELAYED_APP) 704 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); 705 ret = 0; 706 } else if (clk->set_rate != 0) 707 ret = clk->set_rate(clk, rate); 708 709 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) 710 propagate_rate(clk); 711 712 return ret; 713 } 714 715 /* Converts encoded control register address into a full address */ 716 static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset, 717 struct clk *src_clk, u32 *field_mask) 718 { 719 u32 val = ~0, src_reg_addr = 0, mask = 0; 720 721 /* Find target control register.*/ 722 switch ((*type_to_addr & SRC_RATE_SEL_MASK)) { 723 case CM_CORE_SEL1: 724 src_reg_addr = (u32)&CM_CLKSEL1_CORE; 725 if (reg_offset == 13) { /* DSS2_fclk */ 726 mask = 0x1; 727 if (src_clk == &sys_ck) 728 val = 0; 729 if (src_clk == &func_48m_ck) 730 val = 1; 731 } else if (reg_offset == 8) { /* DSS1_fclk */ 732 mask = 0x1f; 733 if (src_clk == &sys_ck) 734 val = 0; 735 else if (src_clk == &core_ck) /* divided clock */ 736 val = 0x10; /* rate needs fixing */ 737 } else if ((reg_offset == 15) && cpu_is_omap2420()){ /*vlnyq*/ 738 mask = 0x1F; 739 if(src_clk == &func_96m_ck) 740 val = 0; 741 else if (src_clk == &core_ck) 742 val = 0x10; 743 } 744 break; 745 case CM_CORE_SEL2: 746 src_reg_addr = (u32)&CM_CLKSEL2_CORE; 747 mask = 0x3; 748 if (src_clk == &func_32k_ck) 749 val = 0x0; 750 if (src_clk == &sys_ck) 751 val = 0x1; 752 if (src_clk == &alt_ck) 753 val = 0x2; 754 break; 755 case CM_WKUP_SEL1: 756 src_reg_addr = (u32)&CM_CLKSEL2_CORE; 757 mask = 0x3; 758 if (src_clk == &func_32k_ck) 759 val = 0x0; 760 if (src_clk == &sys_ck) 761 val = 0x1; 762 if (src_clk == &alt_ck) 763 val = 0x2; 764 break; 765 case CM_PLL_SEL1: 766 src_reg_addr = (u32)&CM_CLKSEL1_PLL; 767 mask = 0x1; 768 if (reg_offset == 0x3) { 769 if (src_clk == &apll96_ck) 770 val = 0; 771 if (src_clk == &alt_ck) 772 val = 1; 773 } 774 else if (reg_offset == 0x5) { 775 if (src_clk == &apll54_ck) 776 val = 0; 777 if (src_clk == &alt_ck) 778 val = 1; 779 } 780 break; 781 case CM_PLL_SEL2: 782 src_reg_addr = (u32)&CM_CLKSEL2_PLL; 783 mask = 0x3; 784 if (src_clk == &func_32k_ck) 785 val = 0x0; 786 if (src_clk == &dpll_ck) 787 val = 0x2; 788 break; 789 case CM_SYSCLKOUT_SEL1: 790 src_reg_addr = (u32)&PRCM_CLKOUT_CTRL; 791 mask = 0x3; 792 if (src_clk == &dpll_ck) 793 val = 0; 794 if (src_clk == &sys_ck) 795 val = 1; 796 if (src_clk == &func_96m_ck) 797 val = 2; 798 if (src_clk == &func_54m_ck) 799 val = 3; 800 break; 801 } 802 803 if (val == ~0) /* Catch errors in offset */ 804 *type_to_addr = 0; 805 else 806 *type_to_addr = src_reg_addr; 807 *field_mask = mask; 808 809 return val; 810 } 811 812 static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) 813 { 814 void __iomem * reg; 815 u32 src_sel, src_off, field_val, field_mask, reg_val, rate; 816 int ret = -EINVAL; 817 818 if (unlikely(clk->flags & CONFIG_PARTICIPANT)) 819 return ret; 820 821 if (clk->flags & SRC_SEL_MASK) { /* On-chip SEL collection */ 822 src_sel = (SRC_RATE_SEL_MASK & clk->flags); 823 src_off = clk->src_offset; 824 825 if (src_sel == 0) 826 goto set_parent_error; 827 828 field_val = omap2_get_src_field(&src_sel, src_off, new_parent, 829 &field_mask); 830 831 reg = (void __iomem *)src_sel; 832 833 if (clk->usecount > 0) 834 _omap2_clk_disable(clk); 835 836 /* Set new source value (previous dividers if any in effect) */ 837 reg_val = __raw_readl(reg) & ~(field_mask << src_off); 838 reg_val |= (field_val << src_off); 839 __raw_writel(reg_val, reg); 840 841 if (clk->flags & DELAYED_APP) 842 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); 843 844 if (clk->usecount > 0) 845 _omap2_clk_enable(clk); 846 847 clk->parent = new_parent; 848 849 /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/ 850 if ((new_parent == &core_ck) && (clk == &dss1_fck)) 851 clk->rate = new_parent->rate / 0x10; 852 else 853 clk->rate = new_parent->rate; 854 855 if (unlikely(clk->flags & RATE_PROPAGATES)) 856 propagate_rate(clk); 857 858 return 0; 859 } else { 860 clk->parent = new_parent; 861 rate = new_parent->rate; 862 omap2_clk_set_rate(clk, rate); 863 ret = 0; 864 } 865 866 set_parent_error: 867 return ret; 868 } 869 870 /* Sets basic clocks based on the specified rate */ 871 static int omap2_select_table_rate(struct clk * clk, unsigned long rate) 872 { 873 u32 flags, cur_rate, done_rate, bypass = 0; 874 u8 cpu_mask = 0; 875 struct prcm_config *prcm; 876 unsigned long found_speed = 0; 877 878 if (clk != &virt_prcm_set) 879 return -EINVAL; 880 881 /* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */ 882 if (cpu_is_omap2420()) 883 cpu_mask = RATE_IN_242X; 884 else if (cpu_is_omap2430()) 885 cpu_mask = RATE_IN_243X; 886 887 for (prcm = rate_table; prcm->mpu_speed; prcm++) { 888 if (!(prcm->flags & cpu_mask)) 889 continue; 890 891 if (prcm->xtal_speed != sys_ck.rate) 892 continue; 893 894 if (prcm->mpu_speed <= rate) { 895 found_speed = prcm->mpu_speed; 896 break; 897 } 898 } 899 900 if (!found_speed) { 901 printk(KERN_INFO "Could not set MPU rate to %luMHz\n", 902 rate / 1000000); 903 return -EINVAL; 904 } 905 906 curr_prcm_set = prcm; 907 cur_rate = omap2_get_dpll_rate(&dpll_ck); 908 909 if (prcm->dpll_speed == cur_rate / 2) { 910 omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1); 911 } else if (prcm->dpll_speed == cur_rate * 2) { 912 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); 913 } else if (prcm->dpll_speed != cur_rate) { 914 local_irq_save(flags); 915 916 if (prcm->dpll_speed == prcm->xtal_speed) 917 bypass = 1; 918 919 if ((prcm->cm_clksel2_pll & 0x3) == 2) 920 done_rate = PRCM_FULL_SPEED; 921 else 922 done_rate = PRCM_HALF_SPEED; 923 924 /* MPU divider */ 925 CM_CLKSEL_MPU = prcm->cm_clksel_mpu; 926 927 /* dsp + iva1 div(2420), iva2.1(2430) */ 928 CM_CLKSEL_DSP = prcm->cm_clksel_dsp; 929 930 CM_CLKSEL_GFX = prcm->cm_clksel_gfx; 931 932 /* Major subsystem dividers */ 933 CM_CLKSEL1_CORE = prcm->cm_clksel1_core; 934 if (cpu_is_omap2430()) 935 CM_CLKSEL_MDM = prcm->cm_clksel_mdm; 936 937 /* x2 to enter init_mem */ 938 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); 939 940 omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr, 941 bypass); 942 943 omap2_init_memory_params(omap2_dll_force_needed()); 944 omap2_reprogram_sdrc(done_rate, 0); 945 946 local_irq_restore(flags); 947 } 948 omap2_clksel_recalc(&dpll_ck); 949 950 return 0; 951 } 952 953 /*------------------------------------------------------------------------- 954 * Omap2 clock reset and init functions 955 *-------------------------------------------------------------------------*/ 956 957 static struct clk_functions omap2_clk_functions = { 958 .clk_enable = omap2_clk_enable, 959 .clk_disable = omap2_clk_disable, 960 .clk_round_rate = omap2_clk_round_rate, 961 .clk_set_rate = omap2_clk_set_rate, 962 .clk_set_parent = omap2_clk_set_parent, 963 }; 964 965 static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) 966 { 967 u32 div, aplls, sclk = 13000000; 968 969 aplls = CM_CLKSEL1_PLL; 970 aplls &= ((1 << 23) | (1 << 24) | (1 << 25)); 971 aplls >>= 23; /* Isolate field, 0,2,3 */ 972 973 if (aplls == 0) 974 sclk = 19200000; 975 else if (aplls == 2) 976 sclk = 13000000; 977 else if (aplls == 3) 978 sclk = 12000000; 979 980 div = PRCM_CLKSRC_CTRL; 981 div &= ((1 << 7) | (1 << 6)); 982 div >>= sys->rate_offset; 983 984 osc->rate = sclk * div; 985 sys->rate = sclk; 986 } 987 988 #ifdef CONFIG_OMAP_RESET_CLOCKS 989 static void __init omap2_disable_unused_clocks(void) 990 { 991 struct clk *ck; 992 u32 regval32; 993 994 list_for_each_entry(ck, &clocks, node) { 995 if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || 996 ck->enable_reg == 0) 997 continue; 998 999 regval32 = __raw_readl(ck->enable_reg); 1000 if ((regval32 & (1 << ck->enable_bit)) == 0) 1001 continue; 1002 1003 printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); 1004 _omap2_clk_disable(ck); 1005 } 1006 } 1007 late_initcall(omap2_disable_unused_clocks); 1008 #endif 1009 1010 /* 1011 * Switch the MPU rate if specified on cmdline. 1012 * We cannot do this early until cmdline is parsed. 1013 */ 1014 static int __init omap2_clk_arch_init(void) 1015 { 1016 if (!mpurate) 1017 return -EINVAL; 1018 1019 if (omap2_select_table_rate(&virt_prcm_set, mpurate)) 1020 printk(KERN_ERR "Could not find matching MPU rate\n"); 1021 1022 propagate_rate(&osc_ck); /* update main root fast */ 1023 propagate_rate(&func_32k_ck); /* update main root slow */ 1024 1025 printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): " 1026 "%ld.%01ld/%ld/%ld MHz\n", 1027 (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, 1028 (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; 1029 1030 return 0; 1031 } 1032 arch_initcall(omap2_clk_arch_init); 1033 1034 int __init omap2_clk_init(void) 1035 { 1036 struct prcm_config *prcm; 1037 struct clk ** clkp; 1038 u32 clkrate; 1039 1040 clk_init(&omap2_clk_functions); 1041 omap2_get_crystal_rate(&osc_ck, &sys_ck); 1042 1043 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks); 1044 clkp++) { 1045 1046 if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) { 1047 clk_register(*clkp); 1048 continue; 1049 } 1050 1051 if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) { 1052 clk_register(*clkp); 1053 continue; 1054 } 1055 } 1056 1057 /* Check the MPU rate set by bootloader */ 1058 clkrate = omap2_get_dpll_rate(&dpll_ck); 1059 for (prcm = rate_table; prcm->mpu_speed; prcm++) { 1060 if (prcm->xtal_speed != sys_ck.rate) 1061 continue; 1062 if (prcm->dpll_speed <= clkrate) 1063 break; 1064 } 1065 curr_prcm_set = prcm; 1066 1067 propagate_rate(&osc_ck); /* update main root fast */ 1068 propagate_rate(&func_32k_ck); /* update main root slow */ 1069 1070 printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): " 1071 "%ld.%01ld/%ld/%ld MHz\n", 1072 (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, 1073 (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; 1074 1075 /* 1076 * Only enable those clocks we will need, let the drivers 1077 * enable other clocks as necessary 1078 */ 1079 clk_enable(&sync_32k_ick); 1080 clk_enable(&omapctrl_ick); 1081 if (cpu_is_omap2430()) 1082 clk_enable(&sdrc_ick); 1083 1084 return 0; 1085 } 1086