xref: /qemu/include/hw/misc/bcm2835_cprman_internals.h (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 #ifndef HW_MISC_CPRMAN_INTERNALS_H
10 #define HW_MISC_CPRMAN_INTERNALS_H
11 
12 #include "hw/registerfields.h"
13 #include "hw/misc/bcm2835_cprman.h"
14 
15 #define TYPE_CPRMAN_PLL "bcm2835-cprman-pll"
16 #define TYPE_CPRMAN_PLL_CHANNEL "bcm2835-cprman-pll-channel"
17 #define TYPE_CPRMAN_CLOCK_MUX "bcm2835-cprman-clock-mux"
18 #define TYPE_CPRMAN_DSI0HSCK_MUX "bcm2835-cprman-dsi0hsck-mux"
19 
20 DECLARE_INSTANCE_CHECKER(CprmanPllState, CPRMAN_PLL,
21                          TYPE_CPRMAN_PLL)
22 DECLARE_INSTANCE_CHECKER(CprmanPllChannelState, CPRMAN_PLL_CHANNEL,
23                          TYPE_CPRMAN_PLL_CHANNEL)
24 DECLARE_INSTANCE_CHECKER(CprmanClockMuxState, CPRMAN_CLOCK_MUX,
25                          TYPE_CPRMAN_CLOCK_MUX)
26 DECLARE_INSTANCE_CHECKER(CprmanDsi0HsckMuxState, CPRMAN_DSI0HSCK_MUX,
27                          TYPE_CPRMAN_DSI0HSCK_MUX)
28 
29 /* Register map */
30 
31 /* PLLs */
32 REG32(CM_PLLA, 0x104)
33     FIELD(CM_PLLA, LOADDSI0, 0, 1)
34     FIELD(CM_PLLA, HOLDDSI0, 1, 1)
35     FIELD(CM_PLLA, LOADCCP2, 2, 1)
36     FIELD(CM_PLLA, HOLDCCP2, 3, 1)
37     FIELD(CM_PLLA, LOADCORE, 4, 1)
38     FIELD(CM_PLLA, HOLDCORE, 5, 1)
39     FIELD(CM_PLLA, LOADPER, 6, 1)
40     FIELD(CM_PLLA, HOLDPER, 7, 1)
41     FIELD(CM_PLLx, ANARST, 8, 1)
42 REG32(CM_PLLC, 0x108)
43     FIELD(CM_PLLC, LOADCORE0, 0, 1)
44     FIELD(CM_PLLC, HOLDCORE0, 1, 1)
45     FIELD(CM_PLLC, LOADCORE1, 2, 1)
46     FIELD(CM_PLLC, HOLDCORE1, 3, 1)
47     FIELD(CM_PLLC, LOADCORE2, 4, 1)
48     FIELD(CM_PLLC, HOLDCORE2, 5, 1)
49     FIELD(CM_PLLC, LOADPER, 6, 1)
50     FIELD(CM_PLLC, HOLDPER, 7, 1)
51 REG32(CM_PLLD, 0x10c)
52     FIELD(CM_PLLD, LOADDSI0, 0, 1)
53     FIELD(CM_PLLD, HOLDDSI0, 1, 1)
54     FIELD(CM_PLLD, LOADDSI1, 2, 1)
55     FIELD(CM_PLLD, HOLDDSI1, 3, 1)
56     FIELD(CM_PLLD, LOADCORE, 4, 1)
57     FIELD(CM_PLLD, HOLDCORE, 5, 1)
58     FIELD(CM_PLLD, LOADPER, 6, 1)
59     FIELD(CM_PLLD, HOLDPER, 7, 1)
60 REG32(CM_PLLH, 0x110)
61     FIELD(CM_PLLH, LOADPIX, 0, 1)
62     FIELD(CM_PLLH, LOADAUX, 1, 1)
63     FIELD(CM_PLLH, LOADRCAL, 2, 1)
64 REG32(CM_PLLB, 0x170)
65     FIELD(CM_PLLB, LOADARM, 0, 1)
66     FIELD(CM_PLLB, HOLDARM, 1, 1)
67 
68 REG32(A2W_PLLA_CTRL, 0x1100)
69     FIELD(A2W_PLLx_CTRL, NDIV, 0, 10)
70     FIELD(A2W_PLLx_CTRL, PDIV, 12, 3)
71     FIELD(A2W_PLLx_CTRL, PWRDN, 16, 1)
72     FIELD(A2W_PLLx_CTRL, PRST_DISABLE, 17, 1)
73 REG32(A2W_PLLC_CTRL, 0x1120)
74 REG32(A2W_PLLD_CTRL, 0x1140)
75 REG32(A2W_PLLH_CTRL, 0x1160)
76 REG32(A2W_PLLB_CTRL, 0x11e0)
77 
78 REG32(A2W_PLLA_ANA0, 0x1010)
79 REG32(A2W_PLLA_ANA1, 0x1014)
80     FIELD(A2W_PLLx_ANA1, FB_PREDIV, 14, 1)
81 REG32(A2W_PLLA_ANA2, 0x1018)
82 REG32(A2W_PLLA_ANA3, 0x101c)
83 
84 REG32(A2W_PLLC_ANA0, 0x1030)
85 REG32(A2W_PLLC_ANA1, 0x1034)
86 REG32(A2W_PLLC_ANA2, 0x1038)
87 REG32(A2W_PLLC_ANA3, 0x103c)
88 
89 REG32(A2W_PLLD_ANA0, 0x1050)
90 REG32(A2W_PLLD_ANA1, 0x1054)
91 REG32(A2W_PLLD_ANA2, 0x1058)
92 REG32(A2W_PLLD_ANA3, 0x105c)
93 
94 REG32(A2W_PLLH_ANA0, 0x1070)
95 REG32(A2W_PLLH_ANA1, 0x1074)
96     FIELD(A2W_PLLH_ANA1, FB_PREDIV, 11, 1)
97 REG32(A2W_PLLH_ANA2, 0x1078)
98 REG32(A2W_PLLH_ANA3, 0x107c)
99 
100 REG32(A2W_PLLB_ANA0, 0x10f0)
101 REG32(A2W_PLLB_ANA1, 0x10f4)
102 REG32(A2W_PLLB_ANA2, 0x10f8)
103 REG32(A2W_PLLB_ANA3, 0x10fc)
104 
105 REG32(A2W_PLLA_FRAC, 0x1200)
106     FIELD(A2W_PLLx_FRAC, FRAC, 0, 20)
107 REG32(A2W_PLLC_FRAC, 0x1220)
108 REG32(A2W_PLLD_FRAC, 0x1240)
109 REG32(A2W_PLLH_FRAC, 0x1260)
110 REG32(A2W_PLLB_FRAC, 0x12e0)
111 
112 /* PLL channels */
113 REG32(A2W_PLLA_DSI0, 0x1300)
114     FIELD(A2W_PLLx_CHANNELy, DIV, 0, 8)
115     FIELD(A2W_PLLx_CHANNELy, DISABLE, 8, 1)
116 REG32(A2W_PLLA_CORE, 0x1400)
117 REG32(A2W_PLLA_PER, 0x1500)
118 REG32(A2W_PLLA_CCP2, 0x1600)
119 
120 REG32(A2W_PLLC_CORE2, 0x1320)
121 REG32(A2W_PLLC_CORE1, 0x1420)
122 REG32(A2W_PLLC_PER, 0x1520)
123 REG32(A2W_PLLC_CORE0, 0x1620)
124 
125 REG32(A2W_PLLD_DSI0, 0x1340)
126 REG32(A2W_PLLD_CORE, 0x1440)
127 REG32(A2W_PLLD_PER, 0x1540)
128 REG32(A2W_PLLD_DSI1, 0x1640)
129 
130 REG32(A2W_PLLH_AUX, 0x1360)
131 REG32(A2W_PLLH_RCAL, 0x1460)
132 REG32(A2W_PLLH_PIX, 0x1560)
133 REG32(A2W_PLLH_STS, 0x1660)
134 
135 REG32(A2W_PLLB_ARM, 0x13e0)
136 
137 /* Clock muxes */
138 REG32(CM_GNRICCTL, 0x000)
139     FIELD(CM_CLOCKx_CTL, SRC, 0, 4)
140     FIELD(CM_CLOCKx_CTL, ENABLE, 4, 1)
141     FIELD(CM_CLOCKx_CTL, KILL, 5, 1)
142     FIELD(CM_CLOCKx_CTL, GATE, 6, 1)
143     FIELD(CM_CLOCKx_CTL, BUSY, 7, 1)
144     FIELD(CM_CLOCKx_CTL, BUSYD, 8, 1)
145     FIELD(CM_CLOCKx_CTL, MASH, 9, 2)
146     FIELD(CM_CLOCKx_CTL, FLIP, 11, 1)
147 REG32(CM_GNRICDIV, 0x004)
148     FIELD(CM_CLOCKx_DIV, FRAC, 0, 12)
149 REG32(CM_VPUCTL, 0x008)
150 REG32(CM_VPUDIV, 0x00c)
151 REG32(CM_SYSCTL, 0x010)
152 REG32(CM_SYSDIV, 0x014)
153 REG32(CM_PERIACTL, 0x018)
154 REG32(CM_PERIADIV, 0x01c)
155 REG32(CM_PERIICTL, 0x020)
156 REG32(CM_PERIIDIV, 0x024)
157 REG32(CM_H264CTL, 0x028)
158 REG32(CM_H264DIV, 0x02c)
159 REG32(CM_ISPCTL, 0x030)
160 REG32(CM_ISPDIV, 0x034)
161 REG32(CM_V3DCTL, 0x038)
162 REG32(CM_V3DDIV, 0x03c)
163 REG32(CM_CAM0CTL, 0x040)
164 REG32(CM_CAM0DIV, 0x044)
165 REG32(CM_CAM1CTL, 0x048)
166 REG32(CM_CAM1DIV, 0x04c)
167 REG32(CM_CCP2CTL, 0x050)
168 REG32(CM_CCP2DIV, 0x054)
169 REG32(CM_DSI0ECTL, 0x058)
170 REG32(CM_DSI0EDIV, 0x05c)
171 REG32(CM_DSI0PCTL, 0x060)
172 REG32(CM_DSI0PDIV, 0x064)
173 REG32(CM_DPICTL, 0x068)
174 REG32(CM_DPIDIV, 0x06c)
175 REG32(CM_GP0CTL, 0x070)
176 REG32(CM_GP0DIV, 0x074)
177 REG32(CM_GP1CTL, 0x078)
178 REG32(CM_GP1DIV, 0x07c)
179 REG32(CM_GP2CTL, 0x080)
180 REG32(CM_GP2DIV, 0x084)
181 REG32(CM_HSMCTL, 0x088)
182 REG32(CM_HSMDIV, 0x08c)
183 REG32(CM_OTPCTL, 0x090)
184 REG32(CM_OTPDIV, 0x094)
185 REG32(CM_PCMCTL, 0x098)
186 REG32(CM_PCMDIV, 0x09c)
187 REG32(CM_PWMCTL, 0x0a0)
188 REG32(CM_PWMDIV, 0x0a4)
189 REG32(CM_SLIMCTL, 0x0a8)
190 REG32(CM_SLIMDIV, 0x0ac)
191 REG32(CM_SMICTL, 0x0b0)
192 REG32(CM_SMIDIV, 0x0b4)
193 REG32(CM_TCNTCTL, 0x0c0)
194 REG32(CM_TCNTCNT, 0x0c4)
195 REG32(CM_TECCTL, 0x0c8)
196 REG32(CM_TECDIV, 0x0cc)
197 REG32(CM_TD0CTL, 0x0d0)
198 REG32(CM_TD0DIV, 0x0d4)
199 REG32(CM_TD1CTL, 0x0d8)
200 REG32(CM_TD1DIV, 0x0dc)
201 REG32(CM_TSENSCTL, 0x0e0)
202 REG32(CM_TSENSDIV, 0x0e4)
203 REG32(CM_TIMERCTL, 0x0e8)
204 REG32(CM_TIMERDIV, 0x0ec)
205 REG32(CM_UARTCTL, 0x0f0)
206 REG32(CM_UARTDIV, 0x0f4)
207 REG32(CM_VECCTL, 0x0f8)
208 REG32(CM_VECDIV, 0x0fc)
209 REG32(CM_PULSECTL, 0x190)
210 REG32(CM_PULSEDIV, 0x194)
211 REG32(CM_SDCCTL, 0x1a8)
212 REG32(CM_SDCDIV, 0x1ac)
213 REG32(CM_ARMCTL, 0x1b0)
214 REG32(CM_AVEOCTL, 0x1b8)
215 REG32(CM_AVEODIV, 0x1bc)
216 REG32(CM_EMMCCTL, 0x1c0)
217 REG32(CM_EMMCDIV, 0x1c4)
218 REG32(CM_EMMC2CTL, 0x1d0)
219 REG32(CM_EMMC2DIV, 0x1d4)
220 
221 /* misc registers */
222 REG32(CM_LOCK, 0x114)
223     FIELD(CM_LOCK, FLOCKH, 12, 1)
224     FIELD(CM_LOCK, FLOCKD, 11, 1)
225     FIELD(CM_LOCK, FLOCKC, 10, 1)
226     FIELD(CM_LOCK, FLOCKB, 9, 1)
227     FIELD(CM_LOCK, FLOCKA, 8, 1)
228 
229 REG32(CM_DSI0HSCK, 0x120)
230     FIELD(CM_DSI0HSCK, SELPLLD, 0, 1)
231 
232 /*
233  * This field is common to all registers. Each register write value must match
234  * the CPRMAN_PASSWORD magic value in its 8 MSB.
235  */
236 FIELD(CPRMAN, PASSWORD, 24, 8)
237 #define CPRMAN_PASSWORD 0x5a
238 
239 /* PLL init info */
240 typedef struct PLLInitInfo {
241     const char *name;
242     size_t cm_offset;
243     size_t a2w_ctrl_offset;
244     size_t a2w_ana_offset;
245     uint32_t prediv_mask; /* Prediv bit in ana[1] */
246     size_t a2w_frac_offset;
247 } PLLInitInfo;
248 
249 #define FILL_PLL_INIT_INFO(pll_)                \
250     .cm_offset = R_CM_ ## pll_,                 \
251     .a2w_ctrl_offset = R_A2W_ ## pll_ ## _CTRL, \
252     .a2w_ana_offset = R_A2W_ ## pll_ ## _ANA0,  \
253     .a2w_frac_offset = R_A2W_ ## pll_ ## _FRAC
254 
255 static const PLLInitInfo PLL_INIT_INFO[] = {
256     [CPRMAN_PLLA] = {
257         .name = "plla",
258         .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK,
259         FILL_PLL_INIT_INFO(PLLA),
260     },
261     [CPRMAN_PLLC] = {
262         .name = "pllc",
263         .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK,
264         FILL_PLL_INIT_INFO(PLLC),
265     },
266     [CPRMAN_PLLD] = {
267         .name = "plld",
268         .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK,
269         FILL_PLL_INIT_INFO(PLLD),
270     },
271     [CPRMAN_PLLH] = {
272         .name = "pllh",
273         .prediv_mask = R_A2W_PLLH_ANA1_FB_PREDIV_MASK,
274         FILL_PLL_INIT_INFO(PLLH),
275     },
276     [CPRMAN_PLLB] = {
277         .name = "pllb",
278         .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK,
279         FILL_PLL_INIT_INFO(PLLB),
280     },
281 };
282 
283 #undef FILL_PLL_CHANNEL_INIT_INFO
284 
285 static inline void set_pll_init_info(BCM2835CprmanState *s,
286                                      CprmanPllState *pll,
287                                      CprmanPll id)
288 {
289     pll->id = id;
290     pll->reg_cm = &s->regs[PLL_INIT_INFO[id].cm_offset];
291     pll->reg_a2w_ctrl = &s->regs[PLL_INIT_INFO[id].a2w_ctrl_offset];
292     pll->reg_a2w_ana = &s->regs[PLL_INIT_INFO[id].a2w_ana_offset];
293     pll->prediv_mask = PLL_INIT_INFO[id].prediv_mask;
294     pll->reg_a2w_frac = &s->regs[PLL_INIT_INFO[id].a2w_frac_offset];
295 }
296 
297 
298 /* PLL channel init info */
299 typedef struct PLLChannelInitInfo {
300     const char *name;
301     CprmanPll parent;
302     size_t cm_offset;
303     uint32_t cm_hold_mask;
304     uint32_t cm_load_mask;
305     size_t a2w_ctrl_offset;
306     unsigned int fixed_divider;
307 } PLLChannelInitInfo;
308 
309 #define FILL_PLL_CHANNEL_INIT_INFO_common(pll_, channel_)            \
310     .parent = CPRMAN_ ## pll_,                                       \
311     .cm_offset = R_CM_ ## pll_,                                      \
312     .cm_load_mask = R_CM_ ## pll_ ## _ ## LOAD ## channel_ ## _MASK, \
313     .a2w_ctrl_offset = R_A2W_ ## pll_ ## _ ## channel_
314 
315 #define FILL_PLL_CHANNEL_INIT_INFO(pll_, channel_)                   \
316     FILL_PLL_CHANNEL_INIT_INFO_common(pll_, channel_),               \
317     .cm_hold_mask = R_CM_ ## pll_ ## _ ## HOLD ## channel_ ## _MASK, \
318     .fixed_divider = 1
319 
320 #define FILL_PLL_CHANNEL_INIT_INFO_nohold(pll_, channel_) \
321     FILL_PLL_CHANNEL_INIT_INFO_common(pll_, channel_),    \
322     .cm_hold_mask = 0
323 
324 static PLLChannelInitInfo PLL_CHANNEL_INIT_INFO[] = {
325     [CPRMAN_PLLA_CHANNEL_DSI0] = {
326         .name = "plla-dsi0",
327         FILL_PLL_CHANNEL_INIT_INFO(PLLA, DSI0),
328     },
329     [CPRMAN_PLLA_CHANNEL_CORE] = {
330         .name = "plla-core",
331         FILL_PLL_CHANNEL_INIT_INFO(PLLA, CORE),
332     },
333     [CPRMAN_PLLA_CHANNEL_PER] = {
334         .name = "plla-per",
335         FILL_PLL_CHANNEL_INIT_INFO(PLLA, PER),
336     },
337     [CPRMAN_PLLA_CHANNEL_CCP2] = {
338         .name = "plla-ccp2",
339         FILL_PLL_CHANNEL_INIT_INFO(PLLA, CCP2),
340     },
341 
342     [CPRMAN_PLLC_CHANNEL_CORE2] = {
343         .name = "pllc-core2",
344         FILL_PLL_CHANNEL_INIT_INFO(PLLC, CORE2),
345     },
346     [CPRMAN_PLLC_CHANNEL_CORE1] = {
347         .name = "pllc-core1",
348         FILL_PLL_CHANNEL_INIT_INFO(PLLC, CORE1),
349     },
350     [CPRMAN_PLLC_CHANNEL_PER] = {
351         .name = "pllc-per",
352         FILL_PLL_CHANNEL_INIT_INFO(PLLC, PER),
353     },
354     [CPRMAN_PLLC_CHANNEL_CORE0] = {
355         .name = "pllc-core0",
356         FILL_PLL_CHANNEL_INIT_INFO(PLLC, CORE0),
357     },
358 
359     [CPRMAN_PLLD_CHANNEL_DSI0] = {
360         .name = "plld-dsi0",
361         FILL_PLL_CHANNEL_INIT_INFO(PLLD, DSI0),
362     },
363     [CPRMAN_PLLD_CHANNEL_CORE] = {
364         .name = "plld-core",
365         FILL_PLL_CHANNEL_INIT_INFO(PLLD, CORE),
366     },
367     [CPRMAN_PLLD_CHANNEL_PER] = {
368         .name = "plld-per",
369         FILL_PLL_CHANNEL_INIT_INFO(PLLD, PER),
370     },
371     [CPRMAN_PLLD_CHANNEL_DSI1] = {
372         .name = "plld-dsi1",
373         FILL_PLL_CHANNEL_INIT_INFO(PLLD, DSI1),
374     },
375 
376     [CPRMAN_PLLH_CHANNEL_AUX] = {
377         .name = "pllh-aux",
378         .fixed_divider = 1,
379         FILL_PLL_CHANNEL_INIT_INFO_nohold(PLLH, AUX),
380     },
381     [CPRMAN_PLLH_CHANNEL_RCAL] = {
382         .name = "pllh-rcal",
383         .fixed_divider = 10,
384         FILL_PLL_CHANNEL_INIT_INFO_nohold(PLLH, RCAL),
385     },
386     [CPRMAN_PLLH_CHANNEL_PIX] = {
387         .name = "pllh-pix",
388         .fixed_divider = 10,
389         FILL_PLL_CHANNEL_INIT_INFO_nohold(PLLH, PIX),
390     },
391 
392     [CPRMAN_PLLB_CHANNEL_ARM] = {
393         .name = "pllb-arm",
394         FILL_PLL_CHANNEL_INIT_INFO(PLLB, ARM),
395     },
396 };
397 
398 #undef FILL_PLL_CHANNEL_INIT_INFO_nohold
399 #undef FILL_PLL_CHANNEL_INIT_INFO
400 #undef FILL_PLL_CHANNEL_INIT_INFO_common
401 
402 static inline void set_pll_channel_init_info(BCM2835CprmanState *s,
403                                              CprmanPllChannelState *channel,
404                                              CprmanPllChannel id)
405 {
406     channel->id = id;
407     channel->parent = PLL_CHANNEL_INIT_INFO[id].parent;
408     channel->reg_cm = &s->regs[PLL_CHANNEL_INIT_INFO[id].cm_offset];
409     channel->hold_mask = PLL_CHANNEL_INIT_INFO[id].cm_hold_mask;
410     channel->load_mask = PLL_CHANNEL_INIT_INFO[id].cm_load_mask;
411     channel->reg_a2w_ctrl = &s->regs[PLL_CHANNEL_INIT_INFO[id].a2w_ctrl_offset];
412     channel->fixed_divider = PLL_CHANNEL_INIT_INFO[id].fixed_divider;
413 }
414 
415 /* Clock mux init info */
416 typedef struct ClockMuxInitInfo {
417     const char *name;
418     size_t cm_offset; /* cm_offset[0]->CM_CTL, cm_offset[1]->CM_DIV */
419     int int_bits;
420     int frac_bits;
421 
422     CprmanPllChannel src_mapping[CPRMAN_NUM_CLOCK_MUX_SRC];
423 } ClockMuxInitInfo;
424 
425 /*
426  * Each clock mux can have up to 10 sources. Sources 0 to 3 are always the
427  * same (ground, xosc, td0, td1). Sources 4 to 9 are mux specific, and are not
428  * always populated. The following macros catch all those cases.
429  */
430 
431 /* Unknown mapping. Connect everything to ground */
432 #define SRC_MAPPING_INFO_unknown                          \
433     .src_mapping = {                                      \
434         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* gnd */          \
435         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* xosc */         \
436         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* test debug 0 */ \
437         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* test debug 1 */ \
438         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll a */        \
439         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll c */        \
440         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll d */        \
441         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll h */        \
442         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll c, core1 */ \
443         CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll c, core2 */ \
444     }
445 
446 /* Only the oscillator and the two test debug clocks */
447 #define SRC_MAPPING_INFO_xosc          \
448     .src_mapping = {                   \
449         CPRMAN_CLOCK_SRC_NORMAL,       \
450         CPRMAN_CLOCK_SRC_NORMAL,       \
451         CPRMAN_CLOCK_SRC_NORMAL,       \
452         CPRMAN_CLOCK_SRC_NORMAL,       \
453         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
454         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
455         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
456         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
457         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
458         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
459     }
460 
461 /* All the PLL "core" channels */
462 #define SRC_MAPPING_INFO_core      \
463     .src_mapping = {               \
464         CPRMAN_CLOCK_SRC_NORMAL,   \
465         CPRMAN_CLOCK_SRC_NORMAL,   \
466         CPRMAN_CLOCK_SRC_NORMAL,   \
467         CPRMAN_CLOCK_SRC_NORMAL,   \
468         CPRMAN_PLLA_CHANNEL_CORE,  \
469         CPRMAN_PLLC_CHANNEL_CORE0, \
470         CPRMAN_PLLD_CHANNEL_CORE,  \
471         CPRMAN_PLLH_CHANNEL_AUX,   \
472         CPRMAN_PLLC_CHANNEL_CORE1, \
473         CPRMAN_PLLC_CHANNEL_CORE2, \
474     }
475 
476 /* All the PLL "per" channels */
477 #define SRC_MAPPING_INFO_periph        \
478     .src_mapping = {                   \
479         CPRMAN_CLOCK_SRC_NORMAL,       \
480         CPRMAN_CLOCK_SRC_NORMAL,       \
481         CPRMAN_CLOCK_SRC_NORMAL,       \
482         CPRMAN_CLOCK_SRC_NORMAL,       \
483         CPRMAN_PLLA_CHANNEL_PER,       \
484         CPRMAN_PLLC_CHANNEL_PER,       \
485         CPRMAN_PLLD_CHANNEL_PER,       \
486         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
487         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
488         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
489     }
490 
491 /*
492  * The DSI0 channels. This one got an intermediate mux between the PLL channels
493  * and the clock input.
494  */
495 #define SRC_MAPPING_INFO_dsi0          \
496     .src_mapping = {                   \
497         CPRMAN_CLOCK_SRC_NORMAL,       \
498         CPRMAN_CLOCK_SRC_NORMAL,       \
499         CPRMAN_CLOCK_SRC_NORMAL,       \
500         CPRMAN_CLOCK_SRC_NORMAL,       \
501         CPRMAN_CLOCK_SRC_DSI0HSCK,     \
502         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
503         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
504         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
505         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
506         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
507     }
508 
509 /* The DSI1 channel */
510 #define SRC_MAPPING_INFO_dsi1          \
511     .src_mapping = {                   \
512         CPRMAN_CLOCK_SRC_NORMAL,       \
513         CPRMAN_CLOCK_SRC_NORMAL,       \
514         CPRMAN_CLOCK_SRC_NORMAL,       \
515         CPRMAN_CLOCK_SRC_NORMAL,       \
516         CPRMAN_PLLD_CHANNEL_DSI1,      \
517         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
518         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
519         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
520         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
521         CPRMAN_CLOCK_SRC_FORCE_GROUND, \
522     }
523 
524 #define FILL_CLOCK_MUX_SRC_MAPPING_INIT_INFO(kind_) \
525     SRC_MAPPING_INFO_ ## kind_
526 
527 #define FILL_CLOCK_MUX_INIT_INFO(clock_, kind_) \
528     .cm_offset = R_CM_ ## clock_ ## CTL,        \
529     FILL_CLOCK_MUX_SRC_MAPPING_INIT_INFO(kind_)
530 
531 static ClockMuxInitInfo CLOCK_MUX_INIT_INFO[] = {
532     [CPRMAN_CLOCK_GNRIC] = {
533         .name = "gnric",
534         FILL_CLOCK_MUX_INIT_INFO(GNRIC, unknown),
535     },
536     [CPRMAN_CLOCK_VPU] = {
537         .name = "vpu",
538         .int_bits = 12,
539         .frac_bits = 8,
540         FILL_CLOCK_MUX_INIT_INFO(VPU, core),
541     },
542     [CPRMAN_CLOCK_SYS] = {
543         .name = "sys",
544         FILL_CLOCK_MUX_INIT_INFO(SYS, unknown),
545     },
546     [CPRMAN_CLOCK_PERIA] = {
547         .name = "peria",
548         FILL_CLOCK_MUX_INIT_INFO(PERIA, unknown),
549     },
550     [CPRMAN_CLOCK_PERII] = {
551         .name = "perii",
552         FILL_CLOCK_MUX_INIT_INFO(PERII, unknown),
553     },
554     [CPRMAN_CLOCK_H264] = {
555         .name = "h264",
556         .int_bits = 4,
557         .frac_bits = 8,
558         FILL_CLOCK_MUX_INIT_INFO(H264, core),
559     },
560     [CPRMAN_CLOCK_ISP] = {
561         .name = "isp",
562         .int_bits = 4,
563         .frac_bits = 8,
564         FILL_CLOCK_MUX_INIT_INFO(ISP, core),
565     },
566     [CPRMAN_CLOCK_V3D] = {
567         .name = "v3d",
568         FILL_CLOCK_MUX_INIT_INFO(V3D, core),
569     },
570     [CPRMAN_CLOCK_CAM0] = {
571         .name = "cam0",
572         .int_bits = 4,
573         .frac_bits = 8,
574         FILL_CLOCK_MUX_INIT_INFO(CAM0, periph),
575     },
576     [CPRMAN_CLOCK_CAM1] = {
577         .name = "cam1",
578         .int_bits = 4,
579         .frac_bits = 8,
580         FILL_CLOCK_MUX_INIT_INFO(CAM1, periph),
581     },
582     [CPRMAN_CLOCK_CCP2] = {
583         .name = "ccp2",
584         FILL_CLOCK_MUX_INIT_INFO(CCP2, unknown),
585     },
586     [CPRMAN_CLOCK_DSI0E] = {
587         .name = "dsi0e",
588         .int_bits = 4,
589         .frac_bits = 8,
590         FILL_CLOCK_MUX_INIT_INFO(DSI0E, dsi0),
591     },
592     [CPRMAN_CLOCK_DSI0P] = {
593         .name = "dsi0p",
594         .int_bits = 0,
595         .frac_bits = 0,
596         FILL_CLOCK_MUX_INIT_INFO(DSI0P, dsi0),
597     },
598     [CPRMAN_CLOCK_DPI] = {
599         .name = "dpi",
600         .int_bits = 4,
601         .frac_bits = 8,
602         FILL_CLOCK_MUX_INIT_INFO(DPI, periph),
603     },
604     [CPRMAN_CLOCK_GP0] = {
605         .name = "gp0",
606         .int_bits = 12,
607         .frac_bits = 12,
608         FILL_CLOCK_MUX_INIT_INFO(GP0, periph),
609     },
610     [CPRMAN_CLOCK_GP1] = {
611         .name = "gp1",
612         .int_bits = 12,
613         .frac_bits = 12,
614         FILL_CLOCK_MUX_INIT_INFO(GP1, periph),
615     },
616     [CPRMAN_CLOCK_GP2] = {
617         .name = "gp2",
618         .int_bits = 12,
619         .frac_bits = 12,
620         FILL_CLOCK_MUX_INIT_INFO(GP2, periph),
621     },
622     [CPRMAN_CLOCK_HSM] = {
623         .name = "hsm",
624         .int_bits = 4,
625         .frac_bits = 8,
626         FILL_CLOCK_MUX_INIT_INFO(HSM, periph),
627     },
628     [CPRMAN_CLOCK_OTP] = {
629         .name = "otp",
630         .int_bits = 4,
631         .frac_bits = 0,
632         FILL_CLOCK_MUX_INIT_INFO(OTP, xosc),
633     },
634     [CPRMAN_CLOCK_PCM] = {
635         .name = "pcm",
636         .int_bits = 12,
637         .frac_bits = 12,
638         FILL_CLOCK_MUX_INIT_INFO(PCM, periph),
639     },
640     [CPRMAN_CLOCK_PWM] = {
641         .name = "pwm",
642         .int_bits = 12,
643         .frac_bits = 12,
644         FILL_CLOCK_MUX_INIT_INFO(PWM, periph),
645     },
646     [CPRMAN_CLOCK_SLIM] = {
647         .name = "slim",
648         .int_bits = 12,
649         .frac_bits = 12,
650         FILL_CLOCK_MUX_INIT_INFO(SLIM, periph),
651     },
652     [CPRMAN_CLOCK_SMI] = {
653         .name = "smi",
654         .int_bits = 4,
655         .frac_bits = 8,
656         FILL_CLOCK_MUX_INIT_INFO(SMI, periph),
657     },
658     [CPRMAN_CLOCK_TEC] = {
659         .name = "tec",
660         .int_bits = 6,
661         .frac_bits = 0,
662         FILL_CLOCK_MUX_INIT_INFO(TEC, xosc),
663     },
664     [CPRMAN_CLOCK_TD0] = {
665         .name = "td0",
666         FILL_CLOCK_MUX_INIT_INFO(TD0, unknown),
667     },
668     [CPRMAN_CLOCK_TD1] = {
669         .name = "td1",
670         FILL_CLOCK_MUX_INIT_INFO(TD1, unknown),
671     },
672     [CPRMAN_CLOCK_TSENS] = {
673         .name = "tsens",
674         .int_bits = 5,
675         .frac_bits = 0,
676         FILL_CLOCK_MUX_INIT_INFO(TSENS, xosc),
677     },
678     [CPRMAN_CLOCK_TIMER] = {
679         .name = "timer",
680         .int_bits = 6,
681         .frac_bits = 12,
682         FILL_CLOCK_MUX_INIT_INFO(TIMER, xosc),
683     },
684     [CPRMAN_CLOCK_UART] = {
685         .name = "uart",
686         .int_bits = 10,
687         .frac_bits = 12,
688         FILL_CLOCK_MUX_INIT_INFO(UART, periph),
689     },
690     [CPRMAN_CLOCK_VEC] = {
691         .name = "vec",
692         .int_bits = 4,
693         .frac_bits = 0,
694         FILL_CLOCK_MUX_INIT_INFO(VEC, periph),
695     },
696     [CPRMAN_CLOCK_PULSE] = {
697         .name = "pulse",
698         FILL_CLOCK_MUX_INIT_INFO(PULSE, xosc),
699     },
700     [CPRMAN_CLOCK_SDC] = {
701         .name = "sdram",
702         .int_bits = 6,
703         .frac_bits = 0,
704         FILL_CLOCK_MUX_INIT_INFO(SDC, core),
705     },
706     [CPRMAN_CLOCK_ARM] = {
707         .name = "arm",
708         FILL_CLOCK_MUX_INIT_INFO(ARM, unknown),
709     },
710     [CPRMAN_CLOCK_AVEO] = {
711         .name = "aveo",
712         .int_bits = 4,
713         .frac_bits = 0,
714         FILL_CLOCK_MUX_INIT_INFO(AVEO, periph),
715     },
716     [CPRMAN_CLOCK_EMMC] = {
717         .name = "emmc",
718         .int_bits = 4,
719         .frac_bits = 8,
720         FILL_CLOCK_MUX_INIT_INFO(EMMC, periph),
721     },
722     [CPRMAN_CLOCK_EMMC2] = {
723         .name = "emmc2",
724         .int_bits = 4,
725         .frac_bits = 8,
726         FILL_CLOCK_MUX_INIT_INFO(EMMC2, unknown),
727     },
728 };
729 
730 #undef FILL_CLOCK_MUX_INIT_INFO
731 #undef FILL_CLOCK_MUX_SRC_MAPPING_INIT_INFO
732 #undef SRC_MAPPING_INFO_dsi1
733 #undef SRC_MAPPING_INFO_dsi0
734 #undef SRC_MAPPING_INFO_periph
735 #undef SRC_MAPPING_INFO_core
736 #undef SRC_MAPPING_INFO_xosc
737 #undef SRC_MAPPING_INFO_unknown
738 
739 static inline void set_clock_mux_init_info(BCM2835CprmanState *s,
740                                            CprmanClockMuxState *mux,
741                                            CprmanClockMux id)
742 {
743     mux->id = id;
744     mux->reg_ctl = &s->regs[CLOCK_MUX_INIT_INFO[id].cm_offset];
745     mux->reg_div = &s->regs[CLOCK_MUX_INIT_INFO[id].cm_offset + 1];
746     mux->int_bits = CLOCK_MUX_INIT_INFO[id].int_bits;
747     mux->frac_bits = CLOCK_MUX_INIT_INFO[id].frac_bits;
748 }
749 
750 #endif
751