xref: /qemu/include/hw/misc/bcm2835_cprman.h (revision 52581c71)
1fc14176bSLuc Michel /*
2fc14176bSLuc Michel  * BCM2835 CPRMAN clock manager
3fc14176bSLuc Michel  *
4fc14176bSLuc Michel  * Copyright (c) 2020 Luc Michel <luc@lmichel.fr>
5fc14176bSLuc Michel  *
6fc14176bSLuc Michel  * SPDX-License-Identifier: GPL-2.0-or-later
7fc14176bSLuc Michel  */
8fc14176bSLuc Michel 
952581c71SMarkus Armbruster #ifndef HW_MISC_BCM2835_CPRMAN_H
1052581c71SMarkus Armbruster #define HW_MISC_BCM2835_CPRMAN_H
11fc14176bSLuc Michel 
12fc14176bSLuc Michel #include "hw/sysbus.h"
13fc14176bSLuc Michel #include "hw/qdev-clock.h"
14fc14176bSLuc Michel 
15fc14176bSLuc Michel #define TYPE_BCM2835_CPRMAN "bcm2835-cprman"
16fc14176bSLuc Michel 
17fc14176bSLuc Michel typedef struct BCM2835CprmanState BCM2835CprmanState;
18fc14176bSLuc Michel 
19fc14176bSLuc Michel DECLARE_INSTANCE_CHECKER(BCM2835CprmanState, CPRMAN,
20fc14176bSLuc Michel                          TYPE_BCM2835_CPRMAN)
21fc14176bSLuc Michel 
22fc14176bSLuc Michel #define CPRMAN_NUM_REGS (0x2000 / sizeof(uint32_t))
23fc14176bSLuc Michel 
241e986e25SLuc Michel typedef enum CprmanPll {
251e986e25SLuc Michel     CPRMAN_PLLA = 0,
261e986e25SLuc Michel     CPRMAN_PLLC,
271e986e25SLuc Michel     CPRMAN_PLLD,
281e986e25SLuc Michel     CPRMAN_PLLH,
291e986e25SLuc Michel     CPRMAN_PLLB,
301e986e25SLuc Michel 
311e986e25SLuc Michel     CPRMAN_NUM_PLL
321e986e25SLuc Michel } CprmanPll;
331e986e25SLuc Michel 
3409d56bbcSLuc Michel typedef enum CprmanPllChannel {
3509d56bbcSLuc Michel     CPRMAN_PLLA_CHANNEL_DSI0 = 0,
3609d56bbcSLuc Michel     CPRMAN_PLLA_CHANNEL_CORE,
3709d56bbcSLuc Michel     CPRMAN_PLLA_CHANNEL_PER,
3809d56bbcSLuc Michel     CPRMAN_PLLA_CHANNEL_CCP2,
3909d56bbcSLuc Michel 
4009d56bbcSLuc Michel     CPRMAN_PLLC_CHANNEL_CORE2,
4109d56bbcSLuc Michel     CPRMAN_PLLC_CHANNEL_CORE1,
4209d56bbcSLuc Michel     CPRMAN_PLLC_CHANNEL_PER,
4309d56bbcSLuc Michel     CPRMAN_PLLC_CHANNEL_CORE0,
4409d56bbcSLuc Michel 
4509d56bbcSLuc Michel     CPRMAN_PLLD_CHANNEL_DSI0,
4609d56bbcSLuc Michel     CPRMAN_PLLD_CHANNEL_CORE,
4709d56bbcSLuc Michel     CPRMAN_PLLD_CHANNEL_PER,
4809d56bbcSLuc Michel     CPRMAN_PLLD_CHANNEL_DSI1,
4909d56bbcSLuc Michel 
5009d56bbcSLuc Michel     CPRMAN_PLLH_CHANNEL_AUX,
5109d56bbcSLuc Michel     CPRMAN_PLLH_CHANNEL_RCAL,
5209d56bbcSLuc Michel     CPRMAN_PLLH_CHANNEL_PIX,
5309d56bbcSLuc Michel 
5409d56bbcSLuc Michel     CPRMAN_PLLB_CHANNEL_ARM,
5509d56bbcSLuc Michel 
5609d56bbcSLuc Michel     CPRMAN_NUM_PLL_CHANNEL,
5772813624SLuc Michel 
5872813624SLuc Michel     /* Special values used when connecting clock sources to clocks */
5972813624SLuc Michel     CPRMAN_CLOCK_SRC_NORMAL = -1,
6072813624SLuc Michel     CPRMAN_CLOCK_SRC_FORCE_GROUND = -2,
6172813624SLuc Michel     CPRMAN_CLOCK_SRC_DSI0HSCK = -3,
6209d56bbcSLuc Michel } CprmanPllChannel;
6309d56bbcSLuc Michel 
6472813624SLuc Michel typedef enum CprmanClockMux {
6572813624SLuc Michel     CPRMAN_CLOCK_GNRIC,
6672813624SLuc Michel     CPRMAN_CLOCK_VPU,
6772813624SLuc Michel     CPRMAN_CLOCK_SYS,
6872813624SLuc Michel     CPRMAN_CLOCK_PERIA,
6972813624SLuc Michel     CPRMAN_CLOCK_PERII,
7072813624SLuc Michel     CPRMAN_CLOCK_H264,
7172813624SLuc Michel     CPRMAN_CLOCK_ISP,
7272813624SLuc Michel     CPRMAN_CLOCK_V3D,
7372813624SLuc Michel     CPRMAN_CLOCK_CAM0,
7472813624SLuc Michel     CPRMAN_CLOCK_CAM1,
7572813624SLuc Michel     CPRMAN_CLOCK_CCP2,
7672813624SLuc Michel     CPRMAN_CLOCK_DSI0E,
7772813624SLuc Michel     CPRMAN_CLOCK_DSI0P,
7872813624SLuc Michel     CPRMAN_CLOCK_DPI,
7972813624SLuc Michel     CPRMAN_CLOCK_GP0,
8072813624SLuc Michel     CPRMAN_CLOCK_GP1,
8172813624SLuc Michel     CPRMAN_CLOCK_GP2,
8272813624SLuc Michel     CPRMAN_CLOCK_HSM,
8372813624SLuc Michel     CPRMAN_CLOCK_OTP,
8472813624SLuc Michel     CPRMAN_CLOCK_PCM,
8572813624SLuc Michel     CPRMAN_CLOCK_PWM,
8672813624SLuc Michel     CPRMAN_CLOCK_SLIM,
8772813624SLuc Michel     CPRMAN_CLOCK_SMI,
8872813624SLuc Michel     CPRMAN_CLOCK_TEC,
8972813624SLuc Michel     CPRMAN_CLOCK_TD0,
9072813624SLuc Michel     CPRMAN_CLOCK_TD1,
9172813624SLuc Michel     CPRMAN_CLOCK_TSENS,
9272813624SLuc Michel     CPRMAN_CLOCK_TIMER,
9372813624SLuc Michel     CPRMAN_CLOCK_UART,
9472813624SLuc Michel     CPRMAN_CLOCK_VEC,
9572813624SLuc Michel     CPRMAN_CLOCK_PULSE,
9672813624SLuc Michel     CPRMAN_CLOCK_SDC,
9772813624SLuc Michel     CPRMAN_CLOCK_ARM,
9872813624SLuc Michel     CPRMAN_CLOCK_AVEO,
9972813624SLuc Michel     CPRMAN_CLOCK_EMMC,
10072813624SLuc Michel     CPRMAN_CLOCK_EMMC2,
10172813624SLuc Michel 
10272813624SLuc Michel     CPRMAN_NUM_CLOCK_MUX
10372813624SLuc Michel } CprmanClockMux;
10472813624SLuc Michel 
10572813624SLuc Michel typedef enum CprmanClockMuxSource {
10672813624SLuc Michel     CPRMAN_CLOCK_SRC_GND = 0,
10772813624SLuc Michel     CPRMAN_CLOCK_SRC_XOSC,
10872813624SLuc Michel     CPRMAN_CLOCK_SRC_TD0,
10972813624SLuc Michel     CPRMAN_CLOCK_SRC_TD1,
11072813624SLuc Michel     CPRMAN_CLOCK_SRC_PLLA,
11172813624SLuc Michel     CPRMAN_CLOCK_SRC_PLLC,
11272813624SLuc Michel     CPRMAN_CLOCK_SRC_PLLD,
11372813624SLuc Michel     CPRMAN_CLOCK_SRC_PLLH,
11472813624SLuc Michel     CPRMAN_CLOCK_SRC_PLLC_CORE1,
11572813624SLuc Michel     CPRMAN_CLOCK_SRC_PLLC_CORE2,
11672813624SLuc Michel 
11772813624SLuc Michel     CPRMAN_NUM_CLOCK_MUX_SRC
11872813624SLuc Michel } CprmanClockMuxSource;
11972813624SLuc Michel 
1201e986e25SLuc Michel typedef struct CprmanPllState {
1211e986e25SLuc Michel     /*< private >*/
1221e986e25SLuc Michel     DeviceState parent_obj;
1231e986e25SLuc Michel 
1241e986e25SLuc Michel     /*< public >*/
1251e986e25SLuc Michel     CprmanPll id;
1261e986e25SLuc Michel 
1271e986e25SLuc Michel     uint32_t *reg_cm;
1281e986e25SLuc Michel     uint32_t *reg_a2w_ctrl;
1291e986e25SLuc Michel     uint32_t *reg_a2w_ana; /* ANA[0] .. ANA[3] */
1301e986e25SLuc Michel     uint32_t prediv_mask; /* prediv bit in ana[1] */
1311e986e25SLuc Michel     uint32_t *reg_a2w_frac;
1321e986e25SLuc Michel 
1331e986e25SLuc Michel     Clock *xosc_in;
1341e986e25SLuc Michel     Clock *out;
1351e986e25SLuc Michel } CprmanPllState;
1361e986e25SLuc Michel 
13709d56bbcSLuc Michel typedef struct CprmanPllChannelState {
13809d56bbcSLuc Michel     /*< private >*/
13909d56bbcSLuc Michel     DeviceState parent_obj;
14009d56bbcSLuc Michel 
14109d56bbcSLuc Michel     /*< public >*/
14209d56bbcSLuc Michel     CprmanPllChannel id;
14309d56bbcSLuc Michel     CprmanPll parent;
14409d56bbcSLuc Michel 
14509d56bbcSLuc Michel     uint32_t *reg_cm;
14609d56bbcSLuc Michel     uint32_t hold_mask;
14709d56bbcSLuc Michel     uint32_t load_mask;
14809d56bbcSLuc Michel     uint32_t *reg_a2w_ctrl;
14909d56bbcSLuc Michel     int fixed_divider;
15009d56bbcSLuc Michel 
15109d56bbcSLuc Michel     Clock *pll_in;
15209d56bbcSLuc Michel     Clock *out;
15309d56bbcSLuc Michel } CprmanPllChannelState;
15409d56bbcSLuc Michel 
15572813624SLuc Michel typedef struct CprmanClockMuxState {
15672813624SLuc Michel     /*< private >*/
15772813624SLuc Michel     DeviceState parent_obj;
15872813624SLuc Michel 
15972813624SLuc Michel     /*< public >*/
16072813624SLuc Michel     CprmanClockMux id;
16172813624SLuc Michel 
16272813624SLuc Michel     uint32_t *reg_ctl;
16372813624SLuc Michel     uint32_t *reg_div;
16472813624SLuc Michel     int int_bits;
16572813624SLuc Michel     int frac_bits;
16672813624SLuc Michel 
16772813624SLuc Michel     Clock *srcs[CPRMAN_NUM_CLOCK_MUX_SRC];
16872813624SLuc Michel     Clock *out;
16972813624SLuc Michel 
17072813624SLuc Michel     /*
17172813624SLuc Michel      * Used by clock srcs update callback to retrieve both the clock and the
17272813624SLuc Michel      * source number.
17372813624SLuc Michel      */
17472813624SLuc Michel     struct CprmanClockMuxState *backref[CPRMAN_NUM_CLOCK_MUX_SRC];
17572813624SLuc Michel } CprmanClockMuxState;
17672813624SLuc Michel 
177502960caSLuc Michel typedef struct CprmanDsi0HsckMuxState {
178502960caSLuc Michel     /*< private >*/
179502960caSLuc Michel     DeviceState parent_obj;
180502960caSLuc Michel 
181502960caSLuc Michel     /*< public >*/
182502960caSLuc Michel     CprmanClockMux id;
183502960caSLuc Michel 
184502960caSLuc Michel     uint32_t *reg_cm;
185502960caSLuc Michel 
186502960caSLuc Michel     Clock *plla_in;
187502960caSLuc Michel     Clock *plld_in;
188502960caSLuc Michel     Clock *out;
189502960caSLuc Michel } CprmanDsi0HsckMuxState;
190502960caSLuc Michel 
191fc14176bSLuc Michel struct BCM2835CprmanState {
192fc14176bSLuc Michel     /*< private >*/
193fc14176bSLuc Michel     SysBusDevice parent_obj;
194fc14176bSLuc Michel 
195fc14176bSLuc Michel     /*< public >*/
196fc14176bSLuc Michel     MemoryRegion iomem;
197fc14176bSLuc Michel 
1981e986e25SLuc Michel     CprmanPllState plls[CPRMAN_NUM_PLL];
19909d56bbcSLuc Michel     CprmanPllChannelState channels[CPRMAN_NUM_PLL_CHANNEL];
20072813624SLuc Michel     CprmanClockMuxState clock_muxes[CPRMAN_NUM_CLOCK_MUX];
201502960caSLuc Michel     CprmanDsi0HsckMuxState dsi0hsck_mux;
2021e986e25SLuc Michel 
203fc14176bSLuc Michel     uint32_t regs[CPRMAN_NUM_REGS];
204fc14176bSLuc Michel     uint32_t xosc_freq;
205fc14176bSLuc Michel 
206fc14176bSLuc Michel     Clock *xosc;
20772813624SLuc Michel     Clock *gnd;
208fc14176bSLuc Michel };
209fc14176bSLuc Michel 
210fc14176bSLuc Michel #endif
211