Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-25-v2' into staging
[qemu.git] / include / hw / misc / bcm2835_cprman.h
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_H
10 #define HW_MISC_CPRMAN_H
11
12 #include "hw/sysbus.h"
13 #include "hw/qdev-clock.h"
14
15 #define TYPE_BCM2835_CPRMAN "bcm2835-cprman"
16
17 typedef struct BCM2835CprmanState BCM2835CprmanState;
18
19 DECLARE_INSTANCE_CHECKER(BCM2835CprmanState, CPRMAN,
20 TYPE_BCM2835_CPRMAN)
21
22 #define CPRMAN_NUM_REGS (0x2000 / sizeof(uint32_t))
23
24 typedef enum CprmanPll {
25 CPRMAN_PLLA = 0,
26 CPRMAN_PLLC,
27 CPRMAN_PLLD,
28 CPRMAN_PLLH,
29 CPRMAN_PLLB,
30
31 CPRMAN_NUM_PLL
32 } CprmanPll;
33
34 typedef enum CprmanPllChannel {
35 CPRMAN_PLLA_CHANNEL_DSI0 = 0,
36 CPRMAN_PLLA_CHANNEL_CORE,
37 CPRMAN_PLLA_CHANNEL_PER,
38 CPRMAN_PLLA_CHANNEL_CCP2,
39
40 CPRMAN_PLLC_CHANNEL_CORE2,
41 CPRMAN_PLLC_CHANNEL_CORE1,
42 CPRMAN_PLLC_CHANNEL_PER,
43 CPRMAN_PLLC_CHANNEL_CORE0,
44
45 CPRMAN_PLLD_CHANNEL_DSI0,
46 CPRMAN_PLLD_CHANNEL_CORE,
47 CPRMAN_PLLD_CHANNEL_PER,
48 CPRMAN_PLLD_CHANNEL_DSI1,
49
50 CPRMAN_PLLH_CHANNEL_AUX,
51 CPRMAN_PLLH_CHANNEL_RCAL,
52 CPRMAN_PLLH_CHANNEL_PIX,
53
54 CPRMAN_PLLB_CHANNEL_ARM,
55
56 CPRMAN_NUM_PLL_CHANNEL,
57
58 /* Special values used when connecting clock sources to clocks */
59 CPRMAN_CLOCK_SRC_NORMAL = -1,
60 CPRMAN_CLOCK_SRC_FORCE_GROUND = -2,
61 CPRMAN_CLOCK_SRC_DSI0HSCK = -3,
62 } CprmanPllChannel;
63
64 typedef enum CprmanClockMux {
65 CPRMAN_CLOCK_GNRIC,
66 CPRMAN_CLOCK_VPU,
67 CPRMAN_CLOCK_SYS,
68 CPRMAN_CLOCK_PERIA,
69 CPRMAN_CLOCK_PERII,
70 CPRMAN_CLOCK_H264,
71 CPRMAN_CLOCK_ISP,
72 CPRMAN_CLOCK_V3D,
73 CPRMAN_CLOCK_CAM0,
74 CPRMAN_CLOCK_CAM1,
75 CPRMAN_CLOCK_CCP2,
76 CPRMAN_CLOCK_DSI0E,
77 CPRMAN_CLOCK_DSI0P,
78 CPRMAN_CLOCK_DPI,
79 CPRMAN_CLOCK_GP0,
80 CPRMAN_CLOCK_GP1,
81 CPRMAN_CLOCK_GP2,
82 CPRMAN_CLOCK_HSM,
83 CPRMAN_CLOCK_OTP,
84 CPRMAN_CLOCK_PCM,
85 CPRMAN_CLOCK_PWM,
86 CPRMAN_CLOCK_SLIM,
87 CPRMAN_CLOCK_SMI,
88 CPRMAN_CLOCK_TEC,
89 CPRMAN_CLOCK_TD0,
90 CPRMAN_CLOCK_TD1,
91 CPRMAN_CLOCK_TSENS,
92 CPRMAN_CLOCK_TIMER,
93 CPRMAN_CLOCK_UART,
94 CPRMAN_CLOCK_VEC,
95 CPRMAN_CLOCK_PULSE,
96 CPRMAN_CLOCK_SDC,
97 CPRMAN_CLOCK_ARM,
98 CPRMAN_CLOCK_AVEO,
99 CPRMAN_CLOCK_EMMC,
100 CPRMAN_CLOCK_EMMC2,
101
102 CPRMAN_NUM_CLOCK_MUX
103 } CprmanClockMux;
104
105 typedef enum CprmanClockMuxSource {
106 CPRMAN_CLOCK_SRC_GND = 0,
107 CPRMAN_CLOCK_SRC_XOSC,
108 CPRMAN_CLOCK_SRC_TD0,
109 CPRMAN_CLOCK_SRC_TD1,
110 CPRMAN_CLOCK_SRC_PLLA,
111 CPRMAN_CLOCK_SRC_PLLC,
112 CPRMAN_CLOCK_SRC_PLLD,
113 CPRMAN_CLOCK_SRC_PLLH,
114 CPRMAN_CLOCK_SRC_PLLC_CORE1,
115 CPRMAN_CLOCK_SRC_PLLC_CORE2,
116
117 CPRMAN_NUM_CLOCK_MUX_SRC
118 } CprmanClockMuxSource;
119
120 typedef struct CprmanPllState {
121 /*< private >*/
122 DeviceState parent_obj;
123
124 /*< public >*/
125 CprmanPll id;
126
127 uint32_t *reg_cm;
128 uint32_t *reg_a2w_ctrl;
129 uint32_t *reg_a2w_ana; /* ANA[0] .. ANA[3] */
130 uint32_t prediv_mask; /* prediv bit in ana[1] */
131 uint32_t *reg_a2w_frac;
132
133 Clock *xosc_in;
134 Clock *out;
135 } CprmanPllState;
136
137 typedef struct CprmanPllChannelState {
138 /*< private >*/
139 DeviceState parent_obj;
140
141 /*< public >*/
142 CprmanPllChannel id;
143 CprmanPll parent;
144
145 uint32_t *reg_cm;
146 uint32_t hold_mask;
147 uint32_t load_mask;
148 uint32_t *reg_a2w_ctrl;
149 int fixed_divider;
150
151 Clock *pll_in;
152 Clock *out;
153 } CprmanPllChannelState;
154
155 typedef struct CprmanClockMuxState {
156 /*< private >*/
157 DeviceState parent_obj;
158
159 /*< public >*/
160 CprmanClockMux id;
161
162 uint32_t *reg_ctl;
163 uint32_t *reg_div;
164 int int_bits;
165 int frac_bits;
166
167 Clock *srcs[CPRMAN_NUM_CLOCK_MUX_SRC];
168 Clock *out;
169
170 /*
171 * Used by clock srcs update callback to retrieve both the clock and the
172 * source number.
173 */
174 struct CprmanClockMuxState *backref[CPRMAN_NUM_CLOCK_MUX_SRC];
175 } CprmanClockMuxState;
176
177 typedef struct CprmanDsi0HsckMuxState {
178 /*< private >*/
179 DeviceState parent_obj;
180
181 /*< public >*/
182 CprmanClockMux id;
183
184 uint32_t *reg_cm;
185
186 Clock *plla_in;
187 Clock *plld_in;
188 Clock *out;
189 } CprmanDsi0HsckMuxState;
190
191 struct BCM2835CprmanState {
192 /*< private >*/
193 SysBusDevice parent_obj;
194
195 /*< public >*/
196 MemoryRegion iomem;
197
198 CprmanPllState plls[CPRMAN_NUM_PLL];
199 CprmanPllChannelState channels[CPRMAN_NUM_PLL_CHANNEL];
200 CprmanClockMuxState clock_muxes[CPRMAN_NUM_CLOCK_MUX];
201 CprmanDsi0HsckMuxState dsi0hsck_mux;
202
203 uint32_t regs[CPRMAN_NUM_REGS];
204 uint32_t xosc_freq;
205
206 Clock *xosc;
207 Clock *gnd;
208 };
209
210 #endif