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