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