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_BCM2835_CPRMAN_INTERNALS_H
10 #define HW_MISC_BCM2835_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
set_pll_init_info(BCM2835CprmanState * s,CprmanPllState * pll,CprmanPll id)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
set_pll_channel_init_info(BCM2835CprmanState * s,CprmanPllChannelState * channel,CprmanPllChannel id)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
set_clock_mux_init_info(BCM2835CprmanState * s,CprmanClockMuxState * mux,CprmanClockMux id)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
751 /*
752 * Object reset info
753 * Those values have been dumped from a Raspberry Pi 3 Model B v1.2 using the
754 * clk debugfs interface in Linux.
755 */
756 typedef struct PLLResetInfo {
757 uint32_t cm;
758 uint32_t a2w_ctrl;
759 uint32_t a2w_ana[4];
760 uint32_t a2w_frac;
761 } PLLResetInfo;
762
763 static const PLLResetInfo PLL_RESET_INFO[] = {
764 [CPRMAN_PLLA] = {
765 .cm = 0x0000008a,
766 .a2w_ctrl = 0x0002103a,
767 .a2w_frac = 0x00098000,
768 .a2w_ana = { 0x00000000, 0x00144000, 0x00000000, 0x00000100 }
769 },
770
771 [CPRMAN_PLLC] = {
772 .cm = 0x00000228,
773 .a2w_ctrl = 0x0002103e,
774 .a2w_frac = 0x00080000,
775 .a2w_ana = { 0x00000000, 0x00144000, 0x00000000, 0x00000100 }
776 },
777
778 [CPRMAN_PLLD] = {
779 .cm = 0x0000020a,
780 .a2w_ctrl = 0x00021034,
781 .a2w_frac = 0x00015556,
782 .a2w_ana = { 0x00000000, 0x00144000, 0x00000000, 0x00000100 }
783 },
784
785 [CPRMAN_PLLH] = {
786 .cm = 0x00000000,
787 .a2w_ctrl = 0x0002102d,
788 .a2w_frac = 0x00000000,
789 .a2w_ana = { 0x00900000, 0x0000000c, 0x00000000, 0x00000000 }
790 },
791
792 [CPRMAN_PLLB] = {
793 /* unknown */
794 .cm = 0x00000000,
795 .a2w_ctrl = 0x00000000,
796 .a2w_frac = 0x00000000,
797 .a2w_ana = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
798 }
799 };
800
801 typedef struct PLLChannelResetInfo {
802 /*
803 * Even though a PLL channel has a CM register, it shares it with its
804 * parent PLL. The parent already takes care of the reset value.
805 */
806 uint32_t a2w_ctrl;
807 } PLLChannelResetInfo;
808
809 static const PLLChannelResetInfo PLL_CHANNEL_RESET_INFO[] = {
810 [CPRMAN_PLLA_CHANNEL_DSI0] = { .a2w_ctrl = 0x00000100 },
811 [CPRMAN_PLLA_CHANNEL_CORE] = { .a2w_ctrl = 0x00000003 },
812 [CPRMAN_PLLA_CHANNEL_PER] = { .a2w_ctrl = 0x00000000 }, /* unknown */
813 [CPRMAN_PLLA_CHANNEL_CCP2] = { .a2w_ctrl = 0x00000100 },
814
815 [CPRMAN_PLLC_CHANNEL_CORE2] = { .a2w_ctrl = 0x00000100 },
816 [CPRMAN_PLLC_CHANNEL_CORE1] = { .a2w_ctrl = 0x00000100 },
817 [CPRMAN_PLLC_CHANNEL_PER] = { .a2w_ctrl = 0x00000002 },
818 [CPRMAN_PLLC_CHANNEL_CORE0] = { .a2w_ctrl = 0x00000002 },
819
820 [CPRMAN_PLLD_CHANNEL_DSI0] = { .a2w_ctrl = 0x00000100 },
821 [CPRMAN_PLLD_CHANNEL_CORE] = { .a2w_ctrl = 0x00000004 },
822 [CPRMAN_PLLD_CHANNEL_PER] = { .a2w_ctrl = 0x00000004 },
823 [CPRMAN_PLLD_CHANNEL_DSI1] = { .a2w_ctrl = 0x00000100 },
824
825 [CPRMAN_PLLH_CHANNEL_AUX] = { .a2w_ctrl = 0x00000004 },
826 [CPRMAN_PLLH_CHANNEL_RCAL] = { .a2w_ctrl = 0x00000000 },
827 [CPRMAN_PLLH_CHANNEL_PIX] = { .a2w_ctrl = 0x00000000 },
828
829 [CPRMAN_PLLB_CHANNEL_ARM] = { .a2w_ctrl = 0x00000000 }, /* unknown */
830 };
831
832 typedef struct ClockMuxResetInfo {
833 uint32_t cm_ctl;
834 uint32_t cm_div;
835 } ClockMuxResetInfo;
836
837 static const ClockMuxResetInfo CLOCK_MUX_RESET_INFO[] = {
838 [CPRMAN_CLOCK_GNRIC] = {
839 .cm_ctl = 0, /* unknown */
840 .cm_div = 0
841 },
842
843 [CPRMAN_CLOCK_VPU] = {
844 .cm_ctl = 0x00000245,
845 .cm_div = 0x00003000,
846 },
847
848 [CPRMAN_CLOCK_SYS] = {
849 .cm_ctl = 0, /* unknown */
850 .cm_div = 0
851 },
852
853 [CPRMAN_CLOCK_PERIA] = {
854 .cm_ctl = 0, /* unknown */
855 .cm_div = 0
856 },
857
858 [CPRMAN_CLOCK_PERII] = {
859 .cm_ctl = 0, /* unknown */
860 .cm_div = 0
861 },
862
863 [CPRMAN_CLOCK_H264] = {
864 .cm_ctl = 0x00000244,
865 .cm_div = 0x00003000,
866 },
867
868 [CPRMAN_CLOCK_ISP] = {
869 .cm_ctl = 0x00000244,
870 .cm_div = 0x00003000,
871 },
872
873 [CPRMAN_CLOCK_V3D] = {
874 .cm_ctl = 0, /* unknown */
875 .cm_div = 0
876 },
877
878 [CPRMAN_CLOCK_CAM0] = {
879 .cm_ctl = 0x00000000,
880 .cm_div = 0x00000000,
881 },
882
883 [CPRMAN_CLOCK_CAM1] = {
884 .cm_ctl = 0x00000000,
885 .cm_div = 0x00000000,
886 },
887
888 [CPRMAN_CLOCK_CCP2] = {
889 .cm_ctl = 0, /* unknown */
890 .cm_div = 0
891 },
892
893 [CPRMAN_CLOCK_DSI0E] = {
894 .cm_ctl = 0x00000000,
895 .cm_div = 0x00000000,
896 },
897
898 [CPRMAN_CLOCK_DSI0P] = {
899 .cm_ctl = 0x00000000,
900 .cm_div = 0x00000000,
901 },
902
903 [CPRMAN_CLOCK_DPI] = {
904 .cm_ctl = 0x00000000,
905 .cm_div = 0x00000000,
906 },
907
908 [CPRMAN_CLOCK_GP0] = {
909 .cm_ctl = 0x00000200,
910 .cm_div = 0x00000000,
911 },
912
913 [CPRMAN_CLOCK_GP1] = {
914 .cm_ctl = 0x00000096,
915 .cm_div = 0x00014000,
916 },
917
918 [CPRMAN_CLOCK_GP2] = {
919 .cm_ctl = 0x00000291,
920 .cm_div = 0x00249f00,
921 },
922
923 [CPRMAN_CLOCK_HSM] = {
924 .cm_ctl = 0x00000000,
925 .cm_div = 0x00000000,
926 },
927
928 [CPRMAN_CLOCK_OTP] = {
929 .cm_ctl = 0x00000091,
930 .cm_div = 0x00004000,
931 },
932
933 [CPRMAN_CLOCK_PCM] = {
934 .cm_ctl = 0x00000200,
935 .cm_div = 0x00000000,
936 },
937
938 [CPRMAN_CLOCK_PWM] = {
939 .cm_ctl = 0x00000200,
940 .cm_div = 0x00000000,
941 },
942
943 [CPRMAN_CLOCK_SLIM] = {
944 .cm_ctl = 0x00000200,
945 .cm_div = 0x00000000,
946 },
947
948 [CPRMAN_CLOCK_SMI] = {
949 .cm_ctl = 0x00000000,
950 .cm_div = 0x00000000,
951 },
952
953 [CPRMAN_CLOCK_TEC] = {
954 .cm_ctl = 0x00000000,
955 .cm_div = 0x00000000,
956 },
957
958 [CPRMAN_CLOCK_TD0] = {
959 .cm_ctl = 0, /* unknown */
960 .cm_div = 0
961 },
962
963 [CPRMAN_CLOCK_TD1] = {
964 .cm_ctl = 0, /* unknown */
965 .cm_div = 0
966 },
967
968 [CPRMAN_CLOCK_TSENS] = {
969 .cm_ctl = 0x00000091,
970 .cm_div = 0x0000a000,
971 },
972
973 [CPRMAN_CLOCK_TIMER] = {
974 .cm_ctl = 0x00000291,
975 .cm_div = 0x00013333,
976 },
977
978 [CPRMAN_CLOCK_UART] = {
979 .cm_ctl = 0x00000296,
980 .cm_div = 0x0000a6ab,
981 },
982
983 [CPRMAN_CLOCK_VEC] = {
984 .cm_ctl = 0x00000097,
985 .cm_div = 0x00002000,
986 },
987
988 [CPRMAN_CLOCK_PULSE] = {
989 .cm_ctl = 0, /* unknown */
990 .cm_div = 0
991 },
992
993 [CPRMAN_CLOCK_SDC] = {
994 .cm_ctl = 0x00004006,
995 .cm_div = 0x00003000,
996 },
997
998 [CPRMAN_CLOCK_ARM] = {
999 .cm_ctl = 0, /* unknown */
1000 .cm_div = 0
1001 },
1002
1003 [CPRMAN_CLOCK_AVEO] = {
1004 .cm_ctl = 0x00000000,
1005 .cm_div = 0x00000000,
1006 },
1007
1008 [CPRMAN_CLOCK_EMMC] = {
1009 .cm_ctl = 0x00000295,
1010 .cm_div = 0x00006000,
1011 },
1012
1013 [CPRMAN_CLOCK_EMMC2] = {
1014 .cm_ctl = 0, /* unknown */
1015 .cm_div = 0
1016 },
1017 };
1018
1019 #endif
1020