xref: /qemu/hw/misc/bcm2835_cprman.c (revision 502960ca04c15cc7e24f3e8f9e0d8070bc3d77d7)
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