xref: /openbmc/qemu/include/hw/misc/bcm2835_cprman.h (revision ec11dc41eec5142b4776db1296972c6323ba5847)
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