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 17 DECLARE_INSTANCE_CHECKER(CprmanPllState, CPRMAN_PLL, 18 TYPE_CPRMAN_PLL) 19 20 /* Register map */ 21 22 /* PLLs */ 23 REG32(CM_PLLA, 0x104) 24 FIELD(CM_PLLA, LOADDSI0, 0, 1) 25 FIELD(CM_PLLA, HOLDDSI0, 1, 1) 26 FIELD(CM_PLLA, LOADCCP2, 2, 1) 27 FIELD(CM_PLLA, HOLDCCP2, 3, 1) 28 FIELD(CM_PLLA, LOADCORE, 4, 1) 29 FIELD(CM_PLLA, HOLDCORE, 5, 1) 30 FIELD(CM_PLLA, LOADPER, 6, 1) 31 FIELD(CM_PLLA, HOLDPER, 7, 1) 32 FIELD(CM_PLLx, ANARST, 8, 1) 33 REG32(CM_PLLC, 0x108) 34 FIELD(CM_PLLC, LOADCORE0, 0, 1) 35 FIELD(CM_PLLC, HOLDCORE0, 1, 1) 36 FIELD(CM_PLLC, LOADCORE1, 2, 1) 37 FIELD(CM_PLLC, HOLDCORE1, 3, 1) 38 FIELD(CM_PLLC, LOADCORE2, 4, 1) 39 FIELD(CM_PLLC, HOLDCORE2, 5, 1) 40 FIELD(CM_PLLC, LOADPER, 6, 1) 41 FIELD(CM_PLLC, HOLDPER, 7, 1) 42 REG32(CM_PLLD, 0x10c) 43 FIELD(CM_PLLD, LOADDSI0, 0, 1) 44 FIELD(CM_PLLD, HOLDDSI0, 1, 1) 45 FIELD(CM_PLLD, LOADDSI1, 2, 1) 46 FIELD(CM_PLLD, HOLDDSI1, 3, 1) 47 FIELD(CM_PLLD, LOADCORE, 4, 1) 48 FIELD(CM_PLLD, HOLDCORE, 5, 1) 49 FIELD(CM_PLLD, LOADPER, 6, 1) 50 FIELD(CM_PLLD, HOLDPER, 7, 1) 51 REG32(CM_PLLH, 0x110) 52 FIELD(CM_PLLH, LOADPIX, 0, 1) 53 FIELD(CM_PLLH, LOADAUX, 1, 1) 54 FIELD(CM_PLLH, LOADRCAL, 2, 1) 55 REG32(CM_PLLB, 0x170) 56 FIELD(CM_PLLB, LOADARM, 0, 1) 57 FIELD(CM_PLLB, HOLDARM, 1, 1) 58 59 REG32(A2W_PLLA_CTRL, 0x1100) 60 FIELD(A2W_PLLx_CTRL, NDIV, 0, 10) 61 FIELD(A2W_PLLx_CTRL, PDIV, 12, 3) 62 FIELD(A2W_PLLx_CTRL, PWRDN, 16, 1) 63 FIELD(A2W_PLLx_CTRL, PRST_DISABLE, 17, 1) 64 REG32(A2W_PLLC_CTRL, 0x1120) 65 REG32(A2W_PLLD_CTRL, 0x1140) 66 REG32(A2W_PLLH_CTRL, 0x1160) 67 REG32(A2W_PLLB_CTRL, 0x11e0) 68 69 REG32(A2W_PLLA_ANA0, 0x1010) 70 REG32(A2W_PLLA_ANA1, 0x1014) 71 FIELD(A2W_PLLx_ANA1, FB_PREDIV, 14, 1) 72 REG32(A2W_PLLA_ANA2, 0x1018) 73 REG32(A2W_PLLA_ANA3, 0x101c) 74 75 REG32(A2W_PLLC_ANA0, 0x1030) 76 REG32(A2W_PLLC_ANA1, 0x1034) 77 REG32(A2W_PLLC_ANA2, 0x1038) 78 REG32(A2W_PLLC_ANA3, 0x103c) 79 80 REG32(A2W_PLLD_ANA0, 0x1050) 81 REG32(A2W_PLLD_ANA1, 0x1054) 82 REG32(A2W_PLLD_ANA2, 0x1058) 83 REG32(A2W_PLLD_ANA3, 0x105c) 84 85 REG32(A2W_PLLH_ANA0, 0x1070) 86 REG32(A2W_PLLH_ANA1, 0x1074) 87 FIELD(A2W_PLLH_ANA1, FB_PREDIV, 11, 1) 88 REG32(A2W_PLLH_ANA2, 0x1078) 89 REG32(A2W_PLLH_ANA3, 0x107c) 90 91 REG32(A2W_PLLB_ANA0, 0x10f0) 92 REG32(A2W_PLLB_ANA1, 0x10f4) 93 REG32(A2W_PLLB_ANA2, 0x10f8) 94 REG32(A2W_PLLB_ANA3, 0x10fc) 95 96 REG32(A2W_PLLA_FRAC, 0x1200) 97 FIELD(A2W_PLLx_FRAC, FRAC, 0, 20) 98 REG32(A2W_PLLC_FRAC, 0x1220) 99 REG32(A2W_PLLD_FRAC, 0x1240) 100 REG32(A2W_PLLH_FRAC, 0x1260) 101 REG32(A2W_PLLB_FRAC, 0x12e0) 102 103 /* misc registers */ 104 REG32(CM_LOCK, 0x114) 105 FIELD(CM_LOCK, FLOCKH, 12, 1) 106 FIELD(CM_LOCK, FLOCKD, 11, 1) 107 FIELD(CM_LOCK, FLOCKC, 10, 1) 108 FIELD(CM_LOCK, FLOCKB, 9, 1) 109 FIELD(CM_LOCK, FLOCKA, 8, 1) 110 111 /* 112 * This field is common to all registers. Each register write value must match 113 * the CPRMAN_PASSWORD magic value in its 8 MSB. 114 */ 115 FIELD(CPRMAN, PASSWORD, 24, 8) 116 #define CPRMAN_PASSWORD 0x5a 117 118 /* PLL init info */ 119 typedef struct PLLInitInfo { 120 const char *name; 121 size_t cm_offset; 122 size_t a2w_ctrl_offset; 123 size_t a2w_ana_offset; 124 uint32_t prediv_mask; /* Prediv bit in ana[1] */ 125 size_t a2w_frac_offset; 126 } PLLInitInfo; 127 128 #define FILL_PLL_INIT_INFO(pll_) \ 129 .cm_offset = R_CM_ ## pll_, \ 130 .a2w_ctrl_offset = R_A2W_ ## pll_ ## _CTRL, \ 131 .a2w_ana_offset = R_A2W_ ## pll_ ## _ANA0, \ 132 .a2w_frac_offset = R_A2W_ ## pll_ ## _FRAC 133 134 static const PLLInitInfo PLL_INIT_INFO[] = { 135 [CPRMAN_PLLA] = { 136 .name = "plla", 137 .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK, 138 FILL_PLL_INIT_INFO(PLLA), 139 }, 140 [CPRMAN_PLLC] = { 141 .name = "pllc", 142 .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK, 143 FILL_PLL_INIT_INFO(PLLC), 144 }, 145 [CPRMAN_PLLD] = { 146 .name = "plld", 147 .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK, 148 FILL_PLL_INIT_INFO(PLLD), 149 }, 150 [CPRMAN_PLLH] = { 151 .name = "pllh", 152 .prediv_mask = R_A2W_PLLH_ANA1_FB_PREDIV_MASK, 153 FILL_PLL_INIT_INFO(PLLH), 154 }, 155 [CPRMAN_PLLB] = { 156 .name = "pllb", 157 .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK, 158 FILL_PLL_INIT_INFO(PLLB), 159 }, 160 }; 161 162 #undef FILL_PLL_CHANNEL_INIT_INFO 163 164 static inline void set_pll_init_info(BCM2835CprmanState *s, 165 CprmanPllState *pll, 166 CprmanPll id) 167 { 168 pll->id = id; 169 pll->reg_cm = &s->regs[PLL_INIT_INFO[id].cm_offset]; 170 pll->reg_a2w_ctrl = &s->regs[PLL_INIT_INFO[id].a2w_ctrl_offset]; 171 pll->reg_a2w_ana = &s->regs[PLL_INIT_INFO[id].a2w_ana_offset]; 172 pll->prediv_mask = PLL_INIT_INFO[id].prediv_mask; 173 pll->reg_a2w_frac = &s->regs[PLL_INIT_INFO[id].a2w_frac_offset]; 174 } 175 176 #endif 177