xref: /qemu/hw/misc/bcm2835_cprman.c (revision 09d56bbc9bc2f40865764b06b9830a9504bd3f9a)
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 
43 #include "qemu/osdep.h"
44 #include "qemu/log.h"
45 #include "migration/vmstate.h"
46 #include "hw/qdev-properties.h"
47 #include "hw/misc/bcm2835_cprman.h"
48 #include "hw/misc/bcm2835_cprman_internals.h"
49 #include "trace.h"
50 
51 /* PLL */
52 
53 static bool pll_is_locked(const CprmanPllState *pll)
54 {
55     return !FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, PWRDN)
56         && !FIELD_EX32(*pll->reg_cm, CM_PLLx, ANARST);
57 }
58 
59 static void pll_update(CprmanPllState *pll)
60 {
61     uint64_t freq, ndiv, fdiv, pdiv;
62 
63     if (!pll_is_locked(pll)) {
64         clock_update(pll->out, 0);
65         return;
66     }
67 
68     pdiv = FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, PDIV);
69 
70     if (!pdiv) {
71         clock_update(pll->out, 0);
72         return;
73     }
74 
75     ndiv = FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, NDIV);
76     fdiv = FIELD_EX32(*pll->reg_a2w_frac, A2W_PLLx_FRAC, FRAC);
77 
78     if (pll->reg_a2w_ana[1] & pll->prediv_mask) {
79         /* The prescaler doubles the parent frequency */
80         ndiv *= 2;
81         fdiv *= 2;
82     }
83 
84     /*
85      * We have a multiplier with an integer part (ndiv) and a fractional part
86      * (fdiv), and a divider (pdiv).
87      */
88     freq = clock_get_hz(pll->xosc_in) *
89         ((ndiv << R_A2W_PLLx_FRAC_FRAC_LENGTH) + fdiv);
90     freq /= pdiv;
91     freq >>= R_A2W_PLLx_FRAC_FRAC_LENGTH;
92 
93     clock_update_hz(pll->out, freq);
94 }
95 
96 static void pll_xosc_update(void *opaque)
97 {
98     pll_update(CPRMAN_PLL(opaque));
99 }
100 
101 static void pll_init(Object *obj)
102 {
103     CprmanPllState *s = CPRMAN_PLL(obj);
104 
105     s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update, s);
106     s->out = qdev_init_clock_out(DEVICE(s), "out");
107 }
108 
109 static const VMStateDescription pll_vmstate = {
110     .name = TYPE_CPRMAN_PLL,
111     .version_id = 1,
112     .minimum_version_id = 1,
113     .fields = (VMStateField[]) {
114         VMSTATE_CLOCK(xosc_in, CprmanPllState),
115         VMSTATE_END_OF_LIST()
116     }
117 };
118 
119 static void pll_class_init(ObjectClass *klass, void *data)
120 {
121     DeviceClass *dc = DEVICE_CLASS(klass);
122 
123     dc->vmsd = &pll_vmstate;
124 }
125 
126 static const TypeInfo cprman_pll_info = {
127     .name = TYPE_CPRMAN_PLL,
128     .parent = TYPE_DEVICE,
129     .instance_size = sizeof(CprmanPllState),
130     .class_init = pll_class_init,
131     .instance_init = pll_init,
132 };
133 
134 
135 /* PLL channel */
136 
137 static void pll_channel_update(CprmanPllChannelState *channel)
138 {
139     clock_update(channel->out, 0);
140 }
141 
142 /* Update a PLL and all its channels */
143 static void pll_update_all_channels(BCM2835CprmanState *s,
144                                     CprmanPllState *pll)
145 {
146     size_t i;
147 
148     pll_update(pll);
149 
150     for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
151         CprmanPllChannelState *channel = &s->channels[i];
152         if (channel->parent == pll->id) {
153             pll_channel_update(channel);
154         }
155     }
156 }
157 
158 static void pll_channel_pll_in_update(void *opaque)
159 {
160     pll_channel_update(CPRMAN_PLL_CHANNEL(opaque));
161 }
162 
163 static void pll_channel_init(Object *obj)
164 {
165     CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj);
166 
167     s->pll_in = qdev_init_clock_in(DEVICE(s), "pll-in",
168                                    pll_channel_pll_in_update, s);
169     s->out = qdev_init_clock_out(DEVICE(s), "out");
170 }
171 
172 static const VMStateDescription pll_channel_vmstate = {
173     .name = TYPE_CPRMAN_PLL_CHANNEL,
174     .version_id = 1,
175     .minimum_version_id = 1,
176     .fields = (VMStateField[]) {
177         VMSTATE_CLOCK(pll_in, CprmanPllChannelState),
178         VMSTATE_END_OF_LIST()
179     }
180 };
181 
182 static void pll_channel_class_init(ObjectClass *klass, void *data)
183 {
184     DeviceClass *dc = DEVICE_CLASS(klass);
185 
186     dc->vmsd = &pll_channel_vmstate;
187 }
188 
189 static const TypeInfo cprman_pll_channel_info = {
190     .name = TYPE_CPRMAN_PLL_CHANNEL,
191     .parent = TYPE_DEVICE,
192     .instance_size = sizeof(CprmanPllChannelState),
193     .class_init = pll_channel_class_init,
194     .instance_init = pll_channel_init,
195 };
196 
197 
198 /* CPRMAN "top level" model */
199 
200 static uint32_t get_cm_lock(const BCM2835CprmanState *s)
201 {
202     static const int CM_LOCK_MAPPING[CPRMAN_NUM_PLL] = {
203         [CPRMAN_PLLA] = R_CM_LOCK_FLOCKA_SHIFT,
204         [CPRMAN_PLLC] = R_CM_LOCK_FLOCKC_SHIFT,
205         [CPRMAN_PLLD] = R_CM_LOCK_FLOCKD_SHIFT,
206         [CPRMAN_PLLH] = R_CM_LOCK_FLOCKH_SHIFT,
207         [CPRMAN_PLLB] = R_CM_LOCK_FLOCKB_SHIFT,
208     };
209 
210     uint32_t r = 0;
211     size_t i;
212 
213     for (i = 0; i < CPRMAN_NUM_PLL; i++) {
214         r |= pll_is_locked(&s->plls[i]) << CM_LOCK_MAPPING[i];
215     }
216 
217     return r;
218 }
219 
220 static uint64_t cprman_read(void *opaque, hwaddr offset,
221                             unsigned size)
222 {
223     BCM2835CprmanState *s = CPRMAN(opaque);
224     uint64_t r = 0;
225     size_t idx = offset / sizeof(uint32_t);
226 
227     switch (idx) {
228     case R_CM_LOCK:
229         r = get_cm_lock(s);
230         break;
231 
232     default:
233         r = s->regs[idx];
234     }
235 
236     trace_bcm2835_cprman_read(offset, r);
237     return r;
238 }
239 
240 static inline void update_pll_and_channels_from_cm(BCM2835CprmanState *s,
241                                                    size_t idx)
242 {
243     size_t i;
244 
245     for (i = 0; i < CPRMAN_NUM_PLL; i++) {
246         if (PLL_INIT_INFO[i].cm_offset == idx) {
247             pll_update_all_channels(s, &s->plls[i]);
248             return;
249         }
250     }
251 }
252 
253 static inline void update_channel_from_a2w(BCM2835CprmanState *s, size_t idx)
254 {
255     size_t i;
256 
257     for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
258         if (PLL_CHANNEL_INIT_INFO[i].a2w_ctrl_offset == idx) {
259             pll_channel_update(&s->channels[i]);
260             return;
261         }
262     }
263 }
264 
265 #define CASE_PLL_A2W_REGS(pll_) \
266     case R_A2W_ ## pll_ ## _CTRL: \
267     case R_A2W_ ## pll_ ## _ANA0: \
268     case R_A2W_ ## pll_ ## _ANA1: \
269     case R_A2W_ ## pll_ ## _ANA2: \
270     case R_A2W_ ## pll_ ## _ANA3: \
271     case R_A2W_ ## pll_ ## _FRAC
272 
273 static void cprman_write(void *opaque, hwaddr offset,
274                          uint64_t value, unsigned size)
275 {
276     BCM2835CprmanState *s = CPRMAN(opaque);
277     size_t idx = offset / sizeof(uint32_t);
278 
279     if (FIELD_EX32(value, CPRMAN, PASSWORD) != CPRMAN_PASSWORD) {
280         trace_bcm2835_cprman_write_invalid_magic(offset, value);
281         return;
282     }
283 
284     value &= ~R_CPRMAN_PASSWORD_MASK;
285 
286     trace_bcm2835_cprman_write(offset, value);
287     s->regs[idx] = value;
288 
289     switch (idx) {
290     case R_CM_PLLA ... R_CM_PLLH:
291     case R_CM_PLLB:
292         /*
293          * A given CM_PLLx register is shared by both the PLL and the channels
294          * of this PLL.
295          */
296         update_pll_and_channels_from_cm(s, idx);
297         break;
298 
299     CASE_PLL_A2W_REGS(PLLA) :
300         pll_update(&s->plls[CPRMAN_PLLA]);
301         break;
302 
303     CASE_PLL_A2W_REGS(PLLC) :
304         pll_update(&s->plls[CPRMAN_PLLC]);
305         break;
306 
307     CASE_PLL_A2W_REGS(PLLD) :
308         pll_update(&s->plls[CPRMAN_PLLD]);
309         break;
310 
311     CASE_PLL_A2W_REGS(PLLH) :
312         pll_update(&s->plls[CPRMAN_PLLH]);
313         break;
314 
315     CASE_PLL_A2W_REGS(PLLB) :
316         pll_update(&s->plls[CPRMAN_PLLB]);
317         break;
318 
319     case R_A2W_PLLA_DSI0:
320     case R_A2W_PLLA_CORE:
321     case R_A2W_PLLA_PER:
322     case R_A2W_PLLA_CCP2:
323     case R_A2W_PLLC_CORE2:
324     case R_A2W_PLLC_CORE1:
325     case R_A2W_PLLC_PER:
326     case R_A2W_PLLC_CORE0:
327     case R_A2W_PLLD_DSI0:
328     case R_A2W_PLLD_CORE:
329     case R_A2W_PLLD_PER:
330     case R_A2W_PLLD_DSI1:
331     case R_A2W_PLLH_AUX:
332     case R_A2W_PLLH_RCAL:
333     case R_A2W_PLLH_PIX:
334     case R_A2W_PLLB_ARM:
335         update_channel_from_a2w(s, idx);
336         break;
337     }
338 }
339 
340 #undef CASE_PLL_A2W_REGS
341 
342 static const MemoryRegionOps cprman_ops = {
343     .read = cprman_read,
344     .write = cprman_write,
345     .endianness = DEVICE_LITTLE_ENDIAN,
346     .valid = {
347         /*
348          * Although this hasn't been checked against real hardware, nor the
349          * information can be found in a datasheet, it seems reasonable because
350          * of the "PASSWORD" magic value found in every registers.
351          */
352         .min_access_size        = 4,
353         .max_access_size        = 4,
354         .unaligned              = false,
355     },
356     .impl = {
357         .max_access_size = 4,
358     },
359 };
360 
361 static void cprman_reset(DeviceState *dev)
362 {
363     BCM2835CprmanState *s = CPRMAN(dev);
364     size_t i;
365 
366     memset(s->regs, 0, sizeof(s->regs));
367 
368     for (i = 0; i < CPRMAN_NUM_PLL; i++) {
369         device_cold_reset(DEVICE(&s->plls[i]));
370     }
371 
372     for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
373         device_cold_reset(DEVICE(&s->channels[i]));
374     }
375 
376     clock_update_hz(s->xosc, s->xosc_freq);
377 }
378 
379 static void cprman_init(Object *obj)
380 {
381     BCM2835CprmanState *s = CPRMAN(obj);
382     size_t i;
383 
384     for (i = 0; i < CPRMAN_NUM_PLL; i++) {
385         object_initialize_child(obj, PLL_INIT_INFO[i].name,
386                                 &s->plls[i], TYPE_CPRMAN_PLL);
387         set_pll_init_info(s, &s->plls[i], i);
388     }
389 
390     for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
391         object_initialize_child(obj, PLL_CHANNEL_INIT_INFO[i].name,
392                                 &s->channels[i],
393                                 TYPE_CPRMAN_PLL_CHANNEL);
394         set_pll_channel_init_info(s, &s->channels[i], i);
395     }
396 
397     s->xosc = clock_new(obj, "xosc");
398 
399     memory_region_init_io(&s->iomem, obj, &cprman_ops,
400                           s, "bcm2835-cprman", 0x2000);
401     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
402 }
403 
404 static void cprman_realize(DeviceState *dev, Error **errp)
405 {
406     BCM2835CprmanState *s = CPRMAN(dev);
407     size_t i;
408 
409     for (i = 0; i < CPRMAN_NUM_PLL; i++) {
410         CprmanPllState *pll = &s->plls[i];
411 
412         clock_set_source(pll->xosc_in, s->xosc);
413 
414         if (!qdev_realize(DEVICE(pll), NULL, errp)) {
415             return;
416         }
417     }
418 
419     for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
420         CprmanPllChannelState *channel = &s->channels[i];
421         CprmanPll parent = PLL_CHANNEL_INIT_INFO[i].parent;
422         Clock *parent_clk = s->plls[parent].out;
423 
424         clock_set_source(channel->pll_in, parent_clk);
425 
426         if (!qdev_realize(DEVICE(channel), NULL, errp)) {
427             return;
428         }
429     }
430 }
431 
432 static const VMStateDescription cprman_vmstate = {
433     .name = TYPE_BCM2835_CPRMAN,
434     .version_id = 1,
435     .minimum_version_id = 1,
436     .fields = (VMStateField[]) {
437         VMSTATE_UINT32_ARRAY(regs, BCM2835CprmanState, CPRMAN_NUM_REGS),
438         VMSTATE_END_OF_LIST()
439     }
440 };
441 
442 static Property cprman_properties[] = {
443     DEFINE_PROP_UINT32("xosc-freq-hz", BCM2835CprmanState, xosc_freq, 19200000),
444     DEFINE_PROP_END_OF_LIST()
445 };
446 
447 static void cprman_class_init(ObjectClass *klass, void *data)
448 {
449     DeviceClass *dc = DEVICE_CLASS(klass);
450 
451     dc->realize = cprman_realize;
452     dc->reset = cprman_reset;
453     dc->vmsd = &cprman_vmstate;
454     device_class_set_props(dc, cprman_properties);
455 }
456 
457 static const TypeInfo cprman_info = {
458     .name = TYPE_BCM2835_CPRMAN,
459     .parent = TYPE_SYS_BUS_DEVICE,
460     .instance_size = sizeof(BCM2835CprmanState),
461     .class_init = cprman_class_init,
462     .instance_init = cprman_init,
463 };
464 
465 static void cprman_register_types(void)
466 {
467     type_register_static(&cprman_info);
468     type_register_static(&cprman_pll_info);
469     type_register_static(&cprman_pll_channel_info);
470 }
471 
472 type_init(cprman_register_types);
473