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