xref: /qemu/include/hw/misc/bcm2835_cprman.h (revision a976a99a)
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_H
10 #define HW_MISC_BCM2835_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
211