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