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