1d6b55a0fSArnaud Minier /* 2d6b55a0fSArnaud Minier * STM32L4X5 RCC (Reset and clock control) 3d6b55a0fSArnaud Minier * 4d6b55a0fSArnaud Minier * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr> 5d6b55a0fSArnaud Minier * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr> 6d6b55a0fSArnaud Minier * 7d6b55a0fSArnaud Minier * SPDX-License-Identifier: GPL-2.0-or-later 8d6b55a0fSArnaud Minier * 9d6b55a0fSArnaud Minier * This work is licensed under the terms of the GNU GPL, version 2 or later. 10d6b55a0fSArnaud Minier * See the COPYING file in the top-level directory. 11d6b55a0fSArnaud Minier * 12d6b55a0fSArnaud Minier * The reference used is the STMicroElectronics RM0351 Reference manual 13d6b55a0fSArnaud Minier * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs. 14d6b55a0fSArnaud Minier * 15d6b55a0fSArnaud Minier * Inspired by the BCM2835 CPRMAN clock manager by Luc Michel. 16d6b55a0fSArnaud Minier */ 17d6b55a0fSArnaud Minier 18d6b55a0fSArnaud Minier #ifndef HW_STM32L4X5_RCC_H 19d6b55a0fSArnaud Minier #define HW_STM32L4X5_RCC_H 20d6b55a0fSArnaud Minier 21d6b55a0fSArnaud Minier #include "hw/sysbus.h" 22d6b55a0fSArnaud Minier #include "qom/object.h" 23d6b55a0fSArnaud Minier 24d6b55a0fSArnaud Minier #define TYPE_STM32L4X5_RCC "stm32l4x5-rcc" 25d6b55a0fSArnaud Minier OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5RccState, STM32L4X5_RCC) 26d6b55a0fSArnaud Minier 27d6b55a0fSArnaud Minier /* In the Stm32l4x5 clock tree, mux have at most 7 sources */ 28d6b55a0fSArnaud Minier #define RCC_NUM_CLOCK_MUX_SRC 7 29*6487653eSArnaud Minier 30*6487653eSArnaud Minier typedef enum PllCommonChannels { 31*6487653eSArnaud Minier RCC_PLL_COMMON_CHANNEL_P = 0, 32*6487653eSArnaud Minier RCC_PLL_COMMON_CHANNEL_Q = 1, 33*6487653eSArnaud Minier RCC_PLL_COMMON_CHANNEL_R = 2, 34*6487653eSArnaud Minier 35*6487653eSArnaud Minier RCC_NUM_CHANNEL_PLL_OUT = 3 36*6487653eSArnaud Minier } PllCommonChannels; 37*6487653eSArnaud Minier 38ec7d83acSArnaud Minier /* NB: Prescaler are assimilated to mux with one source and one output */ 39ec7d83acSArnaud Minier typedef enum RccClockMux { 40ec7d83acSArnaud Minier /* Internal muxes that arent't exposed publicly to other peripherals */ 41ec7d83acSArnaud Minier RCC_CLOCK_MUX_SYSCLK, 42ec7d83acSArnaud Minier RCC_CLOCK_MUX_PLL_INPUT, 43ec7d83acSArnaud Minier RCC_CLOCK_MUX_HCLK, 44ec7d83acSArnaud Minier RCC_CLOCK_MUX_PCLK1, 45ec7d83acSArnaud Minier RCC_CLOCK_MUX_PCLK2, 46ec7d83acSArnaud Minier RCC_CLOCK_MUX_HSE_OVER_32, 47ec7d83acSArnaud Minier RCC_CLOCK_MUX_LCD_AND_RTC_COMMON, 48ec7d83acSArnaud Minier 49ec7d83acSArnaud Minier /* Muxes with a publicly available output */ 50ec7d83acSArnaud Minier RCC_CLOCK_MUX_CORTEX_REFCLK, 51ec7d83acSArnaud Minier RCC_CLOCK_MUX_USART1, 52ec7d83acSArnaud Minier RCC_CLOCK_MUX_USART2, 53ec7d83acSArnaud Minier RCC_CLOCK_MUX_USART3, 54ec7d83acSArnaud Minier RCC_CLOCK_MUX_UART4, 55ec7d83acSArnaud Minier RCC_CLOCK_MUX_UART5, 56ec7d83acSArnaud Minier RCC_CLOCK_MUX_LPUART1, 57ec7d83acSArnaud Minier RCC_CLOCK_MUX_I2C1, 58ec7d83acSArnaud Minier RCC_CLOCK_MUX_I2C2, 59ec7d83acSArnaud Minier RCC_CLOCK_MUX_I2C3, 60ec7d83acSArnaud Minier RCC_CLOCK_MUX_LPTIM1, 61ec7d83acSArnaud Minier RCC_CLOCK_MUX_LPTIM2, 62ec7d83acSArnaud Minier RCC_CLOCK_MUX_SWPMI1, 63ec7d83acSArnaud Minier RCC_CLOCK_MUX_MCO, 64ec7d83acSArnaud Minier RCC_CLOCK_MUX_LSCO, 65ec7d83acSArnaud Minier RCC_CLOCK_MUX_DFSDM1, 66ec7d83acSArnaud Minier RCC_CLOCK_MUX_ADC, 67ec7d83acSArnaud Minier RCC_CLOCK_MUX_CLK48, 68ec7d83acSArnaud Minier RCC_CLOCK_MUX_SAI1, 69ec7d83acSArnaud Minier RCC_CLOCK_MUX_SAI2, 70ec7d83acSArnaud Minier 71ec7d83acSArnaud Minier /* 72ec7d83acSArnaud Minier * Mux that have only one input and one output assigned to as peripheral. 73ec7d83acSArnaud Minier * They could be direct lines but it is simpler 74ec7d83acSArnaud Minier * to use the same logic for all outputs. 75ec7d83acSArnaud Minier */ 76ec7d83acSArnaud Minier /* - AHB1 */ 77ec7d83acSArnaud Minier RCC_CLOCK_MUX_TSC, 78ec7d83acSArnaud Minier RCC_CLOCK_MUX_CRC, 79ec7d83acSArnaud Minier RCC_CLOCK_MUX_FLASH, 80ec7d83acSArnaud Minier RCC_CLOCK_MUX_DMA2, 81ec7d83acSArnaud Minier RCC_CLOCK_MUX_DMA1, 82ec7d83acSArnaud Minier 83ec7d83acSArnaud Minier /* - AHB2 */ 84ec7d83acSArnaud Minier RCC_CLOCK_MUX_RNG, 85ec7d83acSArnaud Minier RCC_CLOCK_MUX_AES, 86ec7d83acSArnaud Minier RCC_CLOCK_MUX_OTGFS, 87ec7d83acSArnaud Minier RCC_CLOCK_MUX_GPIOA, 88ec7d83acSArnaud Minier RCC_CLOCK_MUX_GPIOB, 89ec7d83acSArnaud Minier RCC_CLOCK_MUX_GPIOC, 90ec7d83acSArnaud Minier RCC_CLOCK_MUX_GPIOD, 91ec7d83acSArnaud Minier RCC_CLOCK_MUX_GPIOE, 92ec7d83acSArnaud Minier RCC_CLOCK_MUX_GPIOF, 93ec7d83acSArnaud Minier RCC_CLOCK_MUX_GPIOG, 94ec7d83acSArnaud Minier RCC_CLOCK_MUX_GPIOH, 95ec7d83acSArnaud Minier 96ec7d83acSArnaud Minier /* - AHB3 */ 97ec7d83acSArnaud Minier RCC_CLOCK_MUX_QSPI, 98ec7d83acSArnaud Minier RCC_CLOCK_MUX_FMC, 99ec7d83acSArnaud Minier 100ec7d83acSArnaud Minier /* - APB1 */ 101ec7d83acSArnaud Minier RCC_CLOCK_MUX_OPAMP, 102ec7d83acSArnaud Minier RCC_CLOCK_MUX_DAC1, 103ec7d83acSArnaud Minier RCC_CLOCK_MUX_PWR, 104ec7d83acSArnaud Minier RCC_CLOCK_MUX_CAN1, 105ec7d83acSArnaud Minier RCC_CLOCK_MUX_SPI3, 106ec7d83acSArnaud Minier RCC_CLOCK_MUX_SPI2, 107ec7d83acSArnaud Minier RCC_CLOCK_MUX_WWDG, 108ec7d83acSArnaud Minier RCC_CLOCK_MUX_LCD, 109ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM7, 110ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM6, 111ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM5, 112ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM4, 113ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM3, 114ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM2, 115ec7d83acSArnaud Minier 116ec7d83acSArnaud Minier /* - APB2 */ 117ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM17, 118ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM16, 119ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM15, 120ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM8, 121ec7d83acSArnaud Minier RCC_CLOCK_MUX_SPI1, 122ec7d83acSArnaud Minier RCC_CLOCK_MUX_TIM1, 123ec7d83acSArnaud Minier RCC_CLOCK_MUX_SDMMC1, 124ec7d83acSArnaud Minier RCC_CLOCK_MUX_FW, 125ec7d83acSArnaud Minier RCC_CLOCK_MUX_SYSCFG, 126ec7d83acSArnaud Minier 127ec7d83acSArnaud Minier /* - BDCR */ 128ec7d83acSArnaud Minier RCC_CLOCK_MUX_RTC, 129ec7d83acSArnaud Minier 130ec7d83acSArnaud Minier /* - OTHER */ 131ec7d83acSArnaud Minier RCC_CLOCK_MUX_CORTEX_FCLK, 132ec7d83acSArnaud Minier 133ec7d83acSArnaud Minier RCC_NUM_CLOCK_MUX 134ec7d83acSArnaud Minier } RccClockMux; 135ec7d83acSArnaud Minier 136*6487653eSArnaud Minier typedef enum RccPll { 137*6487653eSArnaud Minier RCC_PLL_PLL, 138*6487653eSArnaud Minier RCC_PLL_PLLSAI1, 139*6487653eSArnaud Minier RCC_PLL_PLLSAI2, 140*6487653eSArnaud Minier 141*6487653eSArnaud Minier RCC_NUM_PLL 142*6487653eSArnaud Minier } RccPll; 143*6487653eSArnaud Minier 144ec7d83acSArnaud Minier typedef struct RccClockMuxState { 145ec7d83acSArnaud Minier DeviceState parent_obj; 146ec7d83acSArnaud Minier 147ec7d83acSArnaud Minier RccClockMux id; 148ec7d83acSArnaud Minier Clock *srcs[RCC_NUM_CLOCK_MUX_SRC]; 149ec7d83acSArnaud Minier Clock *out; 150ec7d83acSArnaud Minier bool enabled; 151ec7d83acSArnaud Minier uint32_t src; 152ec7d83acSArnaud Minier uint32_t multiplier; 153ec7d83acSArnaud Minier uint32_t divider; 154ec7d83acSArnaud Minier 155ec7d83acSArnaud Minier /* 156ec7d83acSArnaud Minier * Used by clock srcs update callback to retrieve both the clock and the 157ec7d83acSArnaud Minier * source number. 158ec7d83acSArnaud Minier */ 159ec7d83acSArnaud Minier struct RccClockMuxState *backref[RCC_NUM_CLOCK_MUX_SRC]; 160ec7d83acSArnaud Minier } RccClockMuxState; 161ec7d83acSArnaud Minier 162*6487653eSArnaud Minier typedef struct RccPllState { 163*6487653eSArnaud Minier DeviceState parent_obj; 164*6487653eSArnaud Minier 165*6487653eSArnaud Minier RccPll id; 166*6487653eSArnaud Minier Clock *in; 167*6487653eSArnaud Minier uint32_t vco_multiplier; 168*6487653eSArnaud Minier Clock *channels[RCC_NUM_CHANNEL_PLL_OUT]; 169*6487653eSArnaud Minier /* Global pll enabled flag */ 170*6487653eSArnaud Minier bool enabled; 171*6487653eSArnaud Minier /* 'enabled' refers to the runtime configuration */ 172*6487653eSArnaud Minier bool channel_enabled[RCC_NUM_CHANNEL_PLL_OUT]; 173*6487653eSArnaud Minier /* 174*6487653eSArnaud Minier * 'exists' refers to the physical configuration 175*6487653eSArnaud Minier * It should only be set at pll initialization. 176*6487653eSArnaud Minier * e.g. pllsai2 doesn't have a Q output. 177*6487653eSArnaud Minier */ 178*6487653eSArnaud Minier bool channel_exists[RCC_NUM_CHANNEL_PLL_OUT]; 179*6487653eSArnaud Minier uint32_t channel_divider[RCC_NUM_CHANNEL_PLL_OUT]; 180*6487653eSArnaud Minier } RccPllState; 181*6487653eSArnaud Minier 182d6b55a0fSArnaud Minier struct Stm32l4x5RccState { 183d6b55a0fSArnaud Minier SysBusDevice parent_obj; 184d6b55a0fSArnaud Minier 185d6b55a0fSArnaud Minier MemoryRegion mmio; 186d6b55a0fSArnaud Minier 187d6b55a0fSArnaud Minier uint32_t cr; 188d6b55a0fSArnaud Minier uint32_t icscr; 189d6b55a0fSArnaud Minier uint32_t cfgr; 190d6b55a0fSArnaud Minier uint32_t pllcfgr; 191d6b55a0fSArnaud Minier uint32_t pllsai1cfgr; 192d6b55a0fSArnaud Minier uint32_t pllsai2cfgr; 193d6b55a0fSArnaud Minier uint32_t cier; 194d6b55a0fSArnaud Minier uint32_t cifr; 195d6b55a0fSArnaud Minier uint32_t ahb1rstr; 196d6b55a0fSArnaud Minier uint32_t ahb2rstr; 197d6b55a0fSArnaud Minier uint32_t ahb3rstr; 198d6b55a0fSArnaud Minier uint32_t apb1rstr1; 199d6b55a0fSArnaud Minier uint32_t apb1rstr2; 200d6b55a0fSArnaud Minier uint32_t apb2rstr; 201d6b55a0fSArnaud Minier uint32_t ahb1enr; 202d6b55a0fSArnaud Minier uint32_t ahb2enr; 203d6b55a0fSArnaud Minier uint32_t ahb3enr; 204d6b55a0fSArnaud Minier uint32_t apb1enr1; 205d6b55a0fSArnaud Minier uint32_t apb1enr2; 206d6b55a0fSArnaud Minier uint32_t apb2enr; 207d6b55a0fSArnaud Minier uint32_t ahb1smenr; 208d6b55a0fSArnaud Minier uint32_t ahb2smenr; 209d6b55a0fSArnaud Minier uint32_t ahb3smenr; 210d6b55a0fSArnaud Minier uint32_t apb1smenr1; 211d6b55a0fSArnaud Minier uint32_t apb1smenr2; 212d6b55a0fSArnaud Minier uint32_t apb2smenr; 213d6b55a0fSArnaud Minier uint32_t ccipr; 214d6b55a0fSArnaud Minier uint32_t bdcr; 215d6b55a0fSArnaud Minier uint32_t csr; 216d6b55a0fSArnaud Minier 217d6b55a0fSArnaud Minier /* Clock sources */ 218d6b55a0fSArnaud Minier Clock *gnd; 219d6b55a0fSArnaud Minier Clock *hsi16_rc; 220d6b55a0fSArnaud Minier Clock *msi_rc; 221d6b55a0fSArnaud Minier Clock *hse; 222d6b55a0fSArnaud Minier Clock *lsi_rc; 223d6b55a0fSArnaud Minier Clock *lse_crystal; 224d6b55a0fSArnaud Minier Clock *sai1_extclk; 225d6b55a0fSArnaud Minier Clock *sai2_extclk; 226d6b55a0fSArnaud Minier 227*6487653eSArnaud Minier /* PLLs */ 228*6487653eSArnaud Minier RccPllState plls[RCC_NUM_PLL]; 229*6487653eSArnaud Minier 230ec7d83acSArnaud Minier /* Muxes ~= outputs */ 231ec7d83acSArnaud Minier RccClockMuxState clock_muxes[RCC_NUM_CLOCK_MUX]; 232ec7d83acSArnaud Minier 233d6b55a0fSArnaud Minier qemu_irq irq; 234d6b55a0fSArnaud Minier uint64_t hse_frequency; 235d6b55a0fSArnaud Minier uint64_t sai1_extclk_frequency; 236d6b55a0fSArnaud Minier uint64_t sai2_extclk_frequency; 237d6b55a0fSArnaud Minier }; 238d6b55a0fSArnaud Minier 239d6b55a0fSArnaud Minier #endif /* HW_STM32L4X5_RCC_H */ 240