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