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