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