1 /* 2 * OMAP clocks. 3 * 4 * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org> 5 * 6 * Clocks data comes in part from arch/arm/mach-omap1/clock.h in Linux. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, see <http://www.gnu.org/licenses/>. 20 */ 21 #include "hw/hw.h" 22 #include "hw/arm/omap.h" 23 24 struct clk { 25 const char *name; 26 const char *alias; 27 struct clk *parent; 28 struct clk *child1; 29 struct clk *sibling; 30 #define ALWAYS_ENABLED (1 << 0) 31 #define CLOCK_IN_OMAP310 (1 << 10) 32 #define CLOCK_IN_OMAP730 (1 << 11) 33 #define CLOCK_IN_OMAP1510 (1 << 12) 34 #define CLOCK_IN_OMAP16XX (1 << 13) 35 #define CLOCK_IN_OMAP242X (1 << 14) 36 #define CLOCK_IN_OMAP243X (1 << 15) 37 #define CLOCK_IN_OMAP343X (1 << 16) 38 uint32_t flags; 39 int id; 40 41 int running; /* Is currently ticking */ 42 int enabled; /* Is enabled, regardless of its input clk */ 43 unsigned long rate; /* Current rate (if .running) */ 44 unsigned int divisor; /* Rate relative to input (if .enabled) */ 45 unsigned int multiplier; /* Rate relative to input (if .enabled) */ 46 qemu_irq users[16]; /* Who to notify on change */ 47 int usecount; /* Automatically idle when unused */ 48 }; 49 50 static struct clk xtal_osc12m = { 51 .name = "xtal_osc_12m", 52 .rate = 12000000, 53 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 54 }; 55 56 static struct clk xtal_osc32k = { 57 .name = "xtal_osc_32k", 58 .rate = 32768, 59 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 60 CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 61 }; 62 63 static struct clk ck_ref = { 64 .name = "ck_ref", 65 .alias = "clkin", 66 .parent = &xtal_osc12m, 67 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 68 ALWAYS_ENABLED, 69 }; 70 71 /* If a dpll is disabled it becomes a bypass, child clocks don't stop */ 72 static struct clk dpll1 = { 73 .name = "dpll1", 74 .parent = &ck_ref, 75 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 76 ALWAYS_ENABLED, 77 }; 78 79 static struct clk dpll2 = { 80 .name = "dpll2", 81 .parent = &ck_ref, 82 .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED, 83 }; 84 85 static struct clk dpll3 = { 86 .name = "dpll3", 87 .parent = &ck_ref, 88 .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED, 89 }; 90 91 static struct clk dpll4 = { 92 .name = "dpll4", 93 .parent = &ck_ref, 94 .multiplier = 4, 95 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 96 }; 97 98 static struct clk apll = { 99 .name = "apll", 100 .parent = &ck_ref, 101 .multiplier = 48, 102 .divisor = 12, 103 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 104 }; 105 106 static struct clk ck_48m = { 107 .name = "ck_48m", 108 .parent = &dpll4, /* either dpll4 or apll */ 109 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 110 }; 111 112 static struct clk ck_dpll1out = { 113 .name = "ck_dpll1out", 114 .parent = &dpll1, 115 .flags = CLOCK_IN_OMAP16XX, 116 }; 117 118 static struct clk sossi_ck = { 119 .name = "ck_sossi", 120 .parent = &ck_dpll1out, 121 .flags = CLOCK_IN_OMAP16XX, 122 }; 123 124 static struct clk clkm1 = { 125 .name = "clkm1", 126 .alias = "ck_gen1", 127 .parent = &dpll1, 128 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 129 ALWAYS_ENABLED, 130 }; 131 132 static struct clk clkm2 = { 133 .name = "clkm2", 134 .alias = "ck_gen2", 135 .parent = &dpll1, 136 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 137 ALWAYS_ENABLED, 138 }; 139 140 static struct clk clkm3 = { 141 .name = "clkm3", 142 .alias = "ck_gen3", 143 .parent = &dpll1, /* either dpll1 or ck_ref */ 144 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 145 ALWAYS_ENABLED, 146 }; 147 148 static struct clk arm_ck = { 149 .name = "arm_ck", 150 .alias = "mpu_ck", 151 .parent = &clkm1, 152 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 153 ALWAYS_ENABLED, 154 }; 155 156 static struct clk armper_ck = { 157 .name = "armper_ck", 158 .alias = "mpuper_ck", 159 .parent = &clkm1, 160 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 161 }; 162 163 static struct clk arm_gpio_ck = { 164 .name = "arm_gpio_ck", 165 .alias = "mpu_gpio_ck", 166 .parent = &clkm1, 167 .divisor = 1, 168 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, 169 }; 170 171 static struct clk armxor_ck = { 172 .name = "armxor_ck", 173 .alias = "mpuxor_ck", 174 .parent = &ck_ref, 175 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 176 }; 177 178 static struct clk armtim_ck = { 179 .name = "armtim_ck", 180 .alias = "mputim_ck", 181 .parent = &ck_ref, /* either CLKIN or DPLL1 */ 182 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 183 }; 184 185 static struct clk armwdt_ck = { 186 .name = "armwdt_ck", 187 .alias = "mpuwd_ck", 188 .parent = &clkm1, 189 .divisor = 14, 190 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 191 ALWAYS_ENABLED, 192 }; 193 194 static struct clk arminth_ck16xx = { 195 .name = "arminth_ck", 196 .parent = &arm_ck, 197 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, 198 /* Note: On 16xx the frequency can be divided by 2 by programming 199 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 200 * 201 * 1510 version is in TC clocks. 202 */ 203 }; 204 205 static struct clk dsp_ck = { 206 .name = "dsp_ck", 207 .parent = &clkm2, 208 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, 209 }; 210 211 static struct clk dspmmu_ck = { 212 .name = "dspmmu_ck", 213 .parent = &clkm2, 214 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 215 ALWAYS_ENABLED, 216 }; 217 218 static struct clk dspper_ck = { 219 .name = "dspper_ck", 220 .parent = &clkm2, 221 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, 222 }; 223 224 static struct clk dspxor_ck = { 225 .name = "dspxor_ck", 226 .parent = &ck_ref, 227 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, 228 }; 229 230 static struct clk dsptim_ck = { 231 .name = "dsptim_ck", 232 .parent = &ck_ref, 233 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, 234 }; 235 236 static struct clk tc_ck = { 237 .name = "tc_ck", 238 .parent = &clkm3, 239 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 240 CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 | 241 ALWAYS_ENABLED, 242 }; 243 244 static struct clk arminth_ck15xx = { 245 .name = "arminth_ck", 246 .parent = &tc_ck, 247 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, 248 /* Note: On 1510 the frequency follows TC_CK 249 * 250 * 16xx version is in MPU clocks. 251 */ 252 }; 253 254 static struct clk tipb_ck = { 255 /* No-idle controlled by "tc_ck" */ 256 .name = "tipb_ck", 257 .parent = &tc_ck, 258 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, 259 }; 260 261 static struct clk l3_ocpi_ck = { 262 /* No-idle controlled by "tc_ck" */ 263 .name = "l3_ocpi_ck", 264 .parent = &tc_ck, 265 .flags = CLOCK_IN_OMAP16XX, 266 }; 267 268 static struct clk tc1_ck = { 269 .name = "tc1_ck", 270 .parent = &tc_ck, 271 .flags = CLOCK_IN_OMAP16XX, 272 }; 273 274 static struct clk tc2_ck = { 275 .name = "tc2_ck", 276 .parent = &tc_ck, 277 .flags = CLOCK_IN_OMAP16XX, 278 }; 279 280 static struct clk dma_ck = { 281 /* No-idle controlled by "tc_ck" */ 282 .name = "dma_ck", 283 .parent = &tc_ck, 284 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 285 ALWAYS_ENABLED, 286 }; 287 288 static struct clk dma_lcdfree_ck = { 289 .name = "dma_lcdfree_ck", 290 .parent = &tc_ck, 291 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, 292 }; 293 294 static struct clk api_ck = { 295 .name = "api_ck", 296 .alias = "mpui_ck", 297 .parent = &tc_ck, 298 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 299 }; 300 301 static struct clk lb_ck = { 302 .name = "lb_ck", 303 .parent = &tc_ck, 304 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, 305 }; 306 307 static struct clk lbfree_ck = { 308 .name = "lbfree_ck", 309 .parent = &tc_ck, 310 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, 311 }; 312 313 static struct clk hsab_ck = { 314 .name = "hsab_ck", 315 .parent = &tc_ck, 316 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, 317 }; 318 319 static struct clk rhea1_ck = { 320 .name = "rhea1_ck", 321 .parent = &tc_ck, 322 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, 323 }; 324 325 static struct clk rhea2_ck = { 326 .name = "rhea2_ck", 327 .parent = &tc_ck, 328 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, 329 }; 330 331 static struct clk lcd_ck_16xx = { 332 .name = "lcd_ck", 333 .parent = &clkm3, 334 .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730, 335 }; 336 337 static struct clk lcd_ck_1510 = { 338 .name = "lcd_ck", 339 .parent = &clkm3, 340 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, 341 }; 342 343 static struct clk uart1_1510 = { 344 .name = "uart1_ck", 345 /* Direct from ULPD, no real parent */ 346 .parent = &armper_ck, /* either armper_ck or dpll4 */ 347 .rate = 12000000, 348 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, 349 }; 350 351 static struct clk uart1_16xx = { 352 .name = "uart1_ck", 353 /* Direct from ULPD, no real parent */ 354 .parent = &armper_ck, 355 .rate = 48000000, 356 .flags = CLOCK_IN_OMAP16XX, 357 }; 358 359 static struct clk uart2_ck = { 360 .name = "uart2_ck", 361 /* Direct from ULPD, no real parent */ 362 .parent = &armper_ck, /* either armper_ck or dpll4 */ 363 .rate = 12000000, 364 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | 365 ALWAYS_ENABLED, 366 }; 367 368 static struct clk uart3_1510 = { 369 .name = "uart3_ck", 370 /* Direct from ULPD, no real parent */ 371 .parent = &armper_ck, /* either armper_ck or dpll4 */ 372 .rate = 12000000, 373 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, 374 }; 375 376 static struct clk uart3_16xx = { 377 .name = "uart3_ck", 378 /* Direct from ULPD, no real parent */ 379 .parent = &armper_ck, 380 .rate = 48000000, 381 .flags = CLOCK_IN_OMAP16XX, 382 }; 383 384 static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */ 385 .name = "usb_clk0", 386 .alias = "usb.clko", 387 /* Direct from ULPD, no parent */ 388 .rate = 6000000, 389 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 390 }; 391 392 static struct clk usb_hhc_ck1510 = { 393 .name = "usb_hhc_ck", 394 /* Direct from ULPD, no parent */ 395 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ 396 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, 397 }; 398 399 static struct clk usb_hhc_ck16xx = { 400 .name = "usb_hhc_ck", 401 /* Direct from ULPD, no parent */ 402 .rate = 48000000, 403 /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ 404 .flags = CLOCK_IN_OMAP16XX, 405 }; 406 407 static struct clk usb_w2fc_mclk = { 408 .name = "usb_w2fc_mclk", 409 .alias = "usb_w2fc_ck", 410 .parent = &ck_48m, 411 .rate = 48000000, 412 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, 413 }; 414 415 static struct clk mclk_1510 = { 416 .name = "mclk", 417 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 418 .rate = 12000000, 419 .flags = CLOCK_IN_OMAP1510, 420 }; 421 422 static struct clk bclk_310 = { 423 .name = "bt_mclk_out", /* Alias midi_mclk_out? */ 424 .parent = &armper_ck, 425 .flags = CLOCK_IN_OMAP310, 426 }; 427 428 static struct clk mclk_310 = { 429 .name = "com_mclk_out", 430 .parent = &armper_ck, 431 .flags = CLOCK_IN_OMAP310, 432 }; 433 434 static struct clk mclk_16xx = { 435 .name = "mclk", 436 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 437 .flags = CLOCK_IN_OMAP16XX, 438 }; 439 440 static struct clk bclk_1510 = { 441 .name = "bclk", 442 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 443 .rate = 12000000, 444 .flags = CLOCK_IN_OMAP1510, 445 }; 446 447 static struct clk bclk_16xx = { 448 .name = "bclk", 449 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 450 .flags = CLOCK_IN_OMAP16XX, 451 }; 452 453 static struct clk mmc1_ck = { 454 .name = "mmc_ck", 455 .id = 1, 456 /* Functional clock is direct from ULPD, interface clock is ARMPER */ 457 .parent = &armper_ck, /* either armper_ck or dpll4 */ 458 .rate = 48000000, 459 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, 460 }; 461 462 static struct clk mmc2_ck = { 463 .name = "mmc_ck", 464 .id = 2, 465 /* Functional clock is direct from ULPD, interface clock is ARMPER */ 466 .parent = &armper_ck, 467 .rate = 48000000, 468 .flags = CLOCK_IN_OMAP16XX, 469 }; 470 471 static struct clk cam_mclk = { 472 .name = "cam.mclk", 473 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, 474 .rate = 12000000, 475 }; 476 477 static struct clk cam_exclk = { 478 .name = "cam.exclk", 479 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, 480 /* Either 12M from cam.mclk or 48M from dpll4 */ 481 .parent = &cam_mclk, 482 }; 483 484 static struct clk cam_lclk = { 485 .name = "cam.lclk", 486 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, 487 }; 488 489 static struct clk i2c_fck = { 490 .name = "i2c_fck", 491 .id = 1, 492 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 493 ALWAYS_ENABLED, 494 .parent = &armxor_ck, 495 }; 496 497 static struct clk i2c_ick = { 498 .name = "i2c_ick", 499 .id = 1, 500 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, 501 .parent = &armper_ck, 502 }; 503 504 static struct clk clk32k = { 505 .name = "clk32-kHz", 506 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 507 CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 508 .parent = &xtal_osc32k, 509 }; 510 511 static struct clk ref_clk = { 512 .name = "ref_clk", 513 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 514 .rate = 12000000, /* 12 MHz or 13 MHz or 19.2 MHz */ 515 /*.parent = sys.xtalin */ 516 }; 517 518 static struct clk apll_96m = { 519 .name = "apll_96m", 520 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 521 .rate = 96000000, 522 /*.parent = ref_clk */ 523 }; 524 525 static struct clk apll_54m = { 526 .name = "apll_54m", 527 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 528 .rate = 54000000, 529 /*.parent = ref_clk */ 530 }; 531 532 static struct clk sys_clk = { 533 .name = "sys_clk", 534 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 535 .rate = 32768, 536 /*.parent = sys.xtalin */ 537 }; 538 539 static struct clk sleep_clk = { 540 .name = "sleep_clk", 541 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 542 .rate = 32768, 543 /*.parent = sys.xtalin */ 544 }; 545 546 static struct clk dpll_ck = { 547 .name = "dpll", 548 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 549 .parent = &ref_clk, 550 }; 551 552 static struct clk dpll_x2_ck = { 553 .name = "dpll_x2", 554 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 555 .parent = &ref_clk, 556 }; 557 558 static struct clk wdt1_sys_clk = { 559 .name = "wdt1_sys_clk", 560 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, 561 .rate = 32768, 562 /*.parent = sys.xtalin */ 563 }; 564 565 static struct clk func_96m_clk = { 566 .name = "func_96m_clk", 567 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 568 .divisor = 1, 569 .parent = &apll_96m, 570 }; 571 572 static struct clk func_48m_clk = { 573 .name = "func_48m_clk", 574 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 575 .divisor = 2, 576 .parent = &apll_96m, 577 }; 578 579 static struct clk func_12m_clk = { 580 .name = "func_12m_clk", 581 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 582 .divisor = 8, 583 .parent = &apll_96m, 584 }; 585 586 static struct clk func_54m_clk = { 587 .name = "func_54m_clk", 588 .flags = CLOCK_IN_OMAP242X, 589 .divisor = 1, 590 .parent = &apll_54m, 591 }; 592 593 static struct clk sys_clkout = { 594 .name = "clkout", 595 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 596 .parent = &sys_clk, 597 }; 598 599 static struct clk sys_clkout2 = { 600 .name = "clkout2", 601 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 602 .parent = &sys_clk, 603 }; 604 605 static struct clk core_clk = { 606 .name = "core_clk", 607 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 608 .parent = &dpll_x2_ck, /* Switchable between dpll_ck and clk32k */ 609 }; 610 611 static struct clk l3_clk = { 612 .name = "l3_clk", 613 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 614 .parent = &core_clk, 615 }; 616 617 static struct clk core_l4_iclk = { 618 .name = "core_l4_iclk", 619 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 620 .parent = &l3_clk, 621 }; 622 623 static struct clk wu_l4_iclk = { 624 .name = "wu_l4_iclk", 625 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 626 .parent = &l3_clk, 627 }; 628 629 static struct clk core_l3_iclk = { 630 .name = "core_l3_iclk", 631 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 632 .parent = &core_clk, 633 }; 634 635 static struct clk core_l4_usb_clk = { 636 .name = "core_l4_usb_clk", 637 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 638 .parent = &l3_clk, 639 }; 640 641 static struct clk wu_gpt1_clk = { 642 .name = "wu_gpt1_clk", 643 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 644 .parent = &sys_clk, 645 }; 646 647 static struct clk wu_32k_clk = { 648 .name = "wu_32k_clk", 649 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 650 .parent = &sys_clk, 651 }; 652 653 static struct clk uart1_fclk = { 654 .name = "uart1_fclk", 655 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 656 .parent = &func_48m_clk, 657 }; 658 659 static struct clk uart1_iclk = { 660 .name = "uart1_iclk", 661 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 662 .parent = &core_l4_iclk, 663 }; 664 665 static struct clk uart2_fclk = { 666 .name = "uart2_fclk", 667 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 668 .parent = &func_48m_clk, 669 }; 670 671 static struct clk uart2_iclk = { 672 .name = "uart2_iclk", 673 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 674 .parent = &core_l4_iclk, 675 }; 676 677 static struct clk uart3_fclk = { 678 .name = "uart3_fclk", 679 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 680 .parent = &func_48m_clk, 681 }; 682 683 static struct clk uart3_iclk = { 684 .name = "uart3_iclk", 685 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 686 .parent = &core_l4_iclk, 687 }; 688 689 static struct clk mpu_fclk = { 690 .name = "mpu_fclk", 691 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 692 .parent = &core_clk, 693 }; 694 695 static struct clk mpu_iclk = { 696 .name = "mpu_iclk", 697 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 698 .parent = &core_clk, 699 }; 700 701 static struct clk int_m_fclk = { 702 .name = "int_m_fclk", 703 .alias = "mpu_intc_fclk", 704 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 705 .parent = &core_clk, 706 }; 707 708 static struct clk int_m_iclk = { 709 .name = "int_m_iclk", 710 .alias = "mpu_intc_iclk", 711 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 712 .parent = &core_clk, 713 }; 714 715 static struct clk core_gpt2_clk = { 716 .name = "core_gpt2_clk", 717 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 718 .parent = &sys_clk, 719 }; 720 721 static struct clk core_gpt3_clk = { 722 .name = "core_gpt3_clk", 723 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 724 .parent = &sys_clk, 725 }; 726 727 static struct clk core_gpt4_clk = { 728 .name = "core_gpt4_clk", 729 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 730 .parent = &sys_clk, 731 }; 732 733 static struct clk core_gpt5_clk = { 734 .name = "core_gpt5_clk", 735 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 736 .parent = &sys_clk, 737 }; 738 739 static struct clk core_gpt6_clk = { 740 .name = "core_gpt6_clk", 741 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 742 .parent = &sys_clk, 743 }; 744 745 static struct clk core_gpt7_clk = { 746 .name = "core_gpt7_clk", 747 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 748 .parent = &sys_clk, 749 }; 750 751 static struct clk core_gpt8_clk = { 752 .name = "core_gpt8_clk", 753 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 754 .parent = &sys_clk, 755 }; 756 757 static struct clk core_gpt9_clk = { 758 .name = "core_gpt9_clk", 759 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 760 .parent = &sys_clk, 761 }; 762 763 static struct clk core_gpt10_clk = { 764 .name = "core_gpt10_clk", 765 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 766 .parent = &sys_clk, 767 }; 768 769 static struct clk core_gpt11_clk = { 770 .name = "core_gpt11_clk", 771 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 772 .parent = &sys_clk, 773 }; 774 775 static struct clk core_gpt12_clk = { 776 .name = "core_gpt12_clk", 777 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 778 .parent = &sys_clk, 779 }; 780 781 static struct clk mcbsp1_clk = { 782 .name = "mcbsp1_cg", 783 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 784 .divisor = 2, 785 .parent = &func_96m_clk, 786 }; 787 788 static struct clk mcbsp2_clk = { 789 .name = "mcbsp2_cg", 790 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 791 .divisor = 2, 792 .parent = &func_96m_clk, 793 }; 794 795 static struct clk emul_clk = { 796 .name = "emul_ck", 797 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 798 .parent = &func_54m_clk, 799 }; 800 801 static struct clk sdma_fclk = { 802 .name = "sdma_fclk", 803 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 804 .parent = &l3_clk, 805 }; 806 807 static struct clk sdma_iclk = { 808 .name = "sdma_iclk", 809 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 810 .parent = &core_l3_iclk, /* core_l4_iclk for the configuration port */ 811 }; 812 813 static struct clk i2c1_fclk = { 814 .name = "i2c1.fclk", 815 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 816 .parent = &func_12m_clk, 817 .divisor = 1, 818 }; 819 820 static struct clk i2c1_iclk = { 821 .name = "i2c1.iclk", 822 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 823 .parent = &core_l4_iclk, 824 }; 825 826 static struct clk i2c2_fclk = { 827 .name = "i2c2.fclk", 828 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 829 .parent = &func_12m_clk, 830 .divisor = 1, 831 }; 832 833 static struct clk i2c2_iclk = { 834 .name = "i2c2.iclk", 835 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 836 .parent = &core_l4_iclk, 837 }; 838 839 static struct clk gpio_dbclk[5] = { 840 { 841 .name = "gpio1_dbclk", 842 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 843 .parent = &wu_32k_clk, 844 }, { 845 .name = "gpio2_dbclk", 846 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 847 .parent = &wu_32k_clk, 848 }, { 849 .name = "gpio3_dbclk", 850 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 851 .parent = &wu_32k_clk, 852 }, { 853 .name = "gpio4_dbclk", 854 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 855 .parent = &wu_32k_clk, 856 }, { 857 .name = "gpio5_dbclk", 858 .flags = CLOCK_IN_OMAP243X, 859 .parent = &wu_32k_clk, 860 }, 861 }; 862 863 static struct clk gpio_iclk = { 864 .name = "gpio_iclk", 865 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 866 .parent = &wu_l4_iclk, 867 }; 868 869 static struct clk mmc_fck = { 870 .name = "mmc_fclk", 871 .flags = CLOCK_IN_OMAP242X, 872 .parent = &func_96m_clk, 873 }; 874 875 static struct clk mmc_ick = { 876 .name = "mmc_iclk", 877 .flags = CLOCK_IN_OMAP242X, 878 .parent = &core_l4_iclk, 879 }; 880 881 static struct clk spi_fclk[3] = { 882 { 883 .name = "spi1_fclk", 884 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 885 .parent = &func_48m_clk, 886 }, { 887 .name = "spi2_fclk", 888 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 889 .parent = &func_48m_clk, 890 }, { 891 .name = "spi3_fclk", 892 .flags = CLOCK_IN_OMAP243X, 893 .parent = &func_48m_clk, 894 }, 895 }; 896 897 static struct clk dss_clk[2] = { 898 { 899 .name = "dss_clk1", 900 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 901 .parent = &core_clk, 902 }, { 903 .name = "dss_clk2", 904 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 905 .parent = &sys_clk, 906 }, 907 }; 908 909 static struct clk dss_54m_clk = { 910 .name = "dss_54m_clk", 911 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 912 .parent = &func_54m_clk, 913 }; 914 915 static struct clk dss_l3_iclk = { 916 .name = "dss_l3_iclk", 917 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 918 .parent = &core_l3_iclk, 919 }; 920 921 static struct clk dss_l4_iclk = { 922 .name = "dss_l4_iclk", 923 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 924 .parent = &core_l4_iclk, 925 }; 926 927 static struct clk spi_iclk[3] = { 928 { 929 .name = "spi1_iclk", 930 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 931 .parent = &core_l4_iclk, 932 }, { 933 .name = "spi2_iclk", 934 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 935 .parent = &core_l4_iclk, 936 }, { 937 .name = "spi3_iclk", 938 .flags = CLOCK_IN_OMAP243X, 939 .parent = &core_l4_iclk, 940 }, 941 }; 942 943 static struct clk omapctrl_clk = { 944 .name = "omapctrl_iclk", 945 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 946 /* XXX Should be in WKUP domain */ 947 .parent = &core_l4_iclk, 948 }; 949 950 static struct clk *onchip_clks[] = { 951 /* OMAP 1 */ 952 953 /* non-ULPD clocks */ 954 &xtal_osc12m, 955 &xtal_osc32k, 956 &ck_ref, 957 &dpll1, 958 &dpll2, 959 &dpll3, 960 &dpll4, 961 &apll, 962 &ck_48m, 963 /* CK_GEN1 clocks */ 964 &clkm1, 965 &ck_dpll1out, 966 &sossi_ck, 967 &arm_ck, 968 &armper_ck, 969 &arm_gpio_ck, 970 &armxor_ck, 971 &armtim_ck, 972 &armwdt_ck, 973 &arminth_ck15xx, &arminth_ck16xx, 974 /* CK_GEN2 clocks */ 975 &clkm2, 976 &dsp_ck, 977 &dspmmu_ck, 978 &dspper_ck, 979 &dspxor_ck, 980 &dsptim_ck, 981 /* CK_GEN3 clocks */ 982 &clkm3, 983 &tc_ck, 984 &tipb_ck, 985 &l3_ocpi_ck, 986 &tc1_ck, 987 &tc2_ck, 988 &dma_ck, 989 &dma_lcdfree_ck, 990 &api_ck, 991 &lb_ck, 992 &lbfree_ck, 993 &hsab_ck, 994 &rhea1_ck, 995 &rhea2_ck, 996 &lcd_ck_16xx, 997 &lcd_ck_1510, 998 /* ULPD clocks */ 999 &uart1_1510, 1000 &uart1_16xx, 1001 &uart2_ck, 1002 &uart3_1510, 1003 &uart3_16xx, 1004 &usb_clk0, 1005 &usb_hhc_ck1510, &usb_hhc_ck16xx, 1006 &mclk_1510, &mclk_16xx, &mclk_310, 1007 &bclk_1510, &bclk_16xx, &bclk_310, 1008 &mmc1_ck, 1009 &mmc2_ck, 1010 &cam_mclk, 1011 &cam_exclk, 1012 &cam_lclk, 1013 &clk32k, 1014 &usb_w2fc_mclk, 1015 /* Virtual clocks */ 1016 &i2c_fck, 1017 &i2c_ick, 1018 1019 /* OMAP 2 */ 1020 1021 &ref_clk, 1022 &apll_96m, 1023 &apll_54m, 1024 &sys_clk, 1025 &sleep_clk, 1026 &dpll_ck, 1027 &dpll_x2_ck, 1028 &wdt1_sys_clk, 1029 &func_96m_clk, 1030 &func_48m_clk, 1031 &func_12m_clk, 1032 &func_54m_clk, 1033 &sys_clkout, 1034 &sys_clkout2, 1035 &core_clk, 1036 &l3_clk, 1037 &core_l4_iclk, 1038 &wu_l4_iclk, 1039 &core_l3_iclk, 1040 &core_l4_usb_clk, 1041 &wu_gpt1_clk, 1042 &wu_32k_clk, 1043 &uart1_fclk, 1044 &uart1_iclk, 1045 &uart2_fclk, 1046 &uart2_iclk, 1047 &uart3_fclk, 1048 &uart3_iclk, 1049 &mpu_fclk, 1050 &mpu_iclk, 1051 &int_m_fclk, 1052 &int_m_iclk, 1053 &core_gpt2_clk, 1054 &core_gpt3_clk, 1055 &core_gpt4_clk, 1056 &core_gpt5_clk, 1057 &core_gpt6_clk, 1058 &core_gpt7_clk, 1059 &core_gpt8_clk, 1060 &core_gpt9_clk, 1061 &core_gpt10_clk, 1062 &core_gpt11_clk, 1063 &core_gpt12_clk, 1064 &mcbsp1_clk, 1065 &mcbsp2_clk, 1066 &emul_clk, 1067 &sdma_fclk, 1068 &sdma_iclk, 1069 &i2c1_fclk, 1070 &i2c1_iclk, 1071 &i2c2_fclk, 1072 &i2c2_iclk, 1073 &gpio_dbclk[0], 1074 &gpio_dbclk[1], 1075 &gpio_dbclk[2], 1076 &gpio_dbclk[3], 1077 &gpio_iclk, 1078 &mmc_fck, 1079 &mmc_ick, 1080 &spi_fclk[0], 1081 &spi_iclk[0], 1082 &spi_fclk[1], 1083 &spi_iclk[1], 1084 &spi_fclk[2], 1085 &spi_iclk[2], 1086 &dss_clk[0], 1087 &dss_clk[1], 1088 &dss_54m_clk, 1089 &dss_l3_iclk, 1090 &dss_l4_iclk, 1091 &omapctrl_clk, 1092 1093 NULL 1094 }; 1095 1096 void omap_clk_adduser(struct clk *clk, qemu_irq user) 1097 { 1098 qemu_irq *i; 1099 1100 for (i = clk->users; *i; i ++); 1101 *i = user; 1102 } 1103 1104 struct clk *omap_findclk(struct omap_mpu_state_s *mpu, const char *name) 1105 { 1106 struct clk *i; 1107 1108 for (i = mpu->clks; i->name; i ++) 1109 if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name))) 1110 return i; 1111 hw_error("%s: %s not found\n", __FUNCTION__, name); 1112 } 1113 1114 void omap_clk_get(struct clk *clk) 1115 { 1116 clk->usecount ++; 1117 } 1118 1119 void omap_clk_put(struct clk *clk) 1120 { 1121 if (!(clk->usecount --)) 1122 hw_error("%s: %s is not in use\n", __FUNCTION__, clk->name); 1123 } 1124 1125 static void omap_clk_update(struct clk *clk) 1126 { 1127 int parent, running; 1128 qemu_irq *user; 1129 struct clk *i; 1130 1131 if (clk->parent) 1132 parent = clk->parent->running; 1133 else 1134 parent = 1; 1135 1136 running = parent && (clk->enabled || 1137 ((clk->flags & ALWAYS_ENABLED) && clk->usecount)); 1138 if (clk->running != running) { 1139 clk->running = running; 1140 for (user = clk->users; *user; user ++) 1141 qemu_set_irq(*user, running); 1142 for (i = clk->child1; i; i = i->sibling) 1143 omap_clk_update(i); 1144 } 1145 } 1146 1147 static void omap_clk_rate_update_full(struct clk *clk, unsigned long int rate, 1148 unsigned long int div, unsigned long int mult) 1149 { 1150 struct clk *i; 1151 qemu_irq *user; 1152 1153 clk->rate = muldiv64(rate, mult, div); 1154 if (clk->running) 1155 for (user = clk->users; *user; user ++) 1156 qemu_irq_raise(*user); 1157 for (i = clk->child1; i; i = i->sibling) 1158 omap_clk_rate_update_full(i, rate, 1159 div * i->divisor, mult * i->multiplier); 1160 } 1161 1162 static void omap_clk_rate_update(struct clk *clk) 1163 { 1164 struct clk *i; 1165 unsigned long int div, mult = div = 1; 1166 1167 for (i = clk; i->parent; i = i->parent) { 1168 div *= i->divisor; 1169 mult *= i->multiplier; 1170 } 1171 1172 omap_clk_rate_update_full(clk, i->rate, div, mult); 1173 } 1174 1175 void omap_clk_reparent(struct clk *clk, struct clk *parent) 1176 { 1177 struct clk **p; 1178 1179 if (clk->parent) { 1180 for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling); 1181 *p = clk->sibling; 1182 } 1183 1184 clk->parent = parent; 1185 if (parent) { 1186 clk->sibling = parent->child1; 1187 parent->child1 = clk; 1188 omap_clk_update(clk); 1189 omap_clk_rate_update(clk); 1190 } else 1191 clk->sibling = NULL; 1192 } 1193 1194 void omap_clk_onoff(struct clk *clk, int on) 1195 { 1196 clk->enabled = on; 1197 omap_clk_update(clk); 1198 } 1199 1200 void omap_clk_canidle(struct clk *clk, int can) 1201 { 1202 if (can) 1203 omap_clk_put(clk); 1204 else 1205 omap_clk_get(clk); 1206 } 1207 1208 void omap_clk_setrate(struct clk *clk, int divide, int multiply) 1209 { 1210 clk->divisor = divide; 1211 clk->multiplier = multiply; 1212 omap_clk_rate_update(clk); 1213 } 1214 1215 int64_t omap_clk_getrate(omap_clk clk) 1216 { 1217 return clk->rate; 1218 } 1219 1220 void omap_clk_init(struct omap_mpu_state_s *mpu) 1221 { 1222 struct clk **i, *j, *k; 1223 int count; 1224 int flag; 1225 1226 if (cpu_is_omap310(mpu)) 1227 flag = CLOCK_IN_OMAP310; 1228 else if (cpu_is_omap1510(mpu)) 1229 flag = CLOCK_IN_OMAP1510; 1230 else if (cpu_is_omap2410(mpu) || cpu_is_omap2420(mpu)) 1231 flag = CLOCK_IN_OMAP242X; 1232 else if (cpu_is_omap2430(mpu)) 1233 flag = CLOCK_IN_OMAP243X; 1234 else if (cpu_is_omap3430(mpu)) 1235 flag = CLOCK_IN_OMAP243X; 1236 else 1237 return; 1238 1239 for (i = onchip_clks, count = 0; *i; i ++) 1240 if ((*i)->flags & flag) 1241 count ++; 1242 mpu->clks = g_new0(struct clk, count + 1); 1243 for (i = onchip_clks, j = mpu->clks; *i; i ++) 1244 if ((*i)->flags & flag) { 1245 memcpy(j, *i, sizeof(struct clk)); 1246 for (k = mpu->clks; k < j; k ++) 1247 if (j->parent && !strcmp(j->parent->name, k->name)) { 1248 j->parent = k; 1249 j->sibling = k->child1; 1250 k->child1 = j; 1251 } else if (k->parent && !strcmp(k->parent->name, j->name)) { 1252 k->parent = j; 1253 k->sibling = j->child1; 1254 j->child1 = k; 1255 } 1256 j->divisor = j->divisor ?: 1; 1257 j->multiplier = j->multiplier ?: 1; 1258 j ++; 1259 } 1260 for (j = mpu->clks; count --; j ++) { 1261 omap_clk_update(j); 1262 omap_clk_rate_update(j); 1263 } 1264 } 1265