1 /* 2 * linux/arch/arm/mach-omap1/clock.c 3 * 4 * Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation 5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> 6 * 7 * Modified to use omap shared clock framework by 8 * Tony Lindgren <tony@atomide.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 #include <linux/kernel.h> 15 #include <linux/list.h> 16 #include <linux/errno.h> 17 #include <linux/err.h> 18 #include <linux/io.h> 19 #include <linux/clk.h> 20 #include <linux/clkdev.h> 21 22 #include <asm/mach-types.h> 23 24 #include <plat/cpu.h> 25 #include <plat/usb.h> 26 #include <plat/clock.h> 27 #include <plat/sram.h> 28 #include <plat/clkdev_omap.h> 29 30 #include <mach/hardware.h> 31 32 #include "iomap.h" 33 #include "clock.h" 34 #include "opp.h" 35 36 __u32 arm_idlect1_mask; 37 struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p; 38 39 /* 40 * Omap1 specific clock functions 41 */ 42 43 unsigned long omap1_uart_recalc(struct clk *clk) 44 { 45 unsigned int val = __raw_readl(clk->enable_reg); 46 return val & clk->enable_bit ? 48000000 : 12000000; 47 } 48 49 unsigned long omap1_sossi_recalc(struct clk *clk) 50 { 51 u32 div = omap_readl(MOD_CONF_CTRL_1); 52 53 div = (div >> 17) & 0x7; 54 div++; 55 56 return clk->parent->rate / div; 57 } 58 59 static void omap1_clk_allow_idle(struct clk *clk) 60 { 61 struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; 62 63 if (!(clk->flags & CLOCK_IDLE_CONTROL)) 64 return; 65 66 if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count)) 67 arm_idlect1_mask |= 1 << iclk->idlect_shift; 68 } 69 70 static void omap1_clk_deny_idle(struct clk *clk) 71 { 72 struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; 73 74 if (!(clk->flags & CLOCK_IDLE_CONTROL)) 75 return; 76 77 if (iclk->no_idle_count++ == 0) 78 arm_idlect1_mask &= ~(1 << iclk->idlect_shift); 79 } 80 81 static __u16 verify_ckctl_value(__u16 newval) 82 { 83 /* This function checks for following limitations set 84 * by the hardware (all conditions must be true): 85 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2 86 * ARM_CK >= TC_CK 87 * DSP_CK >= TC_CK 88 * DSPMMU_CK >= TC_CK 89 * 90 * In addition following rules are enforced: 91 * LCD_CK <= TC_CK 92 * ARMPER_CK <= TC_CK 93 * 94 * However, maximum frequencies are not checked for! 95 */ 96 __u8 per_exp; 97 __u8 lcd_exp; 98 __u8 arm_exp; 99 __u8 dsp_exp; 100 __u8 tc_exp; 101 __u8 dspmmu_exp; 102 103 per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3; 104 lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3; 105 arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3; 106 dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3; 107 tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3; 108 dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3; 109 110 if (dspmmu_exp < dsp_exp) 111 dspmmu_exp = dsp_exp; 112 if (dspmmu_exp > dsp_exp+1) 113 dspmmu_exp = dsp_exp+1; 114 if (tc_exp < arm_exp) 115 tc_exp = arm_exp; 116 if (tc_exp < dspmmu_exp) 117 tc_exp = dspmmu_exp; 118 if (tc_exp > lcd_exp) 119 lcd_exp = tc_exp; 120 if (tc_exp > per_exp) 121 per_exp = tc_exp; 122 123 newval &= 0xf000; 124 newval |= per_exp << CKCTL_PERDIV_OFFSET; 125 newval |= lcd_exp << CKCTL_LCDDIV_OFFSET; 126 newval |= arm_exp << CKCTL_ARMDIV_OFFSET; 127 newval |= dsp_exp << CKCTL_DSPDIV_OFFSET; 128 newval |= tc_exp << CKCTL_TCDIV_OFFSET; 129 newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET; 130 131 return newval; 132 } 133 134 static int calc_dsor_exp(struct clk *clk, unsigned long rate) 135 { 136 /* Note: If target frequency is too low, this function will return 4, 137 * which is invalid value. Caller must check for this value and act 138 * accordingly. 139 * 140 * Note: This function does not check for following limitations set 141 * by the hardware (all conditions must be true): 142 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2 143 * ARM_CK >= TC_CK 144 * DSP_CK >= TC_CK 145 * DSPMMU_CK >= TC_CK 146 */ 147 unsigned long realrate; 148 struct clk * parent; 149 unsigned dsor_exp; 150 151 parent = clk->parent; 152 if (unlikely(parent == NULL)) 153 return -EIO; 154 155 realrate = parent->rate; 156 for (dsor_exp=0; dsor_exp<4; dsor_exp++) { 157 if (realrate <= rate) 158 break; 159 160 realrate /= 2; 161 } 162 163 return dsor_exp; 164 } 165 166 unsigned long omap1_ckctl_recalc(struct clk *clk) 167 { 168 /* Calculate divisor encoded as 2-bit exponent */ 169 int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); 170 171 return clk->parent->rate / dsor; 172 } 173 174 unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk) 175 { 176 int dsor; 177 178 /* Calculate divisor encoded as 2-bit exponent 179 * 180 * The clock control bits are in DSP domain, 181 * so api_ck is needed for access. 182 * Note that DSP_CKCTL virt addr = phys addr, so 183 * we must use __raw_readw() instead of omap_readw(). 184 */ 185 omap1_clk_enable(api_ck_p); 186 dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); 187 omap1_clk_disable(api_ck_p); 188 189 return clk->parent->rate / dsor; 190 } 191 192 /* MPU virtual clock functions */ 193 int omap1_select_table_rate(struct clk *clk, unsigned long rate) 194 { 195 /* Find the highest supported frequency <= rate and switch to it */ 196 struct mpu_rate * ptr; 197 unsigned long ref_rate; 198 199 ref_rate = ck_ref_p->rate; 200 201 for (ptr = omap1_rate_table; ptr->rate; ptr++) { 202 if (!(ptr->flags & cpu_mask)) 203 continue; 204 205 if (ptr->xtal != ref_rate) 206 continue; 207 208 /* Can check only after xtal frequency check */ 209 if (ptr->rate <= rate) 210 break; 211 } 212 213 if (!ptr->rate) 214 return -EINVAL; 215 216 /* 217 * In most cases we should not need to reprogram DPLL. 218 * Reprogramming the DPLL is tricky, it must be done from SRAM. 219 */ 220 omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); 221 222 /* XXX Do we need to recalculate the tree below DPLL1 at this point? */ 223 ck_dpll1_p->rate = ptr->pll_rate; 224 225 return 0; 226 } 227 228 int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) 229 { 230 int dsor_exp; 231 u16 regval; 232 233 dsor_exp = calc_dsor_exp(clk, rate); 234 if (dsor_exp > 3) 235 dsor_exp = -EINVAL; 236 if (dsor_exp < 0) 237 return dsor_exp; 238 239 regval = __raw_readw(DSP_CKCTL); 240 regval &= ~(3 << clk->rate_offset); 241 regval |= dsor_exp << clk->rate_offset; 242 __raw_writew(regval, DSP_CKCTL); 243 clk->rate = clk->parent->rate / (1 << dsor_exp); 244 245 return 0; 246 } 247 248 long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate) 249 { 250 int dsor_exp = calc_dsor_exp(clk, rate); 251 if (dsor_exp < 0) 252 return dsor_exp; 253 if (dsor_exp > 3) 254 dsor_exp = 3; 255 return clk->parent->rate / (1 << dsor_exp); 256 } 257 258 int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate) 259 { 260 int dsor_exp; 261 u16 regval; 262 263 dsor_exp = calc_dsor_exp(clk, rate); 264 if (dsor_exp > 3) 265 dsor_exp = -EINVAL; 266 if (dsor_exp < 0) 267 return dsor_exp; 268 269 regval = omap_readw(ARM_CKCTL); 270 regval &= ~(3 << clk->rate_offset); 271 regval |= dsor_exp << clk->rate_offset; 272 regval = verify_ckctl_value(regval); 273 omap_writew(regval, ARM_CKCTL); 274 clk->rate = clk->parent->rate / (1 << dsor_exp); 275 return 0; 276 } 277 278 long omap1_round_to_table_rate(struct clk *clk, unsigned long rate) 279 { 280 /* Find the highest supported frequency <= rate */ 281 struct mpu_rate * ptr; 282 long highest_rate; 283 unsigned long ref_rate; 284 285 ref_rate = ck_ref_p->rate; 286 287 highest_rate = -EINVAL; 288 289 for (ptr = omap1_rate_table; ptr->rate; ptr++) { 290 if (!(ptr->flags & cpu_mask)) 291 continue; 292 293 if (ptr->xtal != ref_rate) 294 continue; 295 296 highest_rate = ptr->rate; 297 298 /* Can check only after xtal frequency check */ 299 if (ptr->rate <= rate) 300 break; 301 } 302 303 return highest_rate; 304 } 305 306 static unsigned calc_ext_dsor(unsigned long rate) 307 { 308 unsigned dsor; 309 310 /* MCLK and BCLK divisor selection is not linear: 311 * freq = 96MHz / dsor 312 * 313 * RATIO_SEL range: dsor <-> RATIO_SEL 314 * 0..6: (RATIO_SEL+2) <-> (dsor-2) 315 * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6) 316 * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9 317 * can not be used. 318 */ 319 for (dsor = 2; dsor < 96; ++dsor) { 320 if ((dsor & 1) && dsor > 8) 321 continue; 322 if (rate >= 96000000 / dsor) 323 break; 324 } 325 return dsor; 326 } 327 328 /* XXX Only needed on 1510 */ 329 int omap1_set_uart_rate(struct clk *clk, unsigned long rate) 330 { 331 unsigned int val; 332 333 val = __raw_readl(clk->enable_reg); 334 if (rate == 12000000) 335 val &= ~(1 << clk->enable_bit); 336 else if (rate == 48000000) 337 val |= (1 << clk->enable_bit); 338 else 339 return -EINVAL; 340 __raw_writel(val, clk->enable_reg); 341 clk->rate = rate; 342 343 return 0; 344 } 345 346 /* External clock (MCLK & BCLK) functions */ 347 int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate) 348 { 349 unsigned dsor; 350 __u16 ratio_bits; 351 352 dsor = calc_ext_dsor(rate); 353 clk->rate = 96000000 / dsor; 354 if (dsor > 8) 355 ratio_bits = ((dsor - 8) / 2 + 6) << 2; 356 else 357 ratio_bits = (dsor - 2) << 2; 358 359 ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd; 360 __raw_writew(ratio_bits, clk->enable_reg); 361 362 return 0; 363 } 364 365 int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) 366 { 367 u32 l; 368 int div; 369 unsigned long p_rate; 370 371 p_rate = clk->parent->rate; 372 /* Round towards slower frequency */ 373 div = (p_rate + rate - 1) / rate; 374 div--; 375 if (div < 0 || div > 7) 376 return -EINVAL; 377 378 l = omap_readl(MOD_CONF_CTRL_1); 379 l &= ~(7 << 17); 380 l |= div << 17; 381 omap_writel(l, MOD_CONF_CTRL_1); 382 383 clk->rate = p_rate / (div + 1); 384 385 return 0; 386 } 387 388 long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate) 389 { 390 return 96000000 / calc_ext_dsor(rate); 391 } 392 393 void omap1_init_ext_clk(struct clk *clk) 394 { 395 unsigned dsor; 396 __u16 ratio_bits; 397 398 /* Determine current rate and ensure clock is based on 96MHz APLL */ 399 ratio_bits = __raw_readw(clk->enable_reg) & ~1; 400 __raw_writew(ratio_bits, clk->enable_reg); 401 402 ratio_bits = (ratio_bits & 0xfc) >> 2; 403 if (ratio_bits > 6) 404 dsor = (ratio_bits - 6) * 2 + 8; 405 else 406 dsor = ratio_bits + 2; 407 408 clk-> rate = 96000000 / dsor; 409 } 410 411 int omap1_clk_enable(struct clk *clk) 412 { 413 int ret = 0; 414 415 if (clk->usecount++ == 0) { 416 if (clk->parent) { 417 ret = omap1_clk_enable(clk->parent); 418 if (ret) 419 goto err; 420 421 if (clk->flags & CLOCK_NO_IDLE_PARENT) 422 omap1_clk_deny_idle(clk->parent); 423 } 424 425 ret = clk->ops->enable(clk); 426 if (ret) { 427 if (clk->parent) 428 omap1_clk_disable(clk->parent); 429 goto err; 430 } 431 } 432 return ret; 433 434 err: 435 clk->usecount--; 436 return ret; 437 } 438 439 void omap1_clk_disable(struct clk *clk) 440 { 441 if (clk->usecount > 0 && !(--clk->usecount)) { 442 clk->ops->disable(clk); 443 if (likely(clk->parent)) { 444 omap1_clk_disable(clk->parent); 445 if (clk->flags & CLOCK_NO_IDLE_PARENT) 446 omap1_clk_allow_idle(clk->parent); 447 } 448 } 449 } 450 451 static int omap1_clk_enable_generic(struct clk *clk) 452 { 453 __u16 regval16; 454 __u32 regval32; 455 456 if (unlikely(clk->enable_reg == NULL)) { 457 printk(KERN_ERR "clock.c: Enable for %s without enable code\n", 458 clk->name); 459 return -EINVAL; 460 } 461 462 if (clk->flags & ENABLE_REG_32BIT) { 463 regval32 = __raw_readl(clk->enable_reg); 464 regval32 |= (1 << clk->enable_bit); 465 __raw_writel(regval32, clk->enable_reg); 466 } else { 467 regval16 = __raw_readw(clk->enable_reg); 468 regval16 |= (1 << clk->enable_bit); 469 __raw_writew(regval16, clk->enable_reg); 470 } 471 472 return 0; 473 } 474 475 static void omap1_clk_disable_generic(struct clk *clk) 476 { 477 __u16 regval16; 478 __u32 regval32; 479 480 if (clk->enable_reg == NULL) 481 return; 482 483 if (clk->flags & ENABLE_REG_32BIT) { 484 regval32 = __raw_readl(clk->enable_reg); 485 regval32 &= ~(1 << clk->enable_bit); 486 __raw_writel(regval32, clk->enable_reg); 487 } else { 488 regval16 = __raw_readw(clk->enable_reg); 489 regval16 &= ~(1 << clk->enable_bit); 490 __raw_writew(regval16, clk->enable_reg); 491 } 492 } 493 494 const struct clkops clkops_generic = { 495 .enable = omap1_clk_enable_generic, 496 .disable = omap1_clk_disable_generic, 497 }; 498 499 static int omap1_clk_enable_dsp_domain(struct clk *clk) 500 { 501 int retval; 502 503 retval = omap1_clk_enable(api_ck_p); 504 if (!retval) { 505 retval = omap1_clk_enable_generic(clk); 506 omap1_clk_disable(api_ck_p); 507 } 508 509 return retval; 510 } 511 512 static void omap1_clk_disable_dsp_domain(struct clk *clk) 513 { 514 if (omap1_clk_enable(api_ck_p) == 0) { 515 omap1_clk_disable_generic(clk); 516 omap1_clk_disable(api_ck_p); 517 } 518 } 519 520 const struct clkops clkops_dspck = { 521 .enable = omap1_clk_enable_dsp_domain, 522 .disable = omap1_clk_disable_dsp_domain, 523 }; 524 525 /* XXX SYSC register handling does not belong in the clock framework */ 526 static int omap1_clk_enable_uart_functional_16xx(struct clk *clk) 527 { 528 int ret; 529 struct uart_clk *uclk; 530 531 ret = omap1_clk_enable_generic(clk); 532 if (ret == 0) { 533 /* Set smart idle acknowledgement mode */ 534 uclk = (struct uart_clk *)clk; 535 omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8, 536 uclk->sysc_addr); 537 } 538 539 return ret; 540 } 541 542 /* XXX SYSC register handling does not belong in the clock framework */ 543 static void omap1_clk_disable_uart_functional_16xx(struct clk *clk) 544 { 545 struct uart_clk *uclk; 546 547 /* Set force idle acknowledgement mode */ 548 uclk = (struct uart_clk *)clk; 549 omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr); 550 551 omap1_clk_disable_generic(clk); 552 } 553 554 /* XXX SYSC register handling does not belong in the clock framework */ 555 const struct clkops clkops_uart_16xx = { 556 .enable = omap1_clk_enable_uart_functional_16xx, 557 .disable = omap1_clk_disable_uart_functional_16xx, 558 }; 559 560 long omap1_clk_round_rate(struct clk *clk, unsigned long rate) 561 { 562 if (clk->round_rate != NULL) 563 return clk->round_rate(clk, rate); 564 565 return clk->rate; 566 } 567 568 int omap1_clk_set_rate(struct clk *clk, unsigned long rate) 569 { 570 int ret = -EINVAL; 571 572 if (clk->set_rate) 573 ret = clk->set_rate(clk, rate); 574 return ret; 575 } 576 577 /* 578 * Omap1 clock reset and init functions 579 */ 580 581 #ifdef CONFIG_OMAP_RESET_CLOCKS 582 583 void omap1_clk_disable_unused(struct clk *clk) 584 { 585 __u32 regval32; 586 587 /* Clocks in the DSP domain need api_ck. Just assume bootloader 588 * has not enabled any DSP clocks */ 589 if (clk->enable_reg == DSP_IDLECT2) { 590 printk(KERN_INFO "Skipping reset check for DSP domain " 591 "clock \"%s\"\n", clk->name); 592 return; 593 } 594 595 /* Is the clock already disabled? */ 596 if (clk->flags & ENABLE_REG_32BIT) 597 regval32 = __raw_readl(clk->enable_reg); 598 else 599 regval32 = __raw_readw(clk->enable_reg); 600 601 if ((regval32 & (1 << clk->enable_bit)) == 0) 602 return; 603 604 printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); 605 clk->ops->disable(clk); 606 printk(" done\n"); 607 } 608 609 #endif 610