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