1 /* 2 * BCM2835 CPRMAN clock manager 3 * 4 * Copyright (c) 2020 Luc Michel <luc@lmichel.fr> 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9 /* 10 * This peripheral is roughly divided into 3 main parts: 11 * - the PLLs 12 * - the PLL channels 13 * - the clock muxes 14 * 15 * A main oscillator (xosc) feeds all the PLLs. Each PLLs has one or more 16 * channels. Those channel are then connected to the clock muxes. Each mux has 17 * multiples sources (usually the xosc, some of the PLL channels and some "test 18 * debug" clocks). A mux is configured to select a given source through its 19 * control register. Each mux has one output clock that also goes out of the 20 * CPRMAN. This output clock usually connects to another peripheral in the SoC 21 * (so a given mux is dedicated to a peripheral). 22 * 23 * At each level (PLL, channel and mux), the clock can be altered through 24 * dividers (and multipliers in case of the PLLs), and can be disabled (in this 25 * case, the next levels see no clock). 26 * 27 * This can be sum-up as follows (this is an example and not the actual BCM2835 28 * clock tree): 29 * 30 * /-->[PLL]-|->[PLL channel]--... [mux]--> to peripherals 31 * | |->[PLL channel] muxes takes [mux] 32 * | \->[PLL channel] inputs from [mux] 33 * | some channels [mux] 34 * [xosc]---|-->[PLL]-|->[PLL channel] and other srcs [mux] 35 * | \->[PLL channel] ...-->[mux] 36 * | [mux] 37 * \-->[PLL]--->[PLL channel] [mux] 38 * 39 * The page at https://elinux.org/The_Undocumented_Pi gives the actual clock 40 * tree configuration. 41 * 42 * The CPRMAN exposes clock outputs with the name of the clock mux suffixed 43 * with "-out" (e.g. "uart-out", "h264-out", ...). 44 */ 45 46 #include "qemu/osdep.h" 47 #include "qemu/log.h" 48 #include "migration/vmstate.h" 49 #include "hw/qdev-properties.h" 50 #include "hw/misc/bcm2835_cprman.h" 51 #include "hw/misc/bcm2835_cprman_internals.h" 52 #include "trace.h" 53 54 /* PLL */ 55 56 static bool pll_is_locked(const CprmanPllState *pll) 57 { 58 return !FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, PWRDN) 59 && !FIELD_EX32(*pll->reg_cm, CM_PLLx, ANARST); 60 } 61 62 static void pll_update(CprmanPllState *pll) 63 { 64 uint64_t freq, ndiv, fdiv, pdiv; 65 66 if (!pll_is_locked(pll)) { 67 clock_update(pll->out, 0); 68 return; 69 } 70 71 pdiv = FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, PDIV); 72 73 if (!pdiv) { 74 clock_update(pll->out, 0); 75 return; 76 } 77 78 ndiv = FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, NDIV); 79 fdiv = FIELD_EX32(*pll->reg_a2w_frac, A2W_PLLx_FRAC, FRAC); 80 81 if (pll->reg_a2w_ana[1] & pll->prediv_mask) { 82 /* The prescaler doubles the parent frequency */ 83 ndiv *= 2; 84 fdiv *= 2; 85 } 86 87 /* 88 * We have a multiplier with an integer part (ndiv) and a fractional part 89 * (fdiv), and a divider (pdiv). 90 */ 91 freq = clock_get_hz(pll->xosc_in) * 92 ((ndiv << R_A2W_PLLx_FRAC_FRAC_LENGTH) + fdiv); 93 freq /= pdiv; 94 freq >>= R_A2W_PLLx_FRAC_FRAC_LENGTH; 95 96 clock_update_hz(pll->out, freq); 97 } 98 99 static void pll_xosc_update(void *opaque) 100 { 101 pll_update(CPRMAN_PLL(opaque)); 102 } 103 104 static void pll_init(Object *obj) 105 { 106 CprmanPllState *s = CPRMAN_PLL(obj); 107 108 s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update, s); 109 s->out = qdev_init_clock_out(DEVICE(s), "out"); 110 } 111 112 static const VMStateDescription pll_vmstate = { 113 .name = TYPE_CPRMAN_PLL, 114 .version_id = 1, 115 .minimum_version_id = 1, 116 .fields = (VMStateField[]) { 117 VMSTATE_CLOCK(xosc_in, CprmanPllState), 118 VMSTATE_END_OF_LIST() 119 } 120 }; 121 122 static void pll_class_init(ObjectClass *klass, void *data) 123 { 124 DeviceClass *dc = DEVICE_CLASS(klass); 125 126 dc->vmsd = &pll_vmstate; 127 } 128 129 static const TypeInfo cprman_pll_info = { 130 .name = TYPE_CPRMAN_PLL, 131 .parent = TYPE_DEVICE, 132 .instance_size = sizeof(CprmanPllState), 133 .class_init = pll_class_init, 134 .instance_init = pll_init, 135 }; 136 137 138 /* PLL channel */ 139 140 static bool pll_channel_is_enabled(CprmanPllChannelState *channel) 141 { 142 /* 143 * XXX I'm not sure of the purpose of the LOAD field. The Linux driver does 144 * not set it when enabling the channel, but does clear it when disabling 145 * it. 146 */ 147 return !FIELD_EX32(*channel->reg_a2w_ctrl, A2W_PLLx_CHANNELy, DISABLE) 148 && !(*channel->reg_cm & channel->hold_mask); 149 } 150 151 static void pll_channel_update(CprmanPllChannelState *channel) 152 { 153 uint64_t freq, div; 154 155 if (!pll_channel_is_enabled(channel)) { 156 clock_update(channel->out, 0); 157 return; 158 } 159 160 div = FIELD_EX32(*channel->reg_a2w_ctrl, A2W_PLLx_CHANNELy, DIV); 161 162 if (!div) { 163 /* 164 * It seems that when the divider value is 0, it is considered as 165 * being maximum by the hardware (see the Linux driver). 166 */ 167 div = R_A2W_PLLx_CHANNELy_DIV_MASK; 168 } 169 170 /* Some channels have an additional fixed divider */ 171 freq = clock_get_hz(channel->pll_in) / (div * channel->fixed_divider); 172 173 clock_update_hz(channel->out, freq); 174 } 175 176 /* Update a PLL and all its channels */ 177 static void pll_update_all_channels(BCM2835CprmanState *s, 178 CprmanPllState *pll) 179 { 180 size_t i; 181 182 pll_update(pll); 183 184 for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) { 185 CprmanPllChannelState *channel = &s->channels[i]; 186 if (channel->parent == pll->id) { 187 pll_channel_update(channel); 188 } 189 } 190 } 191 192 static void pll_channel_pll_in_update(void *opaque) 193 { 194 pll_channel_update(CPRMAN_PLL_CHANNEL(opaque)); 195 } 196 197 static void pll_channel_init(Object *obj) 198 { 199 CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj); 200 201 s->pll_in = qdev_init_clock_in(DEVICE(s), "pll-in", 202 pll_channel_pll_in_update, s); 203 s->out = qdev_init_clock_out(DEVICE(s), "out"); 204 } 205 206 static const VMStateDescription pll_channel_vmstate = { 207 .name = TYPE_CPRMAN_PLL_CHANNEL, 208 .version_id = 1, 209 .minimum_version_id = 1, 210 .fields = (VMStateField[]) { 211 VMSTATE_CLOCK(pll_in, CprmanPllChannelState), 212 VMSTATE_END_OF_LIST() 213 } 214 }; 215 216 static void pll_channel_class_init(ObjectClass *klass, void *data) 217 { 218 DeviceClass *dc = DEVICE_CLASS(klass); 219 220 dc->vmsd = &pll_channel_vmstate; 221 } 222 223 static const TypeInfo cprman_pll_channel_info = { 224 .name = TYPE_CPRMAN_PLL_CHANNEL, 225 .parent = TYPE_DEVICE, 226 .instance_size = sizeof(CprmanPllChannelState), 227 .class_init = pll_channel_class_init, 228 .instance_init = pll_channel_init, 229 }; 230 231 232 /* clock mux */ 233 234 static bool clock_mux_is_enabled(CprmanClockMuxState *mux) 235 { 236 return FIELD_EX32(*mux->reg_ctl, CM_CLOCKx_CTL, ENABLE); 237 } 238 239 static void clock_mux_update(CprmanClockMuxState *mux) 240 { 241 uint64_t freq; 242 uint32_t div, src = FIELD_EX32(*mux->reg_ctl, CM_CLOCKx_CTL, SRC); 243 bool enabled = clock_mux_is_enabled(mux); 244 245 *mux->reg_ctl = FIELD_DP32(*mux->reg_ctl, CM_CLOCKx_CTL, BUSY, enabled); 246 247 if (!enabled) { 248 clock_update(mux->out, 0); 249 return; 250 } 251 252 freq = clock_get_hz(mux->srcs[src]); 253 254 if (mux->int_bits == 0 && mux->frac_bits == 0) { 255 clock_update_hz(mux->out, freq); 256 return; 257 } 258 259 /* 260 * The divider has an integer and a fractional part. The size of each part 261 * varies with the muxes (int_bits and frac_bits). Both parts are 262 * concatenated, with the integer part always starting at bit 12. 263 * 264 * 31 12 11 0 265 * ------------------------------ 266 * CM_DIV | | int | frac | | 267 * ------------------------------ 268 * <-----> <------> 269 * int_bits frac_bits 270 */ 271 div = extract32(*mux->reg_div, 272 R_CM_CLOCKx_DIV_FRAC_LENGTH - mux->frac_bits, 273 mux->int_bits + mux->frac_bits); 274 275 if (!div) { 276 clock_update(mux->out, 0); 277 return; 278 } 279 280 freq = muldiv64(freq, 1 << mux->frac_bits, div); 281 282 clock_update_hz(mux->out, freq); 283 } 284 285 static void clock_mux_src_update(void *opaque) 286 { 287 CprmanClockMuxState **backref = opaque; 288 CprmanClockMuxState *s = *backref; 289 CprmanClockMuxSource src = backref - s->backref; 290 291 if (FIELD_EX32(*s->reg_ctl, CM_CLOCKx_CTL, SRC) != src) { 292 return; 293 } 294 295 clock_mux_update(s); 296 } 297 298 static void clock_mux_init(Object *obj) 299 { 300 CprmanClockMuxState *s = CPRMAN_CLOCK_MUX(obj); 301 size_t i; 302 303 for (i = 0; i < CPRMAN_NUM_CLOCK_MUX_SRC; i++) { 304 char *name = g_strdup_printf("srcs[%zu]", i); 305 s->backref[i] = s; 306 s->srcs[i] = qdev_init_clock_in(DEVICE(s), name, 307 clock_mux_src_update, 308 &s->backref[i]); 309 g_free(name); 310 } 311 312 s->out = qdev_init_clock_out(DEVICE(s), "out"); 313 } 314 315 static const VMStateDescription clock_mux_vmstate = { 316 .name = TYPE_CPRMAN_CLOCK_MUX, 317 .version_id = 1, 318 .minimum_version_id = 1, 319 .fields = (VMStateField[]) { 320 VMSTATE_ARRAY_CLOCK(srcs, CprmanClockMuxState, 321 CPRMAN_NUM_CLOCK_MUX_SRC), 322 VMSTATE_END_OF_LIST() 323 } 324 }; 325 326 static void clock_mux_class_init(ObjectClass *klass, void *data) 327 { 328 DeviceClass *dc = DEVICE_CLASS(klass); 329 330 dc->vmsd = &clock_mux_vmstate; 331 } 332 333 static const TypeInfo cprman_clock_mux_info = { 334 .name = TYPE_CPRMAN_CLOCK_MUX, 335 .parent = TYPE_DEVICE, 336 .instance_size = sizeof(CprmanClockMuxState), 337 .class_init = clock_mux_class_init, 338 .instance_init = clock_mux_init, 339 }; 340 341 342 /* DSI0HSCK mux */ 343 344 static void dsi0hsck_mux_update(CprmanDsi0HsckMuxState *s) 345 { 346 bool src_is_plld = FIELD_EX32(*s->reg_cm, CM_DSI0HSCK, SELPLLD); 347 Clock *src = src_is_plld ? s->plld_in : s->plla_in; 348 349 clock_update(s->out, clock_get(src)); 350 } 351 352 static void dsi0hsck_mux_in_update(void *opaque) 353 { 354 dsi0hsck_mux_update(CPRMAN_DSI0HSCK_MUX(opaque)); 355 } 356 357 static void dsi0hsck_mux_init(Object *obj) 358 { 359 CprmanDsi0HsckMuxState *s = CPRMAN_DSI0HSCK_MUX(obj); 360 DeviceState *dev = DEVICE(obj); 361 362 s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update, s); 363 s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update, s); 364 s->out = qdev_init_clock_out(DEVICE(s), "out"); 365 } 366 367 static const VMStateDescription dsi0hsck_mux_vmstate = { 368 .name = TYPE_CPRMAN_DSI0HSCK_MUX, 369 .version_id = 1, 370 .minimum_version_id = 1, 371 .fields = (VMStateField[]) { 372 VMSTATE_CLOCK(plla_in, CprmanDsi0HsckMuxState), 373 VMSTATE_CLOCK(plld_in, CprmanDsi0HsckMuxState), 374 VMSTATE_END_OF_LIST() 375 } 376 }; 377 378 static void dsi0hsck_mux_class_init(ObjectClass *klass, void *data) 379 { 380 DeviceClass *dc = DEVICE_CLASS(klass); 381 382 dc->vmsd = &dsi0hsck_mux_vmstate; 383 } 384 385 static const TypeInfo cprman_dsi0hsck_mux_info = { 386 .name = TYPE_CPRMAN_DSI0HSCK_MUX, 387 .parent = TYPE_DEVICE, 388 .instance_size = sizeof(CprmanDsi0HsckMuxState), 389 .class_init = dsi0hsck_mux_class_init, 390 .instance_init = dsi0hsck_mux_init, 391 }; 392 393 394 /* CPRMAN "top level" model */ 395 396 static uint32_t get_cm_lock(const BCM2835CprmanState *s) 397 { 398 static const int CM_LOCK_MAPPING[CPRMAN_NUM_PLL] = { 399 [CPRMAN_PLLA] = R_CM_LOCK_FLOCKA_SHIFT, 400 [CPRMAN_PLLC] = R_CM_LOCK_FLOCKC_SHIFT, 401 [CPRMAN_PLLD] = R_CM_LOCK_FLOCKD_SHIFT, 402 [CPRMAN_PLLH] = R_CM_LOCK_FLOCKH_SHIFT, 403 [CPRMAN_PLLB] = R_CM_LOCK_FLOCKB_SHIFT, 404 }; 405 406 uint32_t r = 0; 407 size_t i; 408 409 for (i = 0; i < CPRMAN_NUM_PLL; i++) { 410 r |= pll_is_locked(&s->plls[i]) << CM_LOCK_MAPPING[i]; 411 } 412 413 return r; 414 } 415 416 static uint64_t cprman_read(void *opaque, hwaddr offset, 417 unsigned size) 418 { 419 BCM2835CprmanState *s = CPRMAN(opaque); 420 uint64_t r = 0; 421 size_t idx = offset / sizeof(uint32_t); 422 423 switch (idx) { 424 case R_CM_LOCK: 425 r = get_cm_lock(s); 426 break; 427 428 default: 429 r = s->regs[idx]; 430 } 431 432 trace_bcm2835_cprman_read(offset, r); 433 return r; 434 } 435 436 static inline void update_pll_and_channels_from_cm(BCM2835CprmanState *s, 437 size_t idx) 438 { 439 size_t i; 440 441 for (i = 0; i < CPRMAN_NUM_PLL; i++) { 442 if (PLL_INIT_INFO[i].cm_offset == idx) { 443 pll_update_all_channels(s, &s->plls[i]); 444 return; 445 } 446 } 447 } 448 449 static inline void update_channel_from_a2w(BCM2835CprmanState *s, size_t idx) 450 { 451 size_t i; 452 453 for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) { 454 if (PLL_CHANNEL_INIT_INFO[i].a2w_ctrl_offset == idx) { 455 pll_channel_update(&s->channels[i]); 456 return; 457 } 458 } 459 } 460 461 static inline void update_mux_from_cm(BCM2835CprmanState *s, size_t idx) 462 { 463 size_t i; 464 465 for (i = 0; i < CPRMAN_NUM_CLOCK_MUX; i++) { 466 if ((CLOCK_MUX_INIT_INFO[i].cm_offset == idx) || 467 (CLOCK_MUX_INIT_INFO[i].cm_offset + 4 == idx)) { 468 /* matches CM_CTL or CM_DIV mux register */ 469 clock_mux_update(&s->clock_muxes[i]); 470 return; 471 } 472 } 473 } 474 475 #define CASE_PLL_A2W_REGS(pll_) \ 476 case R_A2W_ ## pll_ ## _CTRL: \ 477 case R_A2W_ ## pll_ ## _ANA0: \ 478 case R_A2W_ ## pll_ ## _ANA1: \ 479 case R_A2W_ ## pll_ ## _ANA2: \ 480 case R_A2W_ ## pll_ ## _ANA3: \ 481 case R_A2W_ ## pll_ ## _FRAC 482 483 static void cprman_write(void *opaque, hwaddr offset, 484 uint64_t value, unsigned size) 485 { 486 BCM2835CprmanState *s = CPRMAN(opaque); 487 size_t idx = offset / sizeof(uint32_t); 488 489 if (FIELD_EX32(value, CPRMAN, PASSWORD) != CPRMAN_PASSWORD) { 490 trace_bcm2835_cprman_write_invalid_magic(offset, value); 491 return; 492 } 493 494 value &= ~R_CPRMAN_PASSWORD_MASK; 495 496 trace_bcm2835_cprman_write(offset, value); 497 s->regs[idx] = value; 498 499 switch (idx) { 500 case R_CM_PLLA ... R_CM_PLLH: 501 case R_CM_PLLB: 502 /* 503 * A given CM_PLLx register is shared by both the PLL and the channels 504 * of this PLL. 505 */ 506 update_pll_and_channels_from_cm(s, idx); 507 break; 508 509 CASE_PLL_A2W_REGS(PLLA) : 510 pll_update(&s->plls[CPRMAN_PLLA]); 511 break; 512 513 CASE_PLL_A2W_REGS(PLLC) : 514 pll_update(&s->plls[CPRMAN_PLLC]); 515 break; 516 517 CASE_PLL_A2W_REGS(PLLD) : 518 pll_update(&s->plls[CPRMAN_PLLD]); 519 break; 520 521 CASE_PLL_A2W_REGS(PLLH) : 522 pll_update(&s->plls[CPRMAN_PLLH]); 523 break; 524 525 CASE_PLL_A2W_REGS(PLLB) : 526 pll_update(&s->plls[CPRMAN_PLLB]); 527 break; 528 529 case R_A2W_PLLA_DSI0: 530 case R_A2W_PLLA_CORE: 531 case R_A2W_PLLA_PER: 532 case R_A2W_PLLA_CCP2: 533 case R_A2W_PLLC_CORE2: 534 case R_A2W_PLLC_CORE1: 535 case R_A2W_PLLC_PER: 536 case R_A2W_PLLC_CORE0: 537 case R_A2W_PLLD_DSI0: 538 case R_A2W_PLLD_CORE: 539 case R_A2W_PLLD_PER: 540 case R_A2W_PLLD_DSI1: 541 case R_A2W_PLLH_AUX: 542 case R_A2W_PLLH_RCAL: 543 case R_A2W_PLLH_PIX: 544 case R_A2W_PLLB_ARM: 545 update_channel_from_a2w(s, idx); 546 break; 547 548 case R_CM_GNRICCTL ... R_CM_SMIDIV: 549 case R_CM_TCNTCNT ... R_CM_VECDIV: 550 case R_CM_PULSECTL ... R_CM_PULSEDIV: 551 case R_CM_SDCCTL ... R_CM_ARMCTL: 552 case R_CM_AVEOCTL ... R_CM_EMMCDIV: 553 case R_CM_EMMC2CTL ... R_CM_EMMC2DIV: 554 update_mux_from_cm(s, idx); 555 break; 556 557 case R_CM_DSI0HSCK: 558 dsi0hsck_mux_update(&s->dsi0hsck_mux); 559 break; 560 } 561 } 562 563 #undef CASE_PLL_A2W_REGS 564 565 static const MemoryRegionOps cprman_ops = { 566 .read = cprman_read, 567 .write = cprman_write, 568 .endianness = DEVICE_LITTLE_ENDIAN, 569 .valid = { 570 /* 571 * Although this hasn't been checked against real hardware, nor the 572 * information can be found in a datasheet, it seems reasonable because 573 * of the "PASSWORD" magic value found in every registers. 574 */ 575 .min_access_size = 4, 576 .max_access_size = 4, 577 .unaligned = false, 578 }, 579 .impl = { 580 .max_access_size = 4, 581 }, 582 }; 583 584 static void cprman_reset(DeviceState *dev) 585 { 586 BCM2835CprmanState *s = CPRMAN(dev); 587 size_t i; 588 589 memset(s->regs, 0, sizeof(s->regs)); 590 591 for (i = 0; i < CPRMAN_NUM_PLL; i++) { 592 device_cold_reset(DEVICE(&s->plls[i])); 593 } 594 595 for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) { 596 device_cold_reset(DEVICE(&s->channels[i])); 597 } 598 599 device_cold_reset(DEVICE(&s->dsi0hsck_mux)); 600 601 for (i = 0; i < CPRMAN_NUM_CLOCK_MUX; i++) { 602 device_cold_reset(DEVICE(&s->clock_muxes[i])); 603 } 604 605 clock_update_hz(s->xosc, s->xosc_freq); 606 } 607 608 static void cprman_init(Object *obj) 609 { 610 BCM2835CprmanState *s = CPRMAN(obj); 611 size_t i; 612 613 for (i = 0; i < CPRMAN_NUM_PLL; i++) { 614 object_initialize_child(obj, PLL_INIT_INFO[i].name, 615 &s->plls[i], TYPE_CPRMAN_PLL); 616 set_pll_init_info(s, &s->plls[i], i); 617 } 618 619 for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) { 620 object_initialize_child(obj, PLL_CHANNEL_INIT_INFO[i].name, 621 &s->channels[i], 622 TYPE_CPRMAN_PLL_CHANNEL); 623 set_pll_channel_init_info(s, &s->channels[i], i); 624 } 625 626 object_initialize_child(obj, "dsi0hsck-mux", 627 &s->dsi0hsck_mux, TYPE_CPRMAN_DSI0HSCK_MUX); 628 s->dsi0hsck_mux.reg_cm = &s->regs[R_CM_DSI0HSCK]; 629 630 for (i = 0; i < CPRMAN_NUM_CLOCK_MUX; i++) { 631 char *alias; 632 633 object_initialize_child(obj, CLOCK_MUX_INIT_INFO[i].name, 634 &s->clock_muxes[i], 635 TYPE_CPRMAN_CLOCK_MUX); 636 set_clock_mux_init_info(s, &s->clock_muxes[i], i); 637 638 /* Expose muxes output as CPRMAN outputs */ 639 alias = g_strdup_printf("%s-out", CLOCK_MUX_INIT_INFO[i].name); 640 qdev_alias_clock(DEVICE(&s->clock_muxes[i]), "out", DEVICE(obj), alias); 641 g_free(alias); 642 } 643 644 s->xosc = clock_new(obj, "xosc"); 645 s->gnd = clock_new(obj, "gnd"); 646 647 clock_set(s->gnd, 0); 648 649 memory_region_init_io(&s->iomem, obj, &cprman_ops, 650 s, "bcm2835-cprman", 0x2000); 651 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem); 652 } 653 654 static void connect_mux_sources(BCM2835CprmanState *s, 655 CprmanClockMuxState *mux, 656 const CprmanPllChannel *clk_mapping) 657 { 658 size_t i; 659 Clock *td0 = s->clock_muxes[CPRMAN_CLOCK_TD0].out; 660 Clock *td1 = s->clock_muxes[CPRMAN_CLOCK_TD1].out; 661 662 /* For sources from 0 to 3. Source 4 to 9 are mux specific */ 663 Clock * const CLK_SRC_MAPPING[] = { 664 [CPRMAN_CLOCK_SRC_GND] = s->gnd, 665 [CPRMAN_CLOCK_SRC_XOSC] = s->xosc, 666 [CPRMAN_CLOCK_SRC_TD0] = td0, 667 [CPRMAN_CLOCK_SRC_TD1] = td1, 668 }; 669 670 for (i = 0; i < CPRMAN_NUM_CLOCK_MUX_SRC; i++) { 671 CprmanPllChannel mapping = clk_mapping[i]; 672 Clock *src; 673 674 if (mapping == CPRMAN_CLOCK_SRC_FORCE_GROUND) { 675 src = s->gnd; 676 } else if (mapping == CPRMAN_CLOCK_SRC_DSI0HSCK) { 677 src = s->dsi0hsck_mux.out; 678 } else if (i < CPRMAN_CLOCK_SRC_PLLA) { 679 src = CLK_SRC_MAPPING[i]; 680 } else { 681 src = s->channels[mapping].out; 682 } 683 684 clock_set_source(mux->srcs[i], src); 685 } 686 } 687 688 static void cprman_realize(DeviceState *dev, Error **errp) 689 { 690 BCM2835CprmanState *s = CPRMAN(dev); 691 size_t i; 692 693 for (i = 0; i < CPRMAN_NUM_PLL; i++) { 694 CprmanPllState *pll = &s->plls[i]; 695 696 clock_set_source(pll->xosc_in, s->xosc); 697 698 if (!qdev_realize(DEVICE(pll), NULL, errp)) { 699 return; 700 } 701 } 702 703 for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) { 704 CprmanPllChannelState *channel = &s->channels[i]; 705 CprmanPll parent = PLL_CHANNEL_INIT_INFO[i].parent; 706 Clock *parent_clk = s->plls[parent].out; 707 708 clock_set_source(channel->pll_in, parent_clk); 709 710 if (!qdev_realize(DEVICE(channel), NULL, errp)) { 711 return; 712 } 713 } 714 715 clock_set_source(s->dsi0hsck_mux.plla_in, 716 s->channels[CPRMAN_PLLA_CHANNEL_DSI0].out); 717 clock_set_source(s->dsi0hsck_mux.plld_in, 718 s->channels[CPRMAN_PLLD_CHANNEL_DSI0].out); 719 720 if (!qdev_realize(DEVICE(&s->dsi0hsck_mux), NULL, errp)) { 721 return; 722 } 723 724 for (i = 0; i < CPRMAN_NUM_CLOCK_MUX; i++) { 725 CprmanClockMuxState *clock_mux = &s->clock_muxes[i]; 726 727 connect_mux_sources(s, clock_mux, CLOCK_MUX_INIT_INFO[i].src_mapping); 728 729 if (!qdev_realize(DEVICE(clock_mux), NULL, errp)) { 730 return; 731 } 732 } 733 } 734 735 static const VMStateDescription cprman_vmstate = { 736 .name = TYPE_BCM2835_CPRMAN, 737 .version_id = 1, 738 .minimum_version_id = 1, 739 .fields = (VMStateField[]) { 740 VMSTATE_UINT32_ARRAY(regs, BCM2835CprmanState, CPRMAN_NUM_REGS), 741 VMSTATE_END_OF_LIST() 742 } 743 }; 744 745 static Property cprman_properties[] = { 746 DEFINE_PROP_UINT32("xosc-freq-hz", BCM2835CprmanState, xosc_freq, 19200000), 747 DEFINE_PROP_END_OF_LIST() 748 }; 749 750 static void cprman_class_init(ObjectClass *klass, void *data) 751 { 752 DeviceClass *dc = DEVICE_CLASS(klass); 753 754 dc->realize = cprman_realize; 755 dc->reset = cprman_reset; 756 dc->vmsd = &cprman_vmstate; 757 device_class_set_props(dc, cprman_properties); 758 } 759 760 static const TypeInfo cprman_info = { 761 .name = TYPE_BCM2835_CPRMAN, 762 .parent = TYPE_SYS_BUS_DEVICE, 763 .instance_size = sizeof(BCM2835CprmanState), 764 .class_init = cprman_class_init, 765 .instance_init = cprman_init, 766 }; 767 768 static void cprman_register_types(void) 769 { 770 type_register_static(&cprman_info); 771 type_register_static(&cprman_pll_info); 772 type_register_static(&cprman_pll_channel_info); 773 type_register_static(&cprman_clock_mux_info); 774 type_register_static(&cprman_dsi0hsck_mux_info); 775 } 776 777 type_init(cprman_register_types); 778