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->src_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: field_val = 4; break; 675 case 8: field_val = 3; break; 676 case 4: field_val = 2; break; 677 case 2: field_val = 1; break; 678 case 1: field_val = 0; break; 679 } 680 } 681 else 682 field_val = new_div; 683 684 reg = (void __iomem *)div_sel; 685 686 reg_val = __raw_readl(reg); 687 reg_val &= ~(field_mask << div_off); 688 reg_val |= (field_val << div_off); 689 690 __raw_writel(reg_val, reg); 691 clk->rate = clk->parent->rate / field_val; 692 693 if (clk->flags & DELAYED_APP) 694 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); 695 ret = 0; 696 } else if (clk->set_rate != 0) 697 ret = clk->set_rate(clk, rate); 698 699 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) 700 propagate_rate(clk); 701 702 return ret; 703 } 704 705 /* Converts encoded control register address into a full address */ 706 static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset, 707 struct clk *src_clk, u32 *field_mask) 708 { 709 u32 val = ~0, src_reg_addr = 0, mask = 0; 710 711 /* Find target control register.*/ 712 switch ((*type_to_addr & SRC_RATE_SEL_MASK)) { 713 case CM_CORE_SEL1: 714 src_reg_addr = (u32)&CM_CLKSEL1_CORE; 715 if (reg_offset == 13) { /* DSS2_fclk */ 716 mask = 0x1; 717 if (src_clk == &sys_ck) 718 val = 0; 719 if (src_clk == &func_48m_ck) 720 val = 1; 721 } else if (reg_offset == 8) { /* DSS1_fclk */ 722 mask = 0x1f; 723 if (src_clk == &sys_ck) 724 val = 0; 725 else if (src_clk == &core_ck) /* divided clock */ 726 val = 0x10; /* rate needs fixing */ 727 } else if ((reg_offset == 15) && cpu_is_omap2420()){ /*vlnyq*/ 728 mask = 0x1F; 729 if(src_clk == &func_96m_ck) 730 val = 0; 731 else if (src_clk == &core_ck) 732 val = 0x10; 733 } 734 break; 735 case CM_CORE_SEL2: 736 src_reg_addr = (u32)&CM_CLKSEL2_CORE; 737 mask = 0x3; 738 if (src_clk == &func_32k_ck) 739 val = 0x0; 740 if (src_clk == &sys_ck) 741 val = 0x1; 742 if (src_clk == &alt_ck) 743 val = 0x2; 744 break; 745 case CM_WKUP_SEL1: 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_PLL_SEL1: 756 src_reg_addr = (u32)&CM_CLKSEL1_PLL; 757 mask = 0x1; 758 if (reg_offset == 0x3) { 759 if (src_clk == &apll96_ck) 760 val = 0; 761 if (src_clk == &alt_ck) 762 val = 1; 763 } 764 else if (reg_offset == 0x5) { 765 if (src_clk == &apll54_ck) 766 val = 0; 767 if (src_clk == &alt_ck) 768 val = 1; 769 } 770 break; 771 case CM_PLL_SEL2: 772 src_reg_addr = (u32)&CM_CLKSEL2_PLL; 773 mask = 0x3; 774 if (src_clk == &func_32k_ck) 775 val = 0x0; 776 if (src_clk == &dpll_ck) 777 val = 0x2; 778 break; 779 case CM_SYSCLKOUT_SEL1: 780 src_reg_addr = (u32)&PRCM_CLKOUT_CTRL; 781 mask = 0x3; 782 if (src_clk == &dpll_ck) 783 val = 0; 784 if (src_clk == &sys_ck) 785 val = 1; 786 if (src_clk == &func_54m_ck) 787 val = 2; 788 if (src_clk == &func_96m_ck) 789 val = 3; 790 break; 791 } 792 793 if (val == ~0) /* Catch errors in offset */ 794 *type_to_addr = 0; 795 else 796 *type_to_addr = src_reg_addr; 797 *field_mask = mask; 798 799 return val; 800 } 801 802 static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) 803 { 804 void __iomem * reg; 805 u32 src_sel, src_off, field_val, field_mask, reg_val, rate; 806 int ret = -EINVAL; 807 808 if (unlikely(clk->flags & CONFIG_PARTICIPANT)) 809 return ret; 810 811 if (clk->flags & SRC_SEL_MASK) { /* On-chip SEL collection */ 812 src_sel = (SRC_RATE_SEL_MASK & clk->flags); 813 src_off = clk->src_offset; 814 815 if (src_sel == 0) 816 goto set_parent_error; 817 818 field_val = omap2_get_src_field(&src_sel, src_off, new_parent, 819 &field_mask); 820 821 reg = (void __iomem *)src_sel; 822 823 if (clk->usecount > 0) 824 _omap2_clk_disable(clk); 825 826 /* Set new source value (previous dividers if any in effect) */ 827 reg_val = __raw_readl(reg) & ~(field_mask << src_off); 828 reg_val |= (field_val << src_off); 829 __raw_writel(reg_val, reg); 830 831 if (clk->flags & DELAYED_APP) 832 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); 833 834 if (clk->usecount > 0) 835 _omap2_clk_enable(clk); 836 837 clk->parent = new_parent; 838 839 /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/ 840 if ((new_parent == &core_ck) && (clk == &dss1_fck)) 841 clk->rate = new_parent->rate / 0x10; 842 else 843 clk->rate = new_parent->rate; 844 845 if (unlikely(clk->flags & RATE_PROPAGATES)) 846 propagate_rate(clk); 847 848 return 0; 849 } else { 850 clk->parent = new_parent; 851 rate = new_parent->rate; 852 omap2_clk_set_rate(clk, rate); 853 ret = 0; 854 } 855 856 set_parent_error: 857 return ret; 858 } 859 860 /* Sets basic clocks based on the specified rate */ 861 static int omap2_select_table_rate(struct clk * clk, unsigned long rate) 862 { 863 u32 flags, cur_rate, done_rate, bypass = 0; 864 u8 cpu_mask = 0; 865 struct prcm_config *prcm; 866 unsigned long found_speed = 0; 867 868 if (clk != &virt_prcm_set) 869 return -EINVAL; 870 871 /* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */ 872 if (cpu_is_omap2420()) 873 cpu_mask = RATE_IN_242X; 874 else if (cpu_is_omap2430()) 875 cpu_mask = RATE_IN_243X; 876 877 for (prcm = rate_table; prcm->mpu_speed; prcm++) { 878 if (!(prcm->flags & cpu_mask)) 879 continue; 880 881 if (prcm->xtal_speed != sys_ck.rate) 882 continue; 883 884 if (prcm->mpu_speed <= rate) { 885 found_speed = prcm->mpu_speed; 886 break; 887 } 888 } 889 890 if (!found_speed) { 891 printk(KERN_INFO "Could not set MPU rate to %luMHz\n", 892 rate / 1000000); 893 return -EINVAL; 894 } 895 896 curr_prcm_set = prcm; 897 cur_rate = omap2_get_dpll_rate(&dpll_ck); 898 899 if (prcm->dpll_speed == cur_rate / 2) { 900 omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1); 901 } else if (prcm->dpll_speed == cur_rate * 2) { 902 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); 903 } else if (prcm->dpll_speed != cur_rate) { 904 local_irq_save(flags); 905 906 if (prcm->dpll_speed == prcm->xtal_speed) 907 bypass = 1; 908 909 if ((prcm->cm_clksel2_pll & 0x3) == 2) 910 done_rate = PRCM_FULL_SPEED; 911 else 912 done_rate = PRCM_HALF_SPEED; 913 914 /* MPU divider */ 915 CM_CLKSEL_MPU = prcm->cm_clksel_mpu; 916 917 /* dsp + iva1 div(2420), iva2.1(2430) */ 918 CM_CLKSEL_DSP = prcm->cm_clksel_dsp; 919 920 CM_CLKSEL_GFX = prcm->cm_clksel_gfx; 921 922 /* Major subsystem dividers */ 923 CM_CLKSEL1_CORE = prcm->cm_clksel1_core; 924 if (cpu_is_omap2430()) 925 CM_CLKSEL_MDM = prcm->cm_clksel_mdm; 926 927 /* x2 to enter init_mem */ 928 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); 929 930 omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr, 931 bypass); 932 933 omap2_init_memory_params(omap2_dll_force_needed()); 934 omap2_reprogram_sdrc(done_rate, 0); 935 936 local_irq_restore(flags); 937 } 938 omap2_clksel_recalc(&dpll_ck); 939 940 return 0; 941 } 942 943 /*------------------------------------------------------------------------- 944 * Omap2 clock reset and init functions 945 *-------------------------------------------------------------------------*/ 946 947 static struct clk_functions omap2_clk_functions = { 948 .clk_enable = omap2_clk_enable, 949 .clk_disable = omap2_clk_disable, 950 .clk_round_rate = omap2_clk_round_rate, 951 .clk_set_rate = omap2_clk_set_rate, 952 .clk_set_parent = omap2_clk_set_parent, 953 }; 954 955 static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) 956 { 957 u32 div, aplls, sclk = 13000000; 958 959 aplls = CM_CLKSEL1_PLL; 960 aplls &= ((1 << 23) | (1 << 24) | (1 << 25)); 961 aplls >>= 23; /* Isolate field, 0,2,3 */ 962 963 if (aplls == 0) 964 sclk = 19200000; 965 else if (aplls == 2) 966 sclk = 13000000; 967 else if (aplls == 3) 968 sclk = 12000000; 969 970 div = PRCM_CLKSRC_CTRL; 971 div &= ((1 << 7) | (1 << 6)); 972 div >>= sys->rate_offset; 973 974 osc->rate = sclk * div; 975 sys->rate = sclk; 976 } 977 978 #ifdef CONFIG_OMAP_RESET_CLOCKS 979 static void __init omap2_disable_unused_clocks(void) 980 { 981 struct clk *ck; 982 u32 regval32; 983 984 list_for_each_entry(ck, &clocks, node) { 985 if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || 986 ck->enable_reg == 0) 987 continue; 988 989 regval32 = __raw_readl(ck->enable_reg); 990 if ((regval32 & (1 << ck->enable_bit)) == 0) 991 continue; 992 993 printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); 994 _omap2_clk_disable(ck); 995 } 996 } 997 late_initcall(omap2_disable_unused_clocks); 998 #endif 999 1000 /* 1001 * Switch the MPU rate if specified on cmdline. 1002 * We cannot do this early until cmdline is parsed. 1003 */ 1004 static int __init omap2_clk_arch_init(void) 1005 { 1006 if (!mpurate) 1007 return -EINVAL; 1008 1009 if (omap2_select_table_rate(&virt_prcm_set, mpurate)) 1010 printk(KERN_ERR "Could not find matching MPU rate\n"); 1011 1012 propagate_rate(&osc_ck); /* update main root fast */ 1013 propagate_rate(&func_32k_ck); /* update main root slow */ 1014 1015 printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): " 1016 "%ld.%01ld/%ld/%ld MHz\n", 1017 (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, 1018 (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; 1019 1020 return 0; 1021 } 1022 arch_initcall(omap2_clk_arch_init); 1023 1024 int __init omap2_clk_init(void) 1025 { 1026 struct prcm_config *prcm; 1027 struct clk ** clkp; 1028 u32 clkrate; 1029 1030 clk_init(&omap2_clk_functions); 1031 omap2_get_crystal_rate(&osc_ck, &sys_ck); 1032 1033 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks); 1034 clkp++) { 1035 1036 if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) { 1037 clk_register(*clkp); 1038 continue; 1039 } 1040 1041 if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) { 1042 clk_register(*clkp); 1043 continue; 1044 } 1045 } 1046 1047 /* Check the MPU rate set by bootloader */ 1048 clkrate = omap2_get_dpll_rate(&dpll_ck); 1049 for (prcm = rate_table; prcm->mpu_speed; prcm++) { 1050 if (prcm->xtal_speed != sys_ck.rate) 1051 continue; 1052 if (prcm->dpll_speed <= clkrate) 1053 break; 1054 } 1055 curr_prcm_set = prcm; 1056 1057 propagate_rate(&osc_ck); /* update main root fast */ 1058 propagate_rate(&func_32k_ck); /* update main root slow */ 1059 1060 printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): " 1061 "%ld.%01ld/%ld/%ld MHz\n", 1062 (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, 1063 (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; 1064 1065 /* 1066 * Only enable those clocks we will need, let the drivers 1067 * enable other clocks as necessary 1068 */ 1069 clk_enable(&sync_32k_ick); 1070 clk_enable(&omapctrl_ick); 1071 if (cpu_is_omap2430()) 1072 clk_enable(&sdrc_ick); 1073 1074 return 0; 1075 } 1076