blob: fa59517f9bd64abbaf1542937a54116e2d27c3f5 [file] [log] [blame]
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001/*
2 * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <errno.h>
9#include <limits.h>
10#include <stdint.h>
11
12#include "clk-stm32-core.h"
13#include <common/fdt_wrappers.h>
14#include <drivers/clk.h>
15#include <drivers/delay_timer.h>
16#include <drivers/generic_delay_timer.h>
17#include <drivers/st/stm32mp2_clk.h>
18#include <drivers/st/stm32mp_clkfunc.h>
19#include <lib/mmio.h>
20#include <lib/spinlock.h>
21#include <lib/utils_def.h>
22#include <libfdt.h>
23
24#include <platform_def.h>
25
26struct stm32_osci_dt_cfg {
27 unsigned long freq;
28 uint32_t drive;
29 bool bypass;
30 bool digbyp;
31 bool css;
32};
33
34struct stm32_pll_dt_cfg {
35 uint32_t src;
36 uint32_t frac;
37 uint32_t cfg[PLLCFG_NB];
38 uint32_t csg[PLLCSG_NB];
39 bool csg_enabled;
40 bool enabled;
41};
42
43struct stm32_clk_platdata {
44 uintptr_t rcc_base;
45 uint32_t nosci;
46 struct stm32_osci_dt_cfg *osci;
47 uint32_t npll;
48 struct stm32_pll_dt_cfg *pll;
49 uint32_t nflexgen;
50 uint32_t *flexgen;
51 uint32_t nbusclk;
52 uint32_t *busclk;
53 uint32_t nkernelclk;
54 uint32_t *kernelclk;
55};
56
57/* A35 Sub-System which manages its own PLL (PLL1) */
58#define A35_SS_CHGCLKREQ 0x0000
59#define A35_SS_PLL_FREQ1 0x0080
60#define A35_SS_PLL_FREQ2 0x0090
61#define A35_SS_PLL_ENABLE 0x00a0
62
63#define A35_SS_CHGCLKREQ_ARM_CHGCLKREQ BIT(0)
64#define A35_SS_CHGCLKREQ_ARM_CHGCLKACK BIT(1)
65
66#define A35_SS_PLL_FREQ1_FBDIV_MASK GENMASK(11, 0)
67#define A35_SS_PLL_FREQ1_FBDIV_SHIFT 0
68#define A35_SS_PLL_FREQ1_REFDIV_MASK GENMASK(21, 16)
69#define A35_SS_PLL_FREQ1_REFDIV_SHIFT 16
70
71#define A35_SS_PLL_FREQ2_POSTDIV1_MASK GENMASK(2, 0)
72#define A35_SS_PLL_FREQ2_POSTDIV1_SHIFT 0
73#define A35_SS_PLL_FREQ2_POSTDIV2_MASK GENMASK(5, 3)
74#define A35_SS_PLL_FREQ2_POSTDIV2_SHIFT 3
75
76#define A35_SS_PLL_ENABLE_PD BIT(0)
77#define A35_SS_PLL_ENABLE_LOCKP BIT(1)
78#define A35_SS_PLL_ENABLE_NRESET_SWPLL_FF BIT(2)
79
80#define TIMEOUT_US_200MS U(200000)
81#define TIMEOUT_US_1S U(1000000)
82
83#define PLLRDY_TIMEOUT TIMEOUT_US_200MS
84#define CLKSRC_TIMEOUT TIMEOUT_US_200MS
85#define CLKDIV_TIMEOUT TIMEOUT_US_200MS
86#define OSCRDY_TIMEOUT TIMEOUT_US_1S
87
88/* PLL minimal frequencies for clock sources */
89#define PLL_REFCLK_MIN UL(5000000)
90#define PLL_FRAC_REFCLK_MIN UL(10000000)
91
92#define XBAR_CHANNEL_NB 64
93
94/* Warning, should be start to 1 */
95enum clock {
96 _CK_0_MHZ,
97
98 /* ROOT CLOCKS */
99 _CK_HSI,
100 _CK_HSE,
101 _CK_MSI,
102 _CK_LSI,
103 _CK_LSE,
104 _I2SCKIN,
105 _SPDIFSYMB,
106 _CK_PLL1,
107 _CK_PLL2,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200108#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200109 _CK_PLL3,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200110#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200111 _CK_PLL4,
112 _CK_PLL5,
113 _CK_PLL6,
114 _CK_PLL7,
115 _CK_PLL8,
116 _CK_HSE_RTC,
117 _CK_RTCCK,
118 _CK_ICN_HS_MCU,
119 _CK_ICN_SDMMC,
120 _CK_ICN_DDR,
121 _CK_ICN_HSL,
122 _CK_ICN_NIC,
123 _CK_ICN_LS_MCU,
124 _CK_FLEXGEN_07,
125 _CK_FLEXGEN_08,
126 _CK_FLEXGEN_09,
127 _CK_FLEXGEN_10,
128 _CK_FLEXGEN_11,
129 _CK_FLEXGEN_12,
130 _CK_FLEXGEN_13,
131 _CK_FLEXGEN_14,
132 _CK_FLEXGEN_15,
133 _CK_FLEXGEN_16,
134 _CK_FLEXGEN_17,
135 _CK_FLEXGEN_18,
136 _CK_FLEXGEN_19,
137 _CK_FLEXGEN_20,
138 _CK_FLEXGEN_21,
139 _CK_FLEXGEN_22,
140 _CK_FLEXGEN_23,
141 _CK_FLEXGEN_24,
142 _CK_FLEXGEN_25,
143 _CK_FLEXGEN_26,
144 _CK_FLEXGEN_27,
145 _CK_FLEXGEN_28,
146 _CK_FLEXGEN_29,
147 _CK_FLEXGEN_30,
148 _CK_FLEXGEN_31,
149 _CK_FLEXGEN_32,
150 _CK_FLEXGEN_33,
151 _CK_FLEXGEN_34,
152 _CK_FLEXGEN_35,
153 _CK_FLEXGEN_36,
154 _CK_FLEXGEN_37,
155 _CK_FLEXGEN_38,
156 _CK_FLEXGEN_39,
157 _CK_FLEXGEN_40,
158 _CK_FLEXGEN_41,
159 _CK_FLEXGEN_42,
160 _CK_FLEXGEN_43,
161 _CK_FLEXGEN_44,
162 _CK_FLEXGEN_45,
163 _CK_FLEXGEN_46,
164 _CK_FLEXGEN_47,
165 _CK_FLEXGEN_48,
166 _CK_FLEXGEN_49,
167 _CK_FLEXGEN_50,
168 _CK_FLEXGEN_51,
169 _CK_FLEXGEN_52,
170 _CK_FLEXGEN_53,
171 _CK_FLEXGEN_54,
172 _CK_FLEXGEN_55,
173 _CK_FLEXGEN_56,
174 _CK_FLEXGEN_57,
175 _CK_FLEXGEN_58,
176 _CK_FLEXGEN_59,
177 _CK_FLEXGEN_60,
178 _CK_FLEXGEN_61,
179 _CK_FLEXGEN_62,
180 _CK_FLEXGEN_63,
181 _CK_ICN_APB1,
182 _CK_ICN_APB2,
183 _CK_ICN_APB3,
184 _CK_ICN_APB4,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200185#if STM32MP21
186 _CK_ICN_APB5,
187#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200188 _CK_ICN_APBDBG,
189 _CK_BKPSRAM,
190 _CK_BSEC,
191 _CK_CRC,
192 _CK_CRYP1,
193 _CK_CRYP2,
194 _CK_DDR,
195 _CK_DDRCAPB,
196 _CK_DDRCP,
197 _CK_DDRPHYC,
198 _CK_FMC,
199 _CK_GPIOA,
200 _CK_GPIOB,
201 _CK_GPIOC,
202 _CK_GPIOD,
203 _CK_GPIOE,
204 _CK_GPIOF,
205 _CK_GPIOG,
206 _CK_GPIOH,
207 _CK_GPIOI,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200208#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200209 _CK_GPIOJ,
210 _CK_GPIOK,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200211#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200212 _CK_GPIOZ,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200213#if STM32MP21
214 _CK_HASH1,
215 _CK_HASH2,
216#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200217 _CK_HASH,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200218#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200219 _CK_I2C1,
220 _CK_I2C2,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200221#if !STM32MP23
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200222 _CK_I2C3,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200223#endif /* !STM32MP23 */
224#if STM32MP25
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200225 _CK_I2C4,
226 _CK_I2C5,
227 _CK_I2C6,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200228#endif /* STM32MP25 */
229#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200230 _CK_I2C7,
231 _CK_I2C8,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200232#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200233 _CK_IWDG1,
234 _CK_IWDG2,
235 _CK_OSPI1,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200236#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200237 _CK_OSPI2,
238 _CK_OSPIIOM,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200239#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200240 _CK_PKA,
241 _CK_RETRAM,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200242#if STM32MP21
243 _CK_RNG1,
244 _CK_RNG2,
245#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200246 _CK_RNG,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200247#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200248 _CK_RTC,
249 _CK_SAES,
250 _CK_SDMMC1,
251 _CK_SDMMC2,
252 _CK_SRAM1,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200253#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200254 _CK_SRAM2,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200255#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200256 _CK_STGEN,
257 _CK_SYSCPU1,
258 _CK_SYSRAM,
259 _CK_UART4,
260 _CK_UART5,
261 _CK_UART7,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200262#if STM32MP25
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200263 _CK_UART8,
264 _CK_UART9,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200265#endif /* STM32MP25 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200266 _CK_USART1,
267 _CK_USART2,
268 _CK_USART3,
269 _CK_USART6,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200270#if STM32MP21
271 _CK_USBHEHCI,
272 _CK_USBHOHCI,
273#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200274 _CK_USB2EHCI,
275 _CK_USB2OHCI,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200276#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200277 _CK_USB2PHY1,
278 _CK_USB2PHY2,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200279#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200280 _CK_USB3DR,
281 _CK_USB3PCIEPHY,
282 _CK_USBTC,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200283#endif /* !STM32MP21 */
Gabriel Fernandez2a20f3e2024-12-11 14:48:50 +0100284 _CK_BUS_RISAF4,
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200285
286 CK_LAST
287};
288
289static const uint16_t muxsel_src[] = {
290 _CK_HSI, _CK_HSE, _CK_MSI, _CK_0_MHZ
291};
292
293static const uint16_t xbarsel_src[] = {
294 _CK_PLL4, _CK_PLL5, _CK_PLL6, _CK_PLL7, _CK_PLL8,
295 _CK_HSI, _CK_HSE, _CK_MSI, _CK_HSI, _CK_HSE, _CK_MSI,
296 _SPDIFSYMB, _I2SCKIN, _CK_LSI, _CK_LSE
297};
298
299static const uint16_t rtc_src[] = {
300 _CK_0_MHZ, _CK_LSE, _CK_LSI, _CK_HSE_RTC
301};
302
303static const uint16_t usb2phy1_src[] = {
304 _CK_FLEXGEN_57, _CK_HSE
305};
306
307static const uint16_t usb2phy2_src[] = {
308 _CK_FLEXGEN_58, _CK_HSE
309};
310
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200311#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200312static const uint16_t usb3pciphy_src[] = {
313 _CK_FLEXGEN_34, _CK_HSE
314};
315
316static const uint16_t d3per_src[] = {
317 _CK_MSI, _CK_LSI, _CK_LSE
318};
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200319#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200320
321#define MUX_CONF(id, src, _offset, _shift, _witdh)[id] = {\
322 .id_parents = src,\
323 .num_parents = ARRAY_SIZE(src),\
324 .mux = &(struct mux_cfg) {\
325 .offset = (_offset),\
326 .shift = (_shift),\
327 .width = (_witdh),\
328 .bitrdy = UINT8_MAX,\
329 },\
330}
331
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200332static const struct parent_cfg parent_mp2[] = {
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200333 MUX_CONF(MUX_MUXSEL0, muxsel_src, RCC_MUXSELCFGR, 0, 2),
334 MUX_CONF(MUX_MUXSEL1, muxsel_src, RCC_MUXSELCFGR, 4, 2),
335 MUX_CONF(MUX_MUXSEL2, muxsel_src, RCC_MUXSELCFGR, 8, 2),
336 MUX_CONF(MUX_MUXSEL3, muxsel_src, RCC_MUXSELCFGR, 12, 2),
337 MUX_CONF(MUX_MUXSEL4, muxsel_src, RCC_MUXSELCFGR, 16, 2),
338 MUX_CONF(MUX_MUXSEL5, muxsel_src, RCC_MUXSELCFGR, 20, 2),
339 MUX_CONF(MUX_MUXSEL6, muxsel_src, RCC_MUXSELCFGR, 24, 2),
340 MUX_CONF(MUX_MUXSEL7, muxsel_src, RCC_MUXSELCFGR, 28, 2),
341 MUX_CONF(MUX_XBARSEL, xbarsel_src, RCC_XBAR0CFGR, 0, 4),
342 MUX_CONF(MUX_RTC, rtc_src, RCC_BDCR, 16, 2),
343 MUX_CONF(MUX_USB2PHY1, usb2phy1_src, RCC_USB2PHY1CFGR, 15, 1),
344 MUX_CONF(MUX_USB2PHY2, usb2phy2_src, RCC_USB2PHY2CFGR, 15, 1),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200345#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200346 MUX_CONF(MUX_USB3PCIEPHY, usb3pciphy_src, RCC_USB3PCIEPHYCFGR, 15, 1),
347 MUX_CONF(MUX_D3PER, d3per_src, RCC_D3DCR, 16, 2),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200348#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200349};
350
351/* GATES */
352enum enum_gate_cfg {
353 GATE_ZERO, /* reserved for no gate */
354 GATE_LSE,
355 GATE_RTCCK,
356 GATE_LSI,
357 GATE_HSI,
358 GATE_MSI,
359 GATE_HSE,
360 GATE_LSI_RDY,
361 GATE_MSI_RDY,
362 GATE_LSE_RDY,
363 GATE_HSE_RDY,
364 GATE_HSI_RDY,
365 GATE_SYSRAM,
366 GATE_RETRAM,
367 GATE_SRAM1,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200368#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200369 GATE_SRAM2,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200370#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200371
372 GATE_DDRPHYC,
373 GATE_SYSCPU1,
374 GATE_CRC,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200375#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200376 GATE_OSPIIOM,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200377#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200378 GATE_BKPSRAM,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200379#if STM32MP21
380 GATE_HASH1,
381 GATE_HASH2,
382 GATE_RNG1,
383 GATE_RNG2,
384#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200385 GATE_HASH,
386 GATE_RNG,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200387#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200388 GATE_CRYP1,
389 GATE_CRYP2,
390 GATE_SAES,
391 GATE_PKA,
392
393 GATE_GPIOA,
394 GATE_GPIOB,
395 GATE_GPIOC,
396 GATE_GPIOD,
397 GATE_GPIOE,
398 GATE_GPIOF,
399 GATE_GPIOG,
400 GATE_GPIOH,
401 GATE_GPIOI,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200402#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200403 GATE_GPIOJ,
404 GATE_GPIOK,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200405#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200406 GATE_GPIOZ,
407 GATE_RTC,
408
409 GATE_DDRCP,
410
411 /* WARNING 2 CLOCKS FOR ONE GATE */
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200412#if STM32MP21
413 GATE_USBHOHCI,
414 GATE_USBHEHCI,
415#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200416 GATE_USB2OHCI,
417 GATE_USB2EHCI,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200418#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200419
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200420#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200421 GATE_USB3DR,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200422#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200423
424 GATE_BSEC,
425 GATE_IWDG1,
426 GATE_IWDG2,
427
428 GATE_DDRCAPB,
429 GATE_DDR,
430
431 GATE_USART2,
432 GATE_UART4,
433 GATE_USART3,
434 GATE_UART5,
435 GATE_I2C1,
436 GATE_I2C2,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200437#if !STM32MP23
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200438 GATE_I2C3,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200439#endif /* !STM32MP23 */
440#if STM32MP25
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200441 GATE_I2C5,
442 GATE_I2C4,
443 GATE_I2C6,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200444#endif /* STM32MP25 */
445#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200446 GATE_I2C7,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200447#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200448 GATE_USART1,
449 GATE_USART6,
450 GATE_UART7,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200451#if STM32MP25
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200452 GATE_UART8,
453 GATE_UART9,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200454#endif /* STM32MP25 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200455 GATE_STGEN,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200456#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200457 GATE_USB3PCIEPHY,
458 GATE_USBTC,
459 GATE_I2C8,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200460#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200461 GATE_OSPI1,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200462#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200463 GATE_OSPI2,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200464#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200465 GATE_FMC,
466 GATE_SDMMC1,
467 GATE_SDMMC2,
468 GATE_USB2PHY1,
469 GATE_USB2PHY2,
470 LAST_GATE
471};
472
473#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\
474 .offset = (_offset),\
475 .bit_idx = (_bit_idx),\
476 .set_clr = (_offset_clr),\
477}
478
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200479static const struct gate_cfg gates_mp2[LAST_GATE] = {
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200480 GATE_CFG(GATE_LSE, RCC_BDCR, 0, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200481#if STM32MP21
482 GATE_CFG(GATE_LSI, RCC_LSICR, 0, 0),
483#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200484 GATE_CFG(GATE_LSI, RCC_BDCR, 9, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200485#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200486 GATE_CFG(GATE_RTCCK, RCC_BDCR, 20, 0),
487 GATE_CFG(GATE_HSI, RCC_OCENSETR, 0, 1),
488 GATE_CFG(GATE_HSE, RCC_OCENSETR, 8, 1),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200489#if STM32MP21
490 GATE_CFG(GATE_MSI, RCC_OCENSETR, 2, 0),
491#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200492 GATE_CFG(GATE_MSI, RCC_D3DCR, 0, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200493#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200494
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200495#if STM32MP21
496 GATE_CFG(GATE_LSI_RDY, RCC_LSICR, 1, 0),
497#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200498 GATE_CFG(GATE_LSI_RDY, RCC_BDCR, 10, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200499#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200500 GATE_CFG(GATE_LSE_RDY, RCC_BDCR, 2, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200501#if STM32MP21
502 GATE_CFG(GATE_MSI_RDY, RCC_OCRDYR, 2, 0),
503#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200504 GATE_CFG(GATE_MSI_RDY, RCC_D3DCR, 2, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200505#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200506 GATE_CFG(GATE_HSE_RDY, RCC_OCRDYR, 8, 0),
507 GATE_CFG(GATE_HSI_RDY, RCC_OCRDYR, 0, 0),
508 GATE_CFG(GATE_SYSRAM, RCC_SYSRAMCFGR, 1, 0),
509 GATE_CFG(GATE_RETRAM, RCC_RETRAMCFGR, 1, 0),
510 GATE_CFG(GATE_SRAM1, RCC_SRAM1CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200511#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200512 GATE_CFG(GATE_SRAM2, RCC_SRAM2CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200513#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200514 GATE_CFG(GATE_DDRPHYC, RCC_DDRPHYCAPBCFGR, 1, 0),
515 GATE_CFG(GATE_SYSCPU1, RCC_SYSCPU1CFGR, 1, 0),
516 GATE_CFG(GATE_CRC, RCC_CRCCFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200517#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200518 GATE_CFG(GATE_OSPIIOM, RCC_OSPIIOMCFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200519#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200520 GATE_CFG(GATE_BKPSRAM, RCC_BKPSRAMCFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200521#if STM32MP21
522 GATE_CFG(GATE_HASH1, RCC_HASH1CFGR, 1, 0),
523 GATE_CFG(GATE_HASH2, RCC_HASH2CFGR, 1, 0),
524 GATE_CFG(GATE_RNG1, RCC_RNG1CFGR, 1, 0),
525 GATE_CFG(GATE_RNG2, RCC_RNG2CFGR, 1, 0),
526#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200527 GATE_CFG(GATE_HASH, RCC_HASHCFGR, 1, 0),
528 GATE_CFG(GATE_RNG, RCC_RNGCFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200529#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200530 GATE_CFG(GATE_CRYP1, RCC_CRYP1CFGR, 1, 0),
531 GATE_CFG(GATE_CRYP2, RCC_CRYP2CFGR, 1, 0),
532 GATE_CFG(GATE_SAES, RCC_SAESCFGR, 1, 0),
533 GATE_CFG(GATE_PKA, RCC_PKACFGR, 1, 0),
534 GATE_CFG(GATE_GPIOA, RCC_GPIOACFGR, 1, 0),
535 GATE_CFG(GATE_GPIOB, RCC_GPIOBCFGR, 1, 0),
536 GATE_CFG(GATE_GPIOC, RCC_GPIOCCFGR, 1, 0),
537 GATE_CFG(GATE_GPIOD, RCC_GPIODCFGR, 1, 0),
538 GATE_CFG(GATE_GPIOE, RCC_GPIOECFGR, 1, 0),
539 GATE_CFG(GATE_GPIOF, RCC_GPIOFCFGR, 1, 0),
540 GATE_CFG(GATE_GPIOG, RCC_GPIOGCFGR, 1, 0),
541 GATE_CFG(GATE_GPIOH, RCC_GPIOHCFGR, 1, 0),
542 GATE_CFG(GATE_GPIOI, RCC_GPIOICFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200543#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200544 GATE_CFG(GATE_GPIOJ, RCC_GPIOJCFGR, 1, 0),
545 GATE_CFG(GATE_GPIOK, RCC_GPIOKCFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200546#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200547 GATE_CFG(GATE_GPIOZ, RCC_GPIOZCFGR, 1, 0),
548 GATE_CFG(GATE_RTC, RCC_RTCCFGR, 1, 0),
549 GATE_CFG(GATE_DDRCP, RCC_DDRCPCFGR, 1, 0),
550
551 /* WARNING 2 CLOCKS FOR ONE GATE */
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200552#if STM32MP21
553 GATE_CFG(GATE_USBHOHCI, RCC_USBHCFGR, 1, 0),
554 GATE_CFG(GATE_USBHEHCI, RCC_USBHCFGR, 1, 0),
555#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200556 GATE_CFG(GATE_USB2OHCI, RCC_USB2CFGR, 1, 0),
557 GATE_CFG(GATE_USB2EHCI, RCC_USB2CFGR, 1, 0),
558 GATE_CFG(GATE_USB3DR, RCC_USB3DRCFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200559#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200560 GATE_CFG(GATE_BSEC, RCC_BSECCFGR, 1, 0),
561 GATE_CFG(GATE_IWDG1, RCC_IWDG1CFGR, 1, 0),
562 GATE_CFG(GATE_IWDG2, RCC_IWDG2CFGR, 1, 0),
563 GATE_CFG(GATE_DDRCAPB, RCC_DDRCAPBCFGR, 1, 0),
564 GATE_CFG(GATE_DDR, RCC_DDRCFGR, 1, 0),
565 GATE_CFG(GATE_USART2, RCC_USART2CFGR, 1, 0),
566 GATE_CFG(GATE_UART4, RCC_UART4CFGR, 1, 0),
567 GATE_CFG(GATE_USART3, RCC_USART3CFGR, 1, 0),
568 GATE_CFG(GATE_UART5, RCC_UART5CFGR, 1, 0),
569 GATE_CFG(GATE_I2C1, RCC_I2C1CFGR, 1, 0),
570 GATE_CFG(GATE_I2C2, RCC_I2C2CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200571#if !STM32MP23
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200572 GATE_CFG(GATE_I2C3, RCC_I2C3CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200573#endif /* !STM32MP23 */
574#if STM32MP25
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200575 GATE_CFG(GATE_I2C5, RCC_I2C5CFGR, 1, 0),
576 GATE_CFG(GATE_I2C4, RCC_I2C4CFGR, 1, 0),
577 GATE_CFG(GATE_I2C6, RCC_I2C6CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200578#endif /* STM32MP25 */
579#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200580 GATE_CFG(GATE_I2C7, RCC_I2C7CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200581#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200582 GATE_CFG(GATE_USART1, RCC_USART1CFGR, 1, 0),
583 GATE_CFG(GATE_USART6, RCC_USART6CFGR, 1, 0),
584 GATE_CFG(GATE_UART7, RCC_UART7CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200585#if STM32MP25
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200586 GATE_CFG(GATE_UART8, RCC_UART8CFGR, 1, 0),
587 GATE_CFG(GATE_UART9, RCC_UART9CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200588#endif /* STM32MP25 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200589 GATE_CFG(GATE_STGEN, RCC_STGENCFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200590#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200591 GATE_CFG(GATE_USB3PCIEPHY, RCC_USB3PCIEPHYCFGR, 1, 0),
592 GATE_CFG(GATE_USBTC, RCC_USBTCCFGR, 1, 0),
593 GATE_CFG(GATE_I2C8, RCC_I2C8CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200594#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200595 GATE_CFG(GATE_OSPI1, RCC_OSPI1CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200596#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200597 GATE_CFG(GATE_OSPI2, RCC_OSPI2CFGR, 1, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200598#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200599 GATE_CFG(GATE_FMC, RCC_FMCCFGR, 1, 0),
600 GATE_CFG(GATE_SDMMC1, RCC_SDMMC1CFGR, 1, 0),
601 GATE_CFG(GATE_SDMMC2, RCC_SDMMC2CFGR, 1, 0),
602 GATE_CFG(GATE_USB2PHY1, RCC_USB2PHY1CFGR, 1, 0),
603 GATE_CFG(GATE_USB2PHY2, RCC_USB2PHY2CFGR, 1, 0),
604};
605
606static const struct clk_div_table apb_div_table[] = {
607 { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, { 4, 16 },
608 { 5, 16 }, { 6, 16 }, { 7, 16 }, { 0 },
609};
610
611#undef DIV_CFG
612#define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\
613 .offset = _offset,\
614 .shift = _shift,\
615 .width = _width,\
616 .flags = _flags,\
617 .table = _table,\
618 .bitrdy = _bitrdy,\
619}
620
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200621static const struct div_cfg dividers_mp2[] = {
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200622 DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31),
623 DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31),
624 DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31),
625 DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200626#if STM32MP21
627 DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, 31),
628#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200629 DIV_CFG(DIV_APBDBG, RCC_APBDBGDIVR, 0, 3, 0, apb_div_table, 31),
630 DIV_CFG(DIV_LSMCU, RCC_LSMCUDIVR, 0, 1, 0, NULL, 31),
631 DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, 0),
632};
633
634enum stm32_osc {
635 OSC_HSI,
636 OSC_HSE,
637 OSC_MSI,
638 OSC_LSI,
639 OSC_LSE,
640 OSC_I2SCKIN,
641 OSC_SPDIFSYMB,
642 NB_OSCILLATOR
643};
644
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200645static struct clk_oscillator_data stm32mp2_osc_data[] = {
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200646 OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY,
647 NULL, NULL, NULL),
648
649 OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY,
650 NULL, NULL, NULL),
651
652 OSCILLATOR(OSC_MSI, _CK_MSI, "clk-msi", GATE_MSI, GATE_MSI_RDY,
653 NULL, NULL, NULL),
654
655 OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY,
656 BYPASS(RCC_OCENSETR, 10, 7),
657 CSS(RCC_OCENSETR, 11),
658 NULL),
659
660 OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY,
661 BYPASS(RCC_BDCR, 1, 3),
662 CSS(RCC_BDCR, 8),
663 DRIVE(RCC_BDCR, 4, 2, 2)),
664
665 OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE,
666 NULL, NULL, NULL),
667
668 OSCILLATOR(OSC_SPDIFSYMB, _SPDIFSYMB, "spdif_symb", NO_GATE, NO_GATE,
669 NULL, NULL, NULL),
670};
671
672#ifdef IMAGE_BL2
673static const char *clk_stm32_get_oscillator_name(enum stm32_osc id)
674{
675 if (id < NB_OSCILLATOR) {
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200676 return stm32mp2_osc_data[id].name;
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200677 }
678
679 return NULL;
680}
681#endif
682
683enum pll_id {
684 _PLL1,
685 _PLL2,
686 _PLL3,
687 _PLL4,
688 _PLL5,
689 _PLL6,
690 _PLL7,
691 _PLL8,
692 _PLL_NB
693};
694
695/* PLL configuration registers offsets from RCC_PLLxCFGR1 */
696#define RCC_OFFSET_PLLXCFGR1 0x00
697#define RCC_OFFSET_PLLXCFGR2 0x04
698#define RCC_OFFSET_PLLXCFGR3 0x08
699#define RCC_OFFSET_PLLXCFGR4 0x0C
700#define RCC_OFFSET_PLLXCFGR5 0x10
701#define RCC_OFFSET_PLLXCFGR6 0x18
702#define RCC_OFFSET_PLLXCFGR7 0x1C
703
704struct stm32_clk_pll {
705 uint16_t clk_id;
706 uint16_t reg_pllxcfgr1;
707};
708
709#define CLK_PLL_CFG(_idx, _clk_id, _reg)\
710 [(_idx)] = {\
711 .clk_id = (_clk_id),\
712 .reg_pllxcfgr1 = (_reg),\
713 }
714
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200715static const struct stm32_clk_pll stm32mp2_clk_pll[_PLL_NB] = {
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200716 CLK_PLL_CFG(_PLL1, _CK_PLL1, A35_SS_CHGCLKREQ),
717 CLK_PLL_CFG(_PLL2, _CK_PLL2, RCC_PLL2CFGR1),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200718#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200719 CLK_PLL_CFG(_PLL3, _CK_PLL3, RCC_PLL3CFGR1),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200720#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200721 CLK_PLL_CFG(_PLL4, _CK_PLL4, RCC_PLL4CFGR1),
722 CLK_PLL_CFG(_PLL5, _CK_PLL5, RCC_PLL5CFGR1),
723 CLK_PLL_CFG(_PLL6, _CK_PLL6, RCC_PLL6CFGR1),
724 CLK_PLL_CFG(_PLL7, _CK_PLL7, RCC_PLL7CFGR1),
725 CLK_PLL_CFG(_PLL8, _CK_PLL8, RCC_PLL8CFGR1),
726};
727
728static const struct stm32_clk_pll *clk_stm32_pll_data(unsigned int idx)
729{
Nicolas Le Bayon088238a2023-09-29 16:50:37 +0200730 return &stm32mp2_clk_pll[idx];
Gabriel Fernandez615f31f2022-04-20 10:08:49 +0200731}
732
733static unsigned long clk_get_pll_fvco(struct stm32_clk_priv *priv,
734 const struct stm32_clk_pll *pll,
735 unsigned long prate)
736{
737 unsigned long refclk, fvco;
738 uint32_t fracin, fbdiv, refdiv;
739 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
740 uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2;
741 uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
742
743 refclk = prate;
744
745 fracin = mmio_read_32(pllxcfgr3) & RCC_PLLxCFGR3_FRACIN_MASK;
746 fbdiv = (mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FBDIV_MASK) >>
747 RCC_PLLxCFGR2_FBDIV_SHIFT;
748 refdiv = mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FREFDIV_MASK;
749
750 if (fracin != 0U) {
751 uint64_t numerator, denominator;
752
753 numerator = ((uint64_t)fbdiv << 24) + fracin;
754 numerator = refclk * numerator;
755 denominator = (uint64_t)refdiv << 24;
756 fvco = (unsigned long)(numerator / denominator);
757 } else {
758 fvco = (unsigned long)(refclk * fbdiv / refdiv);
759 }
760
761 return fvco;
762}
763
764struct stm32_pll_cfg {
765 uint16_t pll_id;
766};
767
768static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
769{
770 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
771
772 return ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLEN) != 0U);
773}
774
775static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
776{
777 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
778
779 mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
780}
781
782static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
783{
784 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
785
786 /* Stop PLL */
787 mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
788}
789
790static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv,
791 const struct stm32_clk_pll *pll)
792{
793 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
794 uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
795
796 /* Wait PLL lock */
797 while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) == 0U) {
798 if (timeout_elapsed(timeout)) {
799 ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
800 pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcfgr1,
801 mmio_read_32(pllxcfgr1));
802 return -ETIMEDOUT;
803 }
804 }
805
806 return 0;
807}
808
809static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv,
810 const struct stm32_clk_pll *pll)
811{
812 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
813 uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
814
815 /* Wait PLL stopped */
816 while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) != 0U) {
817 if (timeout_elapsed(timeout)) {
818 ERROR("PLL%d stop failed @ 0x%lx: 0x%x\n",
819 pll->clk_id - _CK_PLL1 + 1, pllxcfgr1, mmio_read_32(pllxcfgr1));
820 return -ETIMEDOUT;
821 }
822 }
823
824 return 0;
825}
826
827static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
828{
829 if (_clk_stm32_pll_is_enabled(priv, pll)) {
830 return 0;
831 }
832
833 _clk_stm32_pll_set_on(priv, pll);
834
835 return _clk_stm32_pll_wait_ready_on(priv, pll);
836}
837
838static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
839{
840 if (!_clk_stm32_pll_is_enabled(priv, pll)) {
841 return;
842 }
843
844 _clk_stm32_pll_set_off(priv, pll);
845
846 _clk_stm32_pll_wait_ready_off(priv, pll);
847}
848
849static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id)
850{
851 const struct clk_stm32 *clk = _clk_get(priv, id);
852 struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
853 const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
854
855 return _clk_stm32_pll_is_enabled(priv, pll);
856}
857
858static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id)
859{
860 const struct clk_stm32 *clk = _clk_get(priv, id);
861 struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
862 const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
863
864 return _clk_stm32_pll_enable(priv, pll);
865}
866
867static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id)
868{
869 const struct clk_stm32 *clk = _clk_get(priv, id);
870 struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
871 const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
872
873 _clk_stm32_pll_disable(priv, pll);
874}
875
876static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id,
877 unsigned long prate)
878{
879 const struct clk_stm32 *clk = _clk_get(priv, id);
880 struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
881 const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
882 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
883 uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
884 uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6;
885 uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7;
886 unsigned long dfout;
887 uint32_t postdiv1, postdiv2;
888
889 postdiv1 = mmio_read_32(pllxcfgr6) & RCC_PLLxCFGR6_POSTDIV1_MASK;
890 postdiv2 = mmio_read_32(pllxcfgr7) & RCC_PLLxCFGR7_POSTDIV2_MASK;
891
892 if ((mmio_read_32(pllxcfgr4) & RCC_PLLxCFGR4_BYPASS) != 0U) {
893 dfout = prate;
894 } else {
895 if ((postdiv1 == 0U) || (postdiv2 == 0U)) {
896 dfout = prate;
897 } else {
898 dfout = clk_get_pll_fvco(priv, pll, prate) / (postdiv1 * postdiv2);
899 }
900 }
901
902 return dfout;
903}
904
905static const struct stm32_clk_ops clk_stm32_pll_ops = {
906 .recalc_rate = clk_stm32_pll_recalc_rate,
907 .enable = clk_stm32_pll_enable,
908 .disable = clk_stm32_pll_disable,
909 .is_enabled = clk_stm32_pll_is_enabled,
910};
911
912#define CLK_PLL(idx, _idx, _parent, _pll_id, _flags)[idx] = {\
913 .binding = _idx,\
914 .parent = _parent,\
915 .flags = (_flags),\
916 .clock_cfg = &(struct stm32_pll_cfg) {\
917 .pll_id = _pll_id,\
918 },\
919 .ops = STM32_PLL_OPS,\
920}
921
922static unsigned long clk_get_pll1_fvco(unsigned long refclk)
923{
924 uintptr_t pll_freq1_reg = A35SSC_BASE + A35_SS_PLL_FREQ1;
925 uint32_t reg, fbdiv, refdiv;
926
927 reg = mmio_read_32(pll_freq1_reg);
928
929 fbdiv = (reg & A35_SS_PLL_FREQ1_FBDIV_MASK) >> A35_SS_PLL_FREQ1_FBDIV_SHIFT;
930 refdiv = (reg & A35_SS_PLL_FREQ1_REFDIV_MASK) >> A35_SS_PLL_FREQ1_REFDIV_SHIFT;
931
932 return (unsigned long)(refclk * fbdiv / refdiv);
933}
934
935static unsigned long clk_stm32_pll1_recalc_rate(struct stm32_clk_priv *priv,
936 int id, unsigned long prate)
937{
938 uintptr_t pll_freq2_reg = A35SSC_BASE + A35_SS_PLL_FREQ2;
939 uint32_t postdiv1, postdiv2;
940 unsigned long dfout;
941
942 postdiv1 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV1_MASK) >>
943 A35_SS_PLL_FREQ2_POSTDIV1_SHIFT;
944 postdiv2 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV2_MASK) >>
945 A35_SS_PLL_FREQ2_POSTDIV2_SHIFT;
946
947 if ((postdiv1 == 0U) || (postdiv2 == 0U)) {
948 dfout = prate;
949 } else {
950 dfout = clk_get_pll1_fvco(prate) / (postdiv1 * postdiv2);
951 }
952
953 return dfout;
954}
955
956static const struct stm32_clk_ops clk_stm32_pll1_ops = {
957 .recalc_rate = clk_stm32_pll1_recalc_rate,
958};
959
960#define CLK_PLL1(idx, _idx, _parent, _pll_id, _flags)[idx] = {\
961 .binding = _idx,\
962 .parent = _parent,\
963 .flags = (_flags),\
964 .clock_cfg = &(struct stm32_pll_cfg) {\
965 .pll_id = _pll_id,\
966 },\
967 .ops = STM32_PLL1_OPS,\
968}
969
970struct stm32_clk_flexgen_cfg {
971 uint8_t id;
972};
973
974static unsigned long clk_flexgen_recalc(struct stm32_clk_priv *priv, int idx,
975 unsigned long prate)
976{
977 const struct clk_stm32 *clk = _clk_get(priv, idx);
978 struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
979 uintptr_t rcc_base = priv->base;
980 uint32_t prediv, findiv;
981 uint8_t channel = cfg->id;
982 unsigned long freq = prate;
983
984 prediv = mmio_read_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel)) &
985 RCC_PREDIVxCFGR_PREDIVx_MASK;
986 findiv = mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) &
987 RCC_FINDIVxCFGR_FINDIVx_MASK;
988
989 if (freq == 0UL) {
990 return 0U;
991 }
992
993 switch (prediv) {
994 case 0x0:
995 case 0x1:
996 case 0x3:
997 case 0x3FF:
998 break;
999
1000 default:
1001 ERROR("Unsupported PREDIV value (%x)\n", prediv);
1002 panic();
1003 break;
1004 }
1005
1006 freq /= (prediv + 1U);
1007 freq /= (findiv + 1U);
1008
1009 return freq;
1010}
1011
1012static int clk_flexgen_get_parent(struct stm32_clk_priv *priv, int idx)
1013{
1014 const struct clk_stm32 *clk = _clk_get(priv, idx);
1015 struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
1016 uint32_t sel;
1017 uint32_t address;
1018 uintptr_t rcc_base = priv->base;
1019
1020 address = RCC_XBAR0CFGR + (cfg->id * 4);
1021
1022 sel = mmio_read_32(rcc_base + address) & RCC_XBARxCFGR_XBARxSEL_MASK;
1023
1024 return sel;
1025}
1026
1027static int clk_flexgen_gate_enable(struct stm32_clk_priv *priv, int idx)
1028{
1029 const struct clk_stm32 *clk = _clk_get(priv, idx);
1030 struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
1031 uintptr_t rcc_base = priv->base;
1032 uint8_t channel = cfg->id;
1033
1034 mmio_setbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
1035 RCC_FINDIVxCFGR_FINDIVxEN);
1036
1037 return 0;
1038}
1039
1040static void clk_flexgen_gate_disable(struct stm32_clk_priv *priv, int id)
1041{
1042 const struct clk_stm32 *clk = _clk_get(priv, id);
1043 struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
1044 uintptr_t rcc_base = priv->base;
1045 uint8_t channel = cfg->id;
1046
1047 mmio_clrbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
1048 RCC_FINDIVxCFGR_FINDIVxEN);
1049}
1050
1051static bool clk_flexgen_gate_is_enabled(struct stm32_clk_priv *priv, int id)
1052{
1053 const struct clk_stm32 *clk = _clk_get(priv, id);
1054 struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
1055 uintptr_t rcc_base = priv->base;
1056 uint8_t channel = cfg->id;
1057
1058 return !!(mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) &
1059 RCC_FINDIVxCFGR_FINDIVxEN);
1060}
1061
1062static const struct stm32_clk_ops clk_stm32_flexgen_ops = {
1063 .recalc_rate = clk_flexgen_recalc,
1064 .get_parent = clk_flexgen_get_parent,
1065 .enable = clk_flexgen_gate_enable,
1066 .disable = clk_flexgen_gate_disable,
1067 .is_enabled = clk_flexgen_gate_is_enabled,
1068};
1069
1070#define FLEXGEN(idx, _idx, _flags, _id)[idx] = {\
1071 .binding = _idx,\
1072 .parent = MUX(MUX_XBARSEL),\
1073 .flags = (_flags),\
1074 .clock_cfg = &(struct stm32_clk_flexgen_cfg) {\
1075 .id = _id,\
1076 },\
1077 .ops = STM32_FLEXGEN_OPS,\
1078}
1079
1080#define RCC_0_MHZ UL(0)
1081#define RCC_4_MHZ UL(4000000)
1082#define RCC_16_MHZ UL(16000000)
1083
1084#ifdef IMAGE_BL2
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001085#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001086static int clk_stm32_osc_msi_set_rate(struct stm32_clk_priv *priv, int id, unsigned long rate,
1087 unsigned long prate)
1088{
1089 uintptr_t address = priv->base + RCC_BDCR;
1090 uint32_t mask = RCC_BDCR_MSIFREQSEL;
1091 int ret = -1;
1092
1093 switch (rate) {
1094 case RCC_4_MHZ:
1095 mmio_clrbits_32(address, mask);
1096 ret = 0;
1097 break;
1098
1099 case RCC_16_MHZ:
1100 mmio_setbits_32(address, mask);
1101 ret = 0;
1102 break;
1103
1104 default:
1105 break;
1106 }
1107
1108 return ret;
1109}
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001110#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001111#endif /* IMAGE_BL2 */
1112
1113static unsigned long clk_stm32_osc_msi_recalc_rate(struct stm32_clk_priv *priv,
1114 int id __unused,
1115 unsigned long prate __unused)
1116{
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001117#if STM32MP21
1118 return RCC_16_MHZ;
1119#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001120 uintptr_t address = priv->base + RCC_BDCR;
1121
1122 if ((mmio_read_32(address) & RCC_BDCR_MSIFREQSEL) == 0U) {
1123 return RCC_4_MHZ;
1124 } else {
1125 return RCC_16_MHZ;
1126 }
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001127#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001128}
1129
1130static const struct stm32_clk_ops clk_stm32_osc_msi_ops = {
1131 .recalc_rate = clk_stm32_osc_msi_recalc_rate,
1132 .is_enabled = clk_stm32_osc_gate_is_enabled,
1133 .enable = clk_stm32_osc_gate_enable,
1134 .disable = clk_stm32_osc_gate_disable,
1135 .init = clk_stm32_osc_init,
1136};
1137
1138#define CLK_OSC_MSI(idx, _idx, _parent, _osc_id) \
1139 [(idx)] = (struct clk_stm32){ \
1140 .binding = (_idx),\
1141 .parent = (_parent),\
1142 .flags = CLK_IS_CRITICAL,\
1143 .clock_cfg = &(struct stm32_osc_cfg){\
1144 .osc_id = (_osc_id),\
1145 },\
1146 .ops = STM32_OSC_MSI_OPS,\
1147 }
1148
1149static const struct stm32_clk_ops clk_stm32_rtc_ops = {
1150 .enable = clk_stm32_gate_enable,
1151 .disable = clk_stm32_gate_disable,
1152 .is_enabled = clk_stm32_gate_is_enabled,
1153};
1154
1155#define CLK_RTC(idx, _binding, _parent, _flags, _gate_id)[idx] = {\
1156 .binding = (_binding),\
1157 .parent = (_parent),\
1158 .flags = (_flags),\
1159 .clock_cfg = &(struct clk_stm32_gate_cfg) {\
1160 .id = (_gate_id),\
1161 },\
1162 .ops = STM32_RTC_OPS,\
1163}
1164
1165enum {
1166 STM32_PLL_OPS = STM32_LAST_OPS,
1167 STM32_PLL1_OPS,
1168 STM32_FLEXGEN_OPS,
1169 STM32_OSC_MSI_OPS,
1170 STM32_RTC_OPS,
1171
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001172 MP2_LAST_OPS
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001173};
1174
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001175static const struct stm32_clk_ops *ops_array_mp2[MP2_LAST_OPS] = {
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001176 [NO_OPS] = NULL,
1177 [FIXED_FACTOR_OPS] = &clk_fixed_factor_ops,
1178 [GATE_OPS] = &clk_gate_ops,
1179 [STM32_MUX_OPS] = &clk_mux_ops,
1180 [STM32_DIVIDER_OPS] = &clk_stm32_divider_ops,
1181 [STM32_GATE_OPS] = &clk_stm32_gate_ops,
1182 [STM32_TIMER_OPS] = &clk_timer_ops,
1183 [STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops,
1184 [STM32_OSC_OPS] = &clk_stm32_osc_ops,
1185 [STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops,
1186
1187 [STM32_PLL_OPS] = &clk_stm32_pll_ops,
1188 [STM32_PLL1_OPS] = &clk_stm32_pll1_ops,
1189 [STM32_FLEXGEN_OPS] = &clk_stm32_flexgen_ops,
1190 [STM32_OSC_MSI_OPS] = &clk_stm32_osc_msi_ops,
1191 [STM32_RTC_OPS] = &clk_stm32_rtc_ops
1192};
1193
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001194static const struct clk_stm32 stm32mp2_clk[CK_LAST] = {
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001195 CLK_FIXED_RATE(_CK_0_MHZ, _NO_ID, RCC_0_MHZ),
1196
1197 /* ROOT CLOCKS */
1198 CLK_OSC(_CK_HSE, HSE_CK, CLK_IS_ROOT, OSC_HSE),
1199 CLK_OSC(_CK_LSE, LSE_CK, CLK_IS_ROOT, OSC_LSE),
1200 CLK_OSC(_CK_HSI, HSI_CK, CLK_IS_ROOT, OSC_HSI),
1201 CLK_OSC(_CK_LSI, LSI_CK, CLK_IS_ROOT, OSC_LSI),
1202 CLK_OSC_MSI(_CK_MSI, MSI_CK, CLK_IS_ROOT, OSC_MSI),
1203
1204 CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN),
1205 CLK_OSC_FIXED(_SPDIFSYMB, _NO_ID, CLK_IS_ROOT, OSC_SPDIFSYMB),
1206
1207 STM32_DIV(_CK_HSE_RTC, _NO_ID, _CK_HSE, 0, DIV_RTC),
1208
1209 CLK_RTC(_CK_RTCCK, RTC_CK, MUX(MUX_RTC), 0, GATE_RTCCK),
1210
1211 CLK_PLL1(_CK_PLL1, PLL1_CK, MUX(MUX_MUXSEL5), _PLL1, 0),
1212
1213 CLK_PLL(_CK_PLL2, PLL2_CK, MUX(MUX_MUXSEL6), _PLL2, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001214#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001215 CLK_PLL(_CK_PLL3, PLL3_CK, MUX(MUX_MUXSEL7), _PLL3, 0),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001216#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001217 CLK_PLL(_CK_PLL4, PLL4_CK, MUX(MUX_MUXSEL0), _PLL4, 0),
1218 CLK_PLL(_CK_PLL5, PLL5_CK, MUX(MUX_MUXSEL1), _PLL5, 0),
1219 CLK_PLL(_CK_PLL6, PLL6_CK, MUX(MUX_MUXSEL2), _PLL6, 0),
1220 CLK_PLL(_CK_PLL7, PLL7_CK, MUX(MUX_MUXSEL3), _PLL7, 0),
1221 CLK_PLL(_CK_PLL8, PLL8_CK, MUX(MUX_MUXSEL4), _PLL8, 0),
1222
1223 FLEXGEN(_CK_ICN_HS_MCU, CK_ICN_HS_MCU, CLK_IS_CRITICAL, 0),
1224 FLEXGEN(_CK_ICN_SDMMC, CK_ICN_SDMMC, CLK_IS_CRITICAL, 1),
1225 FLEXGEN(_CK_ICN_DDR, CK_ICN_DDR, CLK_IS_CRITICAL, 2),
1226 FLEXGEN(_CK_ICN_HSL, CK_ICN_HSL, CLK_IS_CRITICAL, 4),
1227 FLEXGEN(_CK_ICN_NIC, CK_ICN_NIC, CLK_IS_CRITICAL, 5),
1228
1229 STM32_DIV(_CK_ICN_LS_MCU, CK_ICN_LS_MCU, _CK_ICN_HS_MCU, 0, DIV_LSMCU),
1230
1231 FLEXGEN(_CK_FLEXGEN_07, CK_FLEXGEN_07, 0, 7),
1232 FLEXGEN(_CK_FLEXGEN_08, CK_FLEXGEN_08, 0, 8),
1233 FLEXGEN(_CK_FLEXGEN_09, CK_FLEXGEN_09, 0, 9),
1234 FLEXGEN(_CK_FLEXGEN_10, CK_FLEXGEN_10, 0, 10),
1235 FLEXGEN(_CK_FLEXGEN_11, CK_FLEXGEN_11, 0, 11),
1236 FLEXGEN(_CK_FLEXGEN_12, CK_FLEXGEN_12, 0, 12),
1237 FLEXGEN(_CK_FLEXGEN_13, CK_FLEXGEN_13, 0, 13),
1238 FLEXGEN(_CK_FLEXGEN_14, CK_FLEXGEN_14, 0, 14),
1239 FLEXGEN(_CK_FLEXGEN_15, CK_FLEXGEN_15, 0, 15),
1240 FLEXGEN(_CK_FLEXGEN_16, CK_FLEXGEN_16, 0, 16),
1241 FLEXGEN(_CK_FLEXGEN_17, CK_FLEXGEN_17, 0, 17),
1242 FLEXGEN(_CK_FLEXGEN_18, CK_FLEXGEN_18, 0, 18),
1243 FLEXGEN(_CK_FLEXGEN_19, CK_FLEXGEN_19, 0, 19),
1244 FLEXGEN(_CK_FLEXGEN_20, CK_FLEXGEN_20, 0, 20),
1245 FLEXGEN(_CK_FLEXGEN_21, CK_FLEXGEN_21, 0, 21),
1246 FLEXGEN(_CK_FLEXGEN_22, CK_FLEXGEN_22, 0, 22),
1247 FLEXGEN(_CK_FLEXGEN_23, CK_FLEXGEN_23, 0, 23),
1248 FLEXGEN(_CK_FLEXGEN_24, CK_FLEXGEN_24, 0, 24),
1249 FLEXGEN(_CK_FLEXGEN_25, CK_FLEXGEN_25, 0, 25),
1250 FLEXGEN(_CK_FLEXGEN_26, CK_FLEXGEN_26, 0, 26),
1251 FLEXGEN(_CK_FLEXGEN_27, CK_FLEXGEN_27, 0, 27),
1252 FLEXGEN(_CK_FLEXGEN_28, CK_FLEXGEN_28, 0, 28),
1253 FLEXGEN(_CK_FLEXGEN_29, CK_FLEXGEN_29, 0, 29),
1254 FLEXGEN(_CK_FLEXGEN_30, CK_FLEXGEN_30, 0, 30),
1255 FLEXGEN(_CK_FLEXGEN_31, CK_FLEXGEN_31, 0, 31),
1256 FLEXGEN(_CK_FLEXGEN_32, CK_FLEXGEN_32, 0, 32),
1257 FLEXGEN(_CK_FLEXGEN_33, CK_FLEXGEN_33, 0, 33),
1258 FLEXGEN(_CK_FLEXGEN_34, CK_FLEXGEN_34, 0, 34),
1259 FLEXGEN(_CK_FLEXGEN_35, CK_FLEXGEN_35, 0, 35),
1260 FLEXGEN(_CK_FLEXGEN_36, CK_FLEXGEN_36, 0, 36),
1261 FLEXGEN(_CK_FLEXGEN_37, CK_FLEXGEN_37, 0, 37),
1262 FLEXGEN(_CK_FLEXGEN_38, CK_FLEXGEN_38, 0, 38),
1263 FLEXGEN(_CK_FLEXGEN_39, CK_FLEXGEN_39, 0, 39),
1264 FLEXGEN(_CK_FLEXGEN_40, CK_FLEXGEN_40, 0, 40),
1265 FLEXGEN(_CK_FLEXGEN_41, CK_FLEXGEN_41, 0, 41),
1266 FLEXGEN(_CK_FLEXGEN_42, CK_FLEXGEN_42, 0, 42),
1267 FLEXGEN(_CK_FLEXGEN_43, CK_FLEXGEN_43, 0, 43),
1268 FLEXGEN(_CK_FLEXGEN_44, CK_FLEXGEN_44, 0, 44),
1269 FLEXGEN(_CK_FLEXGEN_45, CK_FLEXGEN_45, 0, 45),
1270 FLEXGEN(_CK_FLEXGEN_46, CK_FLEXGEN_46, 0, 46),
1271 FLEXGEN(_CK_FLEXGEN_47, CK_FLEXGEN_47, 0, 47),
1272 FLEXGEN(_CK_FLEXGEN_48, CK_FLEXGEN_48, 0, 48),
1273 FLEXGEN(_CK_FLEXGEN_49, CK_FLEXGEN_49, 0, 49),
1274 FLEXGEN(_CK_FLEXGEN_50, CK_FLEXGEN_50, 0, 50),
1275 FLEXGEN(_CK_FLEXGEN_51, CK_FLEXGEN_51, 0, 51),
1276 FLEXGEN(_CK_FLEXGEN_52, CK_FLEXGEN_52, 0, 52),
1277 FLEXGEN(_CK_FLEXGEN_53, CK_FLEXGEN_53, 0, 53),
1278 FLEXGEN(_CK_FLEXGEN_54, CK_FLEXGEN_54, 0, 54),
1279 FLEXGEN(_CK_FLEXGEN_55, CK_FLEXGEN_55, 0, 55),
1280 FLEXGEN(_CK_FLEXGEN_56, CK_FLEXGEN_56, 0, 56),
1281 FLEXGEN(_CK_FLEXGEN_57, CK_FLEXGEN_57, 0, 57),
1282 FLEXGEN(_CK_FLEXGEN_58, CK_FLEXGEN_58, 0, 58),
1283 FLEXGEN(_CK_FLEXGEN_59, CK_FLEXGEN_59, 0, 59),
1284 FLEXGEN(_CK_FLEXGEN_60, CK_FLEXGEN_60, 0, 60),
1285 FLEXGEN(_CK_FLEXGEN_61, CK_FLEXGEN_61, 0, 61),
1286 FLEXGEN(_CK_FLEXGEN_62, CK_FLEXGEN_62, 0, 62),
1287 FLEXGEN(_CK_FLEXGEN_63, CK_FLEXGEN_63, 0, 63),
1288
1289 STM32_DIV(_CK_ICN_APB1, CK_ICN_APB1, _CK_ICN_LS_MCU, 0, DIV_APB1),
1290 STM32_DIV(_CK_ICN_APB2, CK_ICN_APB2, _CK_ICN_LS_MCU, 0, DIV_APB2),
1291 STM32_DIV(_CK_ICN_APB3, CK_ICN_APB3, _CK_ICN_LS_MCU, 0, DIV_APB3),
1292 STM32_DIV(_CK_ICN_APB4, CK_ICN_APB4, _CK_ICN_LS_MCU, 0, DIV_APB4),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001293#if STM32MP21
1294 STM32_DIV(_CK_ICN_APB5, CK_ICN_APB5, _CK_ICN_LS_MCU, 0, DIV_APB5),
1295#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001296 STM32_DIV(_CK_ICN_APBDBG, CK_ICN_APBDBG, _CK_ICN_LS_MCU, 0, DIV_APBDBG),
1297
1298 /* KERNEL CLOCK */
1299 STM32_GATE(_CK_SYSRAM, CK_BUS_SYSRAM, _CK_ICN_HS_MCU, 0, GATE_SYSRAM),
1300 STM32_GATE(_CK_RETRAM, CK_BUS_RETRAM, _CK_ICN_HS_MCU, 0, GATE_RETRAM),
1301 STM32_GATE(_CK_SRAM1, CK_BUS_SRAM1, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM1),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001302#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001303 STM32_GATE(_CK_SRAM2, CK_BUS_SRAM2, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM2),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001304#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001305
1306 STM32_GATE(_CK_DDRPHYC, CK_BUS_DDRPHYC, _CK_ICN_LS_MCU, 0, GATE_DDRPHYC),
1307 STM32_GATE(_CK_SYSCPU1, CK_BUS_SYSCPU1, _CK_ICN_LS_MCU, 0, GATE_SYSCPU1),
1308 STM32_GATE(_CK_CRC, CK_BUS_CRC, _CK_ICN_LS_MCU, 0, GATE_CRC),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001309#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001310 STM32_GATE(_CK_OSPIIOM, CK_BUS_OSPIIOM, _CK_ICN_LS_MCU, 0, GATE_OSPIIOM),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001311#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001312 STM32_GATE(_CK_BKPSRAM, CK_BUS_BKPSRAM, _CK_ICN_LS_MCU, 0, GATE_BKPSRAM),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001313#if STM32MP21
1314 STM32_GATE(_CK_HASH1, CK_BUS_HASH1, _CK_ICN_LS_MCU, 0, GATE_HASH1),
1315 STM32_GATE(_CK_HASH2, CK_BUS_HASH2, _CK_ICN_LS_MCU, 0, GATE_HASH2),
1316 STM32_GATE(_CK_RNG1, CK_BUS_RNG1, _CK_ICN_LS_MCU, 0, GATE_RNG1),
1317 STM32_GATE(_CK_RNG2, CK_BUS_RNG2, _CK_ICN_LS_MCU, 0, GATE_RNG2),
1318#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001319 STM32_GATE(_CK_HASH, CK_BUS_HASH, _CK_ICN_LS_MCU, 0, GATE_HASH),
1320 STM32_GATE(_CK_RNG, CK_BUS_RNG, _CK_ICN_LS_MCU, 0, GATE_RNG),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001321#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001322 STM32_GATE(_CK_CRYP1, CK_BUS_CRYP1, _CK_ICN_LS_MCU, 0, GATE_CRYP1),
1323 STM32_GATE(_CK_CRYP2, CK_BUS_CRYP2, _CK_ICN_LS_MCU, 0, GATE_CRYP2),
1324 STM32_GATE(_CK_SAES, CK_BUS_SAES, _CK_ICN_LS_MCU, 0, GATE_SAES),
1325 STM32_GATE(_CK_PKA, CK_BUS_PKA, _CK_ICN_LS_MCU, 0, GATE_PKA),
1326
1327 STM32_GATE(_CK_GPIOA, CK_BUS_GPIOA, _CK_ICN_LS_MCU, 0, GATE_GPIOA),
1328 STM32_GATE(_CK_GPIOB, CK_BUS_GPIOB, _CK_ICN_LS_MCU, 0, GATE_GPIOB),
1329 STM32_GATE(_CK_GPIOC, CK_BUS_GPIOC, _CK_ICN_LS_MCU, 0, GATE_GPIOC),
1330 STM32_GATE(_CK_GPIOD, CK_BUS_GPIOD, _CK_ICN_LS_MCU, 0, GATE_GPIOD),
1331 STM32_GATE(_CK_GPIOE, CK_BUS_GPIOE, _CK_ICN_LS_MCU, 0, GATE_GPIOE),
1332 STM32_GATE(_CK_GPIOF, CK_BUS_GPIOF, _CK_ICN_LS_MCU, 0, GATE_GPIOF),
1333 STM32_GATE(_CK_GPIOG, CK_BUS_GPIOG, _CK_ICN_LS_MCU, 0, GATE_GPIOG),
1334 STM32_GATE(_CK_GPIOH, CK_BUS_GPIOH, _CK_ICN_LS_MCU, 0, GATE_GPIOH),
1335 STM32_GATE(_CK_GPIOI, CK_BUS_GPIOI, _CK_ICN_LS_MCU, 0, GATE_GPIOI),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001336#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001337 STM32_GATE(_CK_GPIOJ, CK_BUS_GPIOJ, _CK_ICN_LS_MCU, 0, GATE_GPIOJ),
1338 STM32_GATE(_CK_GPIOK, CK_BUS_GPIOK, _CK_ICN_LS_MCU, 0, GATE_GPIOK),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001339#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001340 STM32_GATE(_CK_GPIOZ, CK_BUS_GPIOZ, _CK_ICN_LS_MCU, 0, GATE_GPIOZ),
1341 STM32_GATE(_CK_RTC, CK_BUS_RTC, _CK_ICN_LS_MCU, 0, GATE_RTC),
1342
Gabriel Fernandez2a20f3e2024-12-11 14:48:50 +01001343 STM32_GATE(_CK_BUS_RISAF4, CK_BUS_RISAF4, _CK_ICN_LS_MCU, CLK_IS_CRITICAL, GATE_DDRCP),
1344 STM32_GATE(_CK_DDRCP, CK_BUS_DDR, _CK_ICN_DDR, CLK_IS_CRITICAL, GATE_DDRCP),
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001345
1346 /* WARNING 2 CLOCKS FOR ONE GATE */
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001347#if STM32MP21
1348 STM32_GATE(_CK_USBHOHCI, CK_BUS_USBHOHCI, _CK_ICN_HSL, 0, GATE_USBHOHCI),
1349 STM32_GATE(_CK_USBHEHCI, CK_BUS_USBHEHCI, _CK_ICN_HSL, 0, GATE_USBHEHCI),
1350#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001351 STM32_GATE(_CK_USB2OHCI, CK_BUS_USB2OHCI, _CK_ICN_HSL, 0, GATE_USB2OHCI),
1352 STM32_GATE(_CK_USB2EHCI, CK_BUS_USB2EHCI, _CK_ICN_HSL, 0, GATE_USB2EHCI),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001353#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001354
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001355#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001356 STM32_GATE(_CK_USB3DR, CK_BUS_USB3DR, _CK_ICN_HSL, 0, GATE_USB3DR),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001357#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001358
1359 STM32_GATE(_CK_BSEC, CK_BUS_BSEC, _CK_ICN_APB3, 0, GATE_BSEC),
1360 STM32_GATE(_CK_IWDG1, CK_BUS_IWDG1, _CK_ICN_APB3, 0, GATE_IWDG1),
1361 STM32_GATE(_CK_IWDG2, CK_BUS_IWDG2, _CK_ICN_APB3, 0, GATE_IWDG2),
1362
1363 STM32_GATE(_CK_DDRCAPB, CK_BUS_DDRC, _CK_ICN_APB4, 0, GATE_DDRCAPB),
1364 STM32_GATE(_CK_DDR, CK_BUS_DDRCFG, _CK_ICN_APB4, 0, GATE_DDR),
1365
1366 STM32_GATE(_CK_USART2, CK_KER_USART2, _CK_FLEXGEN_08, 0, GATE_USART2),
1367 STM32_GATE(_CK_UART4, CK_KER_UART4, _CK_FLEXGEN_08, 0, GATE_UART4),
1368 STM32_GATE(_CK_USART3, CK_KER_USART3, _CK_FLEXGEN_09, 0, GATE_USART3),
1369 STM32_GATE(_CK_UART5, CK_KER_UART5, _CK_FLEXGEN_09, 0, GATE_UART5),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001370#if STM32MP21
1371 STM32_GATE(_CK_I2C1, CK_KER_I2C1, _CK_FLEXGEN_13, 0, GATE_I2C1),
1372 STM32_GATE(_CK_I2C2, CK_KER_I2C2, _CK_FLEXGEN_13, 0, GATE_I2C2),
1373 STM32_GATE(_CK_USART1, CK_KER_USART1, _CK_FLEXGEN_18, 0, GATE_USART1),
1374 STM32_GATE(_CK_USART6, CK_KER_USART6, _CK_FLEXGEN_19, 0, GATE_USART6),
1375 STM32_GATE(_CK_UART7, CK_KER_UART7, _CK_FLEXGEN_20, 0, GATE_UART7),
1376 STM32_GATE(_CK_I2C3, CK_KER_I2C3, _CK_FLEXGEN_38, 0, GATE_I2C3),
1377#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001378 STM32_GATE(_CK_I2C1, CK_KER_I2C1, _CK_FLEXGEN_12, 0, GATE_I2C1),
1379 STM32_GATE(_CK_I2C2, CK_KER_I2C2, _CK_FLEXGEN_12, 0, GATE_I2C2),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001380#if STM32MP25
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001381 STM32_GATE(_CK_I2C3, CK_KER_I2C3, _CK_FLEXGEN_13, 0, GATE_I2C3),
1382 STM32_GATE(_CK_I2C5, CK_KER_I2C5, _CK_FLEXGEN_13, 0, GATE_I2C5),
1383 STM32_GATE(_CK_I2C4, CK_KER_I2C4, _CK_FLEXGEN_14, 0, GATE_I2C4),
1384 STM32_GATE(_CK_I2C6, CK_KER_I2C6, _CK_FLEXGEN_14, 0, GATE_I2C6),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001385#endif /* STM32MP25 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001386 STM32_GATE(_CK_I2C7, CK_KER_I2C7, _CK_FLEXGEN_15, 0, GATE_I2C7),
1387 STM32_GATE(_CK_USART1, CK_KER_USART1, _CK_FLEXGEN_19, 0, GATE_USART1),
1388 STM32_GATE(_CK_USART6, CK_KER_USART6, _CK_FLEXGEN_20, 0, GATE_USART6),
1389 STM32_GATE(_CK_UART7, CK_KER_UART7, _CK_FLEXGEN_21, 0, GATE_UART7),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001390#if STM32MP25
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001391 STM32_GATE(_CK_UART8, CK_KER_UART8, _CK_FLEXGEN_21, 0, GATE_UART8),
1392 STM32_GATE(_CK_UART9, CK_KER_UART9, _CK_FLEXGEN_22, 0, GATE_UART9),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001393#endif /* STM32MP25 */
1394#endif /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001395 STM32_GATE(_CK_STGEN, CK_KER_STGEN, _CK_FLEXGEN_33, 0, GATE_STGEN),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001396#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001397 STM32_GATE(_CK_USB3PCIEPHY, CK_KER_USB3PCIEPHY, _CK_FLEXGEN_34, 0, GATE_USB3PCIEPHY),
1398 STM32_GATE(_CK_USBTC, CK_KER_USBTC, _CK_FLEXGEN_35, 0, GATE_USBTC),
1399 STM32_GATE(_CK_I2C8, CK_KER_I2C8, _CK_FLEXGEN_38, 0, GATE_I2C8),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001400#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001401 STM32_GATE(_CK_OSPI1, CK_KER_OSPI1, _CK_FLEXGEN_48, 0, GATE_OSPI1),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001402#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001403 STM32_GATE(_CK_OSPI2, CK_KER_OSPI2, _CK_FLEXGEN_49, 0, GATE_OSPI2),
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001404#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001405 STM32_GATE(_CK_FMC, CK_KER_FMC, _CK_FLEXGEN_50, 0, GATE_FMC),
1406 STM32_GATE(_CK_SDMMC1, CK_KER_SDMMC1, _CK_FLEXGEN_51, 0, GATE_SDMMC1),
1407 STM32_GATE(_CK_SDMMC2, CK_KER_SDMMC2, _CK_FLEXGEN_52, 0, GATE_SDMMC2),
1408 STM32_GATE(_CK_USB2PHY1, CK_KER_USB2PHY1, _CK_FLEXGEN_57, 0, GATE_USB2PHY1),
1409 STM32_GATE(_CK_USB2PHY2, CK_KER_USB2PHY2, _CK_FLEXGEN_58, 0, GATE_USB2PHY2),
1410};
1411
1412enum clksrc_id {
1413 CLKSRC_CA35SS,
1414 CLKSRC_PLL1,
1415 CLKSRC_PLL2,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001416#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001417 CLKSRC_PLL3,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001418#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001419 CLKSRC_PLL4,
1420 CLKSRC_PLL5,
1421 CLKSRC_PLL6,
1422 CLKSRC_PLL7,
1423 CLKSRC_PLL8,
1424 CLKSRC_XBAR_CHANNEL0,
1425 CLKSRC_XBAR_CHANNEL1,
1426 CLKSRC_XBAR_CHANNEL2,
1427 CLKSRC_XBAR_CHANNEL3,
1428 CLKSRC_XBAR_CHANNEL4,
1429 CLKSRC_XBAR_CHANNEL5,
1430 CLKSRC_XBAR_CHANNEL6,
1431 CLKSRC_XBAR_CHANNEL7,
1432 CLKSRC_XBAR_CHANNEL8,
1433 CLKSRC_XBAR_CHANNEL9,
1434 CLKSRC_XBAR_CHANNEL10,
1435 CLKSRC_XBAR_CHANNEL11,
1436 CLKSRC_XBAR_CHANNEL12,
1437 CLKSRC_XBAR_CHANNEL13,
1438 CLKSRC_XBAR_CHANNEL14,
1439 CLKSRC_XBAR_CHANNEL15,
1440 CLKSRC_XBAR_CHANNEL16,
1441 CLKSRC_XBAR_CHANNEL17,
1442 CLKSRC_XBAR_CHANNEL18,
1443 CLKSRC_XBAR_CHANNEL19,
1444 CLKSRC_XBAR_CHANNEL20,
1445 CLKSRC_XBAR_CHANNEL21,
1446 CLKSRC_XBAR_CHANNEL22,
1447 CLKSRC_XBAR_CHANNEL23,
1448 CLKSRC_XBAR_CHANNEL24,
1449 CLKSRC_XBAR_CHANNEL25,
1450 CLKSRC_XBAR_CHANNEL26,
1451 CLKSRC_XBAR_CHANNEL27,
1452 CLKSRC_XBAR_CHANNEL28,
1453 CLKSRC_XBAR_CHANNEL29,
1454 CLKSRC_XBAR_CHANNEL30,
1455 CLKSRC_XBAR_CHANNEL31,
1456 CLKSRC_XBAR_CHANNEL32,
1457 CLKSRC_XBAR_CHANNEL33,
1458 CLKSRC_XBAR_CHANNEL34,
1459 CLKSRC_XBAR_CHANNEL35,
1460 CLKSRC_XBAR_CHANNEL36,
1461 CLKSRC_XBAR_CHANNEL37,
1462 CLKSRC_XBAR_CHANNEL38,
1463 CLKSRC_XBAR_CHANNEL39,
1464 CLKSRC_XBAR_CHANNEL40,
1465 CLKSRC_XBAR_CHANNEL41,
1466 CLKSRC_XBAR_CHANNEL42,
1467 CLKSRC_XBAR_CHANNEL43,
1468 CLKSRC_XBAR_CHANNEL44,
1469 CLKSRC_XBAR_CHANNEL45,
1470 CLKSRC_XBAR_CHANNEL46,
1471 CLKSRC_XBAR_CHANNEL47,
1472 CLKSRC_XBAR_CHANNEL48,
1473 CLKSRC_XBAR_CHANNEL49,
1474 CLKSRC_XBAR_CHANNEL50,
1475 CLKSRC_XBAR_CHANNEL51,
1476 CLKSRC_XBAR_CHANNEL52,
1477 CLKSRC_XBAR_CHANNEL53,
1478 CLKSRC_XBAR_CHANNEL54,
1479 CLKSRC_XBAR_CHANNEL55,
1480 CLKSRC_XBAR_CHANNEL56,
1481 CLKSRC_XBAR_CHANNEL57,
1482 CLKSRC_XBAR_CHANNEL58,
1483 CLKSRC_XBAR_CHANNEL59,
1484 CLKSRC_XBAR_CHANNEL60,
1485 CLKSRC_XBAR_CHANNEL61,
1486 CLKSRC_XBAR_CHANNEL62,
1487 CLKSRC_XBAR_CHANNEL63,
1488 CLKSRC_RTC,
1489 CLKSRC_MCO1,
1490 CLKSRC_MCO2,
1491 CLKSRC_NB
1492};
1493
1494static void stm32mp2_a35_ss_on_hsi(void)
1495{
1496 uintptr_t a35_ss_address = A35SSC_BASE;
1497 uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ;
1498 uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
1499 uint64_t timeout;
1500
1501 if ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) ==
1502 A35_SS_CHGCLKREQ_ARM_CHGCLKACK) {
1503 /* Nothing to do, clock source is already set on bypass clock */
1504 return;
1505 }
1506
1507 mmio_setbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ);
1508
1509 timeout = timeout_init_us(CLKSRC_TIMEOUT);
1510 while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) !=
1511 A35_SS_CHGCLKREQ_ARM_CHGCLKACK) {
1512 if (timeout_elapsed(timeout)) {
1513 EARLY_ERROR("Cannot switch A35 to bypass clock\n");
1514 panic();
1515 }
1516 }
1517
1518 mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF);
1519}
1520
1521#ifdef IMAGE_BL2
1522static void stm32mp2_clk_muxsel_on_hsi(struct stm32_clk_priv *priv)
1523{
1524 mmio_clrbits_32(priv->base + RCC_MUXSELCFGR,
1525 RCC_MUXSELCFGR_MUXSEL0_MASK |
1526 RCC_MUXSELCFGR_MUXSEL1_MASK |
1527 RCC_MUXSELCFGR_MUXSEL2_MASK |
1528 RCC_MUXSELCFGR_MUXSEL3_MASK |
1529 RCC_MUXSELCFGR_MUXSEL4_MASK |
1530 RCC_MUXSELCFGR_MUXSEL5_MASK |
1531 RCC_MUXSELCFGR_MUXSEL6_MASK |
1532 RCC_MUXSELCFGR_MUXSEL7_MASK);
1533}
1534
1535static void stm32mp2_clk_xbar_on_hsi(struct stm32_clk_priv *priv)
1536{
1537 uintptr_t xbar0cfgr = priv->base + RCC_XBAR0CFGR;
1538 uint32_t i;
1539
1540 for (i = 0; i < XBAR_CHANNEL_NB; i++) {
1541 mmio_clrsetbits_32(xbar0cfgr + (0x4 * i),
1542 RCC_XBAR0CFGR_XBAR0SEL_MASK,
1543 XBAR_SRC_HSI);
1544 }
1545}
1546
1547static int stm32mp2_a35_pll1_start(void)
1548{
1549 uintptr_t a35_ss_address = A35SSC_BASE;
1550 uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
1551 uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ;
1552 uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
1553
1554 mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD);
1555
1556 /* Wait PLL lock */
1557 while ((mmio_read_32(pll_enable_reg) & A35_SS_PLL_ENABLE_LOCKP) == 0U) {
1558 if (timeout_elapsed(timeout)) {
1559 EARLY_ERROR("PLL1 start failed @ 0x%lx: 0x%x\n",
1560 pll_enable_reg, mmio_read_32(pll_enable_reg));
1561 return -ETIMEDOUT;
1562 }
1563 }
1564
1565 /* De-assert reset on PLL output clock path */
1566 mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF);
1567
1568 /* Switch CPU clock to PLL clock */
1569 mmio_clrbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ);
1570
1571 /* Wait for clock change acknowledge */
1572 timeout = timeout_init_us(CLKSRC_TIMEOUT);
1573 while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) != 0U) {
1574 if (timeout_elapsed(timeout)) {
1575 EARLY_ERROR("CA35SS switch to PLL1 failed @ 0x%lx: 0x%x\n",
1576 chgclkreq_reg, mmio_read_32(chgclkreq_reg));
1577 return -ETIMEDOUT;
1578 }
1579 }
1580
1581 return 0;
1582}
1583
1584static void stm32mp2_a35_pll1_config(uint32_t fbdiv, uint32_t refdiv, uint32_t postdiv1,
1585 uint32_t postdiv2)
1586{
1587 uintptr_t a35_ss_address = A35SSC_BASE;
1588 uintptr_t pll_freq1_reg = a35_ss_address + A35_SS_PLL_FREQ1;
1589 uintptr_t pll_freq2_reg = a35_ss_address + A35_SS_PLL_FREQ2;
1590
1591 mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_REFDIV_MASK,
1592 (refdiv << A35_SS_PLL_FREQ1_REFDIV_SHIFT) &
1593 A35_SS_PLL_FREQ1_REFDIV_MASK);
1594
1595 mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_FBDIV_MASK,
1596 (fbdiv << A35_SS_PLL_FREQ1_FBDIV_SHIFT) &
1597 A35_SS_PLL_FREQ1_FBDIV_MASK);
1598
1599 mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV1_MASK,
1600 (postdiv1 << A35_SS_PLL_FREQ2_POSTDIV1_SHIFT) &
1601 A35_SS_PLL_FREQ2_POSTDIV1_MASK);
1602
1603 mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV2_MASK,
1604 (postdiv2 << A35_SS_PLL_FREQ2_POSTDIV2_SHIFT) &
1605 A35_SS_PLL_FREQ2_POSTDIV2_MASK);
1606}
1607
1608static int clk_stm32_pll_config_output(struct stm32_clk_priv *priv,
1609 const struct stm32_clk_pll *pll,
1610 uint32_t *pllcfg,
1611 uint32_t fracv)
1612{
1613 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
1614 uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2;
1615 uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
1616 uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
1617 uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6;
1618 uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7;
1619 unsigned long refclk;
1620
1621 refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id);
1622
1623 if (fracv == 0U) {
1624 /* PLL in integer mode */
1625
1626 /*
1627 * No need to check max clock, as oscillator reference clocks
1628 * will always be less than 1.2GHz
1629 */
1630 if (refclk < PLL_REFCLK_MIN) {
1631 panic();
1632 }
1633
1634 mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK);
1635 mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
1636 mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN);
1637 mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
1638 mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST);
1639 } else {
1640 /* PLL in frac mode */
1641
1642 /*
1643 * No need to check max clock, as oscillator reference clocks
1644 * will always be less than 1.2GHz
1645 */
1646 if (refclk < PLL_FRAC_REFCLK_MIN) {
1647 panic();
1648 }
1649
1650 mmio_clrsetbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK,
1651 fracv & RCC_PLLxCFGR3_FRACIN_MASK);
1652 mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
1653 mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
1654 }
1655
1656 assert(pllcfg[REFDIV] != 0U);
1657
1658 mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FBDIV_MASK,
1659 (pllcfg[FBDIV] << RCC_PLLxCFGR2_FBDIV_SHIFT) &
1660 RCC_PLLxCFGR2_FBDIV_MASK);
1661 mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FREFDIV_MASK,
1662 pllcfg[REFDIV] & RCC_PLLxCFGR2_FREFDIV_MASK);
1663 mmio_clrsetbits_32(pllxcfgr6, RCC_PLLxCFGR6_POSTDIV1_MASK,
1664 pllcfg[POSTDIV1] & RCC_PLLxCFGR6_POSTDIV1_MASK);
1665 mmio_clrsetbits_32(pllxcfgr7, RCC_PLLxCFGR7_POSTDIV2_MASK,
1666 pllcfg[POSTDIV2] & RCC_PLLxCFGR7_POSTDIV2_MASK);
1667
1668 if ((pllcfg[POSTDIV1] == 0U) || (pllcfg[POSTDIV2] == 0U)) {
1669 /* Bypass mode */
1670 mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS);
1671 mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN);
1672 } else {
1673 mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS);
1674 mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN);
1675 }
1676
1677 return 0;
1678}
1679
1680static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv,
1681 const struct stm32_clk_pll *pll,
1682 uint32_t *csg)
1683{
1684 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
1685 uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
1686 uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
1687 uintptr_t pllxcfgr5 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR5;
1688
1689
1690 mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_DIVVAL_MASK,
1691 csg[DIVVAL] & RCC_PLLxCFGR5_DIVVAL_MASK);
1692 mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_SPREAD_MASK,
1693 (csg[SPREAD] << RCC_PLLxCFGR5_SPREAD_SHIFT) &
1694 RCC_PLLxCFGR5_SPREAD_MASK);
1695
1696 if (csg[DOWNSPREAD] != 0) {
1697 mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD);
1698 } else {
1699 mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD);
1700 }
1701
1702 mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
1703
1704 mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
1705 udelay(1);
1706
1707 mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
1708 mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN);
1709}
1710
1711static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data);
1712
1713static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx)
1714{
1715 struct stm32_clk_priv *priv = clk_stm32_get_priv();
1716 struct stm32_clk_platdata *pdata = priv->pdata;
1717
1718 return &pdata->pll[pll_idx];
1719}
1720
1721static int _clk_stm32_pll1_init(struct stm32_clk_priv *priv, int pll_idx,
1722 struct stm32_pll_dt_cfg *pll_conf)
1723{
1724 const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx);
1725 unsigned long refclk;
1726 int ret = 0;
1727
1728 stm32mp2_a35_ss_on_hsi();
1729
1730 ret = stm32_clk_configure_mux(priv, pll_conf->src);
1731 if (ret != 0) {
1732 panic();
1733 }
1734
1735 refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id);
1736
1737 /*
1738 * No need to check max clock, as oscillator reference clocks will
1739 * always be less than 1.2 GHz
1740 */
1741 if (refclk < PLL_REFCLK_MIN) {
1742 EARLY_ERROR("%s: %d\n", __func__, __LINE__);
1743 panic();
1744 }
1745
1746 stm32mp2_a35_pll1_config(pll_conf->cfg[FBDIV], pll_conf->cfg[REFDIV],
1747 pll_conf->cfg[POSTDIV1], pll_conf->cfg[POSTDIV2]);
1748
1749 ret = stm32mp2_a35_pll1_start();
1750 if (ret != 0) {
1751 panic();
1752 }
1753
1754 return 0;
1755}
1756
1757static int clk_stm32_pll_wait_mux_ready(struct stm32_clk_priv *priv,
1758 const struct stm32_clk_pll *pll)
1759{
1760 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
1761 uint64_t timeout = timeout_init_us(CLKSRC_TIMEOUT);
1762
1763 while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_CKREFST) !=
1764 RCC_PLLxCFGR1_CKREFST) {
1765 if (timeout_elapsed(timeout)) {
1766 EARLY_ERROR("PLL%d ref clock not started\n", pll->clk_id - _CK_PLL1 + 1);
1767 return -ETIMEDOUT;
1768 }
1769 }
1770
1771 return 0;
1772}
1773
1774static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx,
1775 struct stm32_pll_dt_cfg *pll_conf)
1776{
1777 const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx);
1778 uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
1779 bool spread_spectrum = false;
1780 int ret = 0;
1781
1782 _clk_stm32_pll_disable(priv, pll);
1783
1784 ret = stm32_clk_configure_mux(priv, pll_conf->src);
1785 if (ret != 0) {
1786 panic();
1787 }
1788
1789 ret = clk_stm32_pll_wait_mux_ready(priv, pll);
1790 if (ret != 0) {
1791 panic();
1792 }
1793
1794 ret = clk_stm32_pll_config_output(priv, pll, pll_conf->cfg, pll_conf->frac);
1795 if (ret != 0) {
1796 panic();
1797 }
1798
1799 if (pll_conf->csg_enabled) {
1800 clk_stm32_pll_config_csg(priv, pll, pll_conf->csg);
1801 spread_spectrum = true;
1802 }
1803
1804 _clk_stm32_pll_enable(priv, pll);
1805
1806 if (spread_spectrum) {
1807 mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST);
1808 }
1809
1810 return 0;
1811}
1812
1813static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx)
1814{
1815 struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx);
1816
1817 if (pll_conf->enabled) {
1818 if (pll_idx == _PLL1) {
1819 return _clk_stm32_pll1_init(priv, pll_idx, pll_conf);
1820 } else {
1821 return _clk_stm32_pll_init(priv, pll_idx, pll_conf);
1822 }
1823 }
1824
1825 return 0;
1826}
1827
1828static int stm32mp2_clk_pll_configure(struct stm32_clk_priv *priv)
1829{
1830 enum pll_id i;
1831 int err;
1832
1833 for (i = _PLL1; i < _PLL_NB; i++) {
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02001834#if STM32MP21
1835 if (i == _PLL3) {
1836 continue;
1837 }
1838#endif
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02001839 err = clk_stm32_pll_init(priv, i);
1840 if (err) {
1841 return err;
1842 }
1843 }
1844
1845 return 0;
1846}
1847
1848static int wait_predivsr(uint16_t channel)
1849{
1850 struct stm32_clk_priv *priv = clk_stm32_get_priv();
1851 uintptr_t rcc_base = priv->base;
1852 uintptr_t previvsr;
1853 uint32_t channel_bit;
1854 uint64_t timeout;
1855
1856 if (channel < __WORD_BIT) {
1857 previvsr = rcc_base + RCC_PREDIVSR1;
1858 channel_bit = BIT(channel);
1859 } else {
1860 previvsr = rcc_base + RCC_PREDIVSR2;
1861 channel_bit = BIT(channel - __WORD_BIT);
1862 }
1863
1864 timeout = timeout_init_us(CLKDIV_TIMEOUT);
1865 while ((mmio_read_32(previvsr) & channel_bit) != 0U) {
1866 if (timeout_elapsed(timeout)) {
1867 EARLY_ERROR("Pre divider status: %x\n",
1868 mmio_read_32(previvsr));
1869 return -ETIMEDOUT;
1870 }
1871 }
1872
1873 return 0;
1874}
1875
1876static int wait_findivsr(uint16_t channel)
1877{
1878 struct stm32_clk_priv *priv = clk_stm32_get_priv();
1879 uintptr_t rcc_base = priv->base;
1880 uintptr_t finvivsr;
1881 uint32_t channel_bit;
1882 uint64_t timeout;
1883
1884 if (channel < __WORD_BIT) {
1885 finvivsr = rcc_base + RCC_FINDIVSR1;
1886 channel_bit = BIT(channel);
1887 } else {
1888 finvivsr = rcc_base + RCC_FINDIVSR2;
1889 channel_bit = BIT(channel - __WORD_BIT);
1890 }
1891
1892 timeout = timeout_init_us(CLKDIV_TIMEOUT);
1893 while ((mmio_read_32(finvivsr) & channel_bit) != 0U) {
1894 if (timeout_elapsed(timeout)) {
1895 EARLY_ERROR("Final divider status: %x\n",
1896 mmio_read_32(finvivsr));
1897 return -ETIMEDOUT;
1898 }
1899 }
1900
1901 return 0;
1902}
1903
1904static int wait_xbar_sts(uint16_t channel)
1905{
1906 struct stm32_clk_priv *priv = clk_stm32_get_priv();
1907 uintptr_t rcc_base = priv->base;
1908 uintptr_t xbar_cfgr = rcc_base + RCC_XBAR0CFGR + (0x4U * channel);
1909 uint64_t timeout;
1910
1911 timeout = timeout_init_us(CLKDIV_TIMEOUT);
1912 while ((mmio_read_32(xbar_cfgr) & RCC_XBAR0CFGR_XBAR0STS) != 0U) {
1913 if (timeout_elapsed(timeout)) {
1914 EARLY_ERROR("XBAR%uCFGR: %x\n", channel,
1915 mmio_read_32(xbar_cfgr));
1916 return -ETIMEDOUT;
1917 }
1918 }
1919
1920 return 0;
1921}
1922
1923static void flexclkgen_config_channel(uint16_t channel, unsigned int clk_src,
1924 unsigned int prediv, unsigned int findiv)
1925{
1926 struct stm32_clk_priv *priv = clk_stm32_get_priv();
1927 uintptr_t rcc_base = priv->base;
1928
1929 if (wait_predivsr(channel) != 0) {
1930 panic();
1931 }
1932
1933 mmio_clrsetbits_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel),
1934 RCC_PREDIV0CFGR_PREDIV0_MASK,
1935 prediv);
1936
1937 if (wait_predivsr(channel) != 0) {
1938 panic();
1939 }
1940
1941 if (wait_findivsr(channel) != 0) {
1942 panic();
1943 }
1944
1945 mmio_clrsetbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
1946 RCC_FINDIV0CFGR_FINDIV0_MASK,
1947 findiv);
1948
1949 if (wait_findivsr(channel) != 0) {
1950 panic();
1951 }
1952
1953 if (wait_xbar_sts(channel) != 0) {
1954 panic();
1955 }
1956
1957 mmio_clrsetbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel),
1958 RCC_XBARxCFGR_XBARxSEL_MASK,
1959 clk_src);
1960 mmio_setbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel),
1961 RCC_XBARxCFGR_XBARxEN);
1962
1963 if (wait_xbar_sts(channel) != 0) {
1964 panic();
1965 }
1966}
1967
1968static int stm32mp2_clk_flexgen_configure(struct stm32_clk_priv *priv)
1969{
1970 struct stm32_clk_platdata *pdata = priv->pdata;
1971 uint32_t i;
1972
1973 for (i = 0U; i < pdata->nflexgen; i++) {
1974 uint32_t val = pdata->flexgen[i];
1975 uint32_t cmd, cmd_data;
1976 unsigned int channel, clk_src, pdiv, fdiv;
1977
1978 cmd = (val & CMD_MASK) >> CMD_SHIFT;
1979 cmd_data = val & ~CMD_MASK;
1980
1981 if (cmd != CMD_FLEXGEN) {
1982 continue;
1983 }
1984
1985 channel = (cmd_data & FLEX_ID_MASK) >> FLEX_ID_SHIFT;
1986 clk_src = (cmd_data & FLEX_SEL_MASK) >> FLEX_SEL_SHIFT;
1987 pdiv = (cmd_data & FLEX_PDIV_MASK) >> FLEX_PDIV_SHIFT;
1988 fdiv = (cmd_data & FLEX_FDIV_MASK) >> FLEX_FDIV_SHIFT;
1989
1990 switch (channel) {
1991 case 33U: /* STGEN */
1992 break;
1993
1994 default:
1995 flexclkgen_config_channel(channel, clk_src, pdiv, fdiv);
1996 break;
1997 }
1998 }
1999
2000 return 0;
2001}
2002
2003static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv)
2004{
2005 struct stm32_clk_platdata *pdata = priv->pdata;
2006 struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE];
2007 bool digbyp = osci->digbyp;
2008 bool bypass = osci->bypass;
2009 bool css = osci->css;
2010
2011 if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) {
2012 return;
2013 }
2014
2015 clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass);
2016
2017 _clk_stm32_enable(priv, _CK_HSE);
2018
2019 clk_oscillator_set_css(priv, _CK_HSE, css);
2020}
2021
2022static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv)
2023{
2024 struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE);
2025 struct stm32_clk_platdata *pdata = priv->pdata;
2026 struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
2027 bool digbyp = osci->digbyp;
2028 bool bypass = osci->bypass;
2029 uint8_t drive = osci->drive;
2030
2031 if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) {
2032 return;
2033 }
2034
2035 /* Do not reconfigure LSE if already enabled */
2036 if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) {
2037 return;
2038 }
2039
2040 clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
2041
2042 clk_oscillator_set_drive(priv, _CK_LSE, drive);
2043
2044 _clk_stm32_gate_enable(priv, osc_data->gate_id);
2045}
2046
2047static int stm32mp2_clk_switch_to_hsi(struct stm32_clk_priv *priv)
2048{
2049 stm32mp2_a35_ss_on_hsi();
2050 stm32mp2_clk_muxsel_on_hsi(priv);
2051 stm32mp2_clk_xbar_on_hsi(priv);
2052
2053 return 0;
2054}
2055
2056static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv)
2057{
2058 int ret = 0;
2059
2060 if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) {
2061 ret = clk_oscillator_wait_ready_on(priv, _CK_LSE);
2062 }
2063
2064 return ret;
2065}
2066
2067static void stm32_enable_oscillator_msi(struct stm32_clk_priv *priv)
2068{
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002069#if !STM32MP21
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002070 struct stm32_clk_platdata *pdata = priv->pdata;
2071 struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_MSI];
2072 int err;
2073
2074 err = clk_stm32_osc_msi_set_rate(priv, _CK_MSI, osci->freq, 0);
2075 if (err != 0) {
2076 EARLY_ERROR("Invalid rate %lu MHz for MSI ! (4 or 16 only)\n",
2077 osci->freq / 1000000U);
2078 panic();
2079 }
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002080#endif /* !STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002081
2082 _clk_stm32_enable(priv, _CK_MSI);
2083}
2084
2085static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv)
2086{
2087 stm32_enable_oscillator_hse(priv);
2088 stm32_enable_oscillator_lse(priv);
2089 stm32_enable_oscillator_msi(priv);
2090 _clk_stm32_enable(priv, _CK_LSI);
2091}
2092
2093static int stm32_clk_configure_div(struct stm32_clk_priv *priv, uint32_t data)
2094{
2095 int div_id = (data & DIV_ID_MASK) >> DIV_ID_SHIFT;
2096 int div_n = (data & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
2097
2098 return clk_stm32_set_div(priv, div_id, div_n);
2099}
2100
2101static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data)
2102{
2103 int mux_id = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
2104 int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
2105
2106 return clk_mux_set_parent(priv, mux_id, sel);
2107}
2108
2109static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data)
2110{
2111 unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
2112
2113 return clk_get_index(priv, binding_id);
2114}
2115
2116static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
2117{
2118 int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
2119 bool enable = ((data & CLK_ON_MASK) >> CLK_ON_SHIFT) != 0U;
2120 int clk_id = 0;
2121 int ret = 0;
2122
2123 clk_id = stm32_clk_configure_clk_get_binding_id(priv, data);
2124 if (clk_id < 0) {
2125 return clk_id;
2126 }
2127
2128 if (sel != CLK_NOMUX) {
2129 ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel);
2130 if (ret != 0) {
2131 return ret;
2132 }
2133 }
2134
2135 if (enable) {
2136 clk_stm32_enable_call_ops(priv, clk_id);
2137 } else {
2138 clk_stm32_disable_call_ops(priv, clk_id);
2139 }
2140
2141 return 0;
2142}
2143
2144static int stm32_clk_configure(struct stm32_clk_priv *priv, uint32_t val)
2145{
2146 uint32_t cmd = (val & CMD_MASK) >> CMD_SHIFT;
2147 uint32_t cmd_data = val & ~CMD_MASK;
2148 int ret = -1;
2149
2150 switch (cmd) {
2151 case CMD_DIV:
2152 ret = stm32_clk_configure_div(priv, cmd_data);
2153 break;
2154
2155 case CMD_MUX:
2156 ret = stm32_clk_configure_mux(priv, cmd_data);
2157 break;
2158
2159 case CMD_CLK:
2160 ret = stm32_clk_configure_clk(priv, cmd_data);
2161 break;
2162
2163 default:
2164 EARLY_ERROR("%s: cmd unknown ! : 0x%x\n", __func__, val);
2165 break;
2166 }
2167
2168 return ret;
2169}
2170
2171static int stm32_clk_bus_configure(struct stm32_clk_priv *priv)
2172{
2173 struct stm32_clk_platdata *pdata = priv->pdata;
2174 uint32_t i;
2175
2176 for (i = 0; i < pdata->nbusclk; i++) {
2177 int ret;
2178
2179 ret = stm32_clk_configure(priv, pdata->busclk[i]);
2180 if (ret != 0) {
2181 return ret;
2182 }
2183 }
2184
2185 return 0;
2186}
2187
2188static int stm32_clk_kernel_configure(struct stm32_clk_priv *priv)
2189{
2190 struct stm32_clk_platdata *pdata = priv->pdata;
2191 uint32_t i;
2192
2193 for (i = 0U; i < pdata->nkernelclk; i++) {
2194 int ret;
2195
2196 ret = stm32_clk_configure(priv, pdata->kernelclk[i]);
2197 if (ret != 0) {
2198 return ret;
2199 }
2200 }
2201
2202 return 0;
2203}
2204
2205static int stm32mp2_init_clock_tree(void)
2206{
2207 struct stm32_clk_priv *priv = clk_stm32_get_priv();
2208 int ret;
2209
2210 /* Set timer with STGEN without changing its clock source */
2211 stm32mp_stgen_restore_rate();
2212 generic_delay_timer_init();
2213
2214 stm32_clk_oscillators_enable(priv);
2215
2216 /* Come back to HSI */
2217 ret = stm32mp2_clk_switch_to_hsi(priv);
2218 if (ret != 0) {
2219 panic();
2220 }
2221
2222 ret = stm32mp2_clk_pll_configure(priv);
2223 if (ret != 0) {
2224 panic();
2225 }
2226
2227 /* Wait LSE ready before to use it */
2228 ret = stm32_clk_oscillators_wait_lse_ready(priv);
2229 if (ret != 0) {
2230 panic();
2231 }
2232
2233 ret = stm32mp2_clk_flexgen_configure(priv);
2234 if (ret != 0) {
2235 panic();
2236 }
2237
2238 ret = stm32_clk_bus_configure(priv);
2239 if (ret != 0) {
2240 panic();
2241 }
2242
2243 ret = stm32_clk_kernel_configure(priv);
2244 if (ret != 0) {
2245 panic();
2246 }
2247
2248 return 0;
2249}
2250
2251static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
2252 struct stm32_osci_dt_cfg *osci)
2253{
2254 int subnode = 0;
2255
2256 /* Default value oscillator not found, freq=0 */
2257 osci->freq = 0;
2258
2259 fdt_for_each_subnode(subnode, fdt, node) {
2260 const char *cchar = NULL;
2261 const fdt32_t *cuint = NULL;
2262 int ret = 0;
2263
2264 cchar = fdt_get_name(fdt, subnode, &ret);
2265 if (cchar == NULL) {
2266 return ret;
2267 }
2268
2269 if (strncmp(cchar, name, (size_t)ret) ||
2270 fdt_get_status(subnode) == DT_DISABLED) {
2271 continue;
2272 }
2273
2274 cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret);
2275 if (cuint == NULL) {
2276 return ret;
2277 }
2278
2279 osci->freq = fdt32_to_cpu(*cuint);
2280
2281 if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) {
2282 osci->bypass = true;
2283 }
2284
2285 if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) {
2286 osci->digbyp = true;
2287 }
2288
2289 if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) {
2290 osci->css = true;
2291 }
2292
2293 osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH);
2294
2295 return 0;
2296 }
2297
2298 return 0;
2299}
2300
2301static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata)
2302{
2303 int fdt_err = 0;
2304 uint32_t i = 0;
2305 int node = 0;
2306
2307 node = fdt_path_offset(fdt, "/clocks");
2308 if (node < 0) {
2309 return -FDT_ERR_NOTFOUND;
2310 }
2311
2312 for (i = 0; i < pdata->nosci; i++) {
2313 const char *name = NULL;
2314
2315 name = clk_stm32_get_oscillator_name((enum stm32_osc)i);
2316 if (name == NULL) {
2317 continue;
2318 }
2319
2320 fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]);
2321 if (fdt_err < 0) {
2322 panic();
2323 }
2324 }
2325
2326 return 0;
2327}
2328
2329static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
2330{
2331 const fdt32_t *cuint = NULL;
2332 int subnode_pll = 0;
2333 uint32_t val = 0;
2334 int err = 0;
2335
2336 cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
2337 if (!cuint) {
2338 return -FDT_ERR_NOTFOUND;
2339 }
2340
2341 subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
2342 if (subnode_pll < 0) {
2343 return -FDT_ERR_NOTFOUND;
2344 }
2345
2346 err = fdt_read_uint32_array(fdt, subnode_pll, "cfg", (int)PLLCFG_NB, pll->cfg);
2347 if (err != 0) {
2348 return err;
2349 }
2350
2351 err = fdt_read_uint32_array(fdt, subnode_pll, "csg", (int)PLLCSG_NB, pll->csg);
2352
2353 pll->csg_enabled = (err == 0);
2354
2355 if (err == -FDT_ERR_NOTFOUND) {
2356 err = 0;
2357 }
2358
2359 if (err != 0) {
2360 return err;
2361 }
2362
2363 pll->enabled = true;
2364
2365 pll->frac = fdt_read_uint32_default(fdt, subnode_pll, "frac", 0);
2366
2367 pll->src = UINT32_MAX;
2368
2369 err = fdt_read_uint32(fdt, subnode_pll, "src", &val);
2370 if (err == 0) {
2371 pll->src = val;
2372 }
2373
2374 return 0;
2375}
2376
2377#define RCC_PLL_NAME_SIZE 12
2378
2379static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
2380{
2381 unsigned int i = 0;
2382
2383 for (i = _PLL1; i < pdata->npll; i++) {
2384 struct stm32_pll_dt_cfg *pll = pdata->pll + i;
2385 char name[RCC_PLL_NAME_SIZE];
2386 int subnode = 0;
2387 int err = 0;
2388
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002389#if STM32MP21
2390 if (i == _PLL3) {
2391 continue;
2392 }
2393#endif
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002394 snprintf(name, sizeof(name), "st,pll-%u", i + 1);
2395
2396 subnode = fdt_subnode_offset(fdt, node, name);
2397 if (!fdt_check_node(subnode)) {
2398 continue;
2399 }
2400
2401 err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
2402 if (err != 0) {
2403 panic();
2404 }
2405 }
2406
2407 return 0;
2408}
2409
2410static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
2411{
2412 void *fdt = NULL;
2413 int node;
2414 int err;
2415
2416 if (fdt_get_address(&fdt) == 0) {
2417 return -ENOENT;
2418 }
2419
2420 node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
2421 if (node < 0) {
2422 panic();
2423 }
2424
2425 err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata);
2426 if (err != 0) {
2427 return err;
2428 }
2429
2430 err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
2431 if (err != 0) {
2432 return err;
2433 }
2434
2435 err = stm32_clk_parse_fdt_by_name(fdt, node, "st,busclk", pdata->busclk, &pdata->nbusclk);
2436 if (err != 0) {
2437 return err;
2438 }
2439
2440 err = stm32_clk_parse_fdt_by_name(fdt, node, "st,flexgen", pdata->flexgen,
2441 &pdata->nflexgen);
2442 if (err != 0) {
2443 return err;
2444 }
2445
2446 err = stm32_clk_parse_fdt_by_name(fdt, node, "st,kerclk", pdata->kernelclk,
2447 &pdata->nkernelclk);
2448 if (err != 0) {
2449 return err;
2450 }
2451
2452 return 0;
2453}
2454#endif /* IMAGE_BL2 */
2455
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002456static struct stm32_osci_dt_cfg mp2_osci[NB_OSCILLATOR];
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002457
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002458static struct stm32_pll_dt_cfg mp2_pll[_PLL_NB];
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002459
2460#define DT_FLEXGEN_CLK_MAX 64
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002461static uint32_t mp2_flexgen[DT_FLEXGEN_CLK_MAX];
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002462
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002463#if STM32MP21
2464#define DT_BUS_CLK_MAX 7
2465#else /* STM32MP21 */
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002466#define DT_BUS_CLK_MAX 6
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002467#endif /* STM32MP21 */
2468static uint32_t mp2_busclk[DT_BUS_CLK_MAX];
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002469
2470#define DT_KERNEL_CLK_MAX 20
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002471static uint32_t mp2_kernelclk[DT_KERNEL_CLK_MAX];
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002472
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002473static struct stm32_clk_platdata stm32mp2_pdata = {
2474 .osci = mp2_osci,
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002475 .nosci = NB_OSCILLATOR,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002476 .pll = mp2_pll,
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002477 .npll = _PLL_NB,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002478 .flexgen = mp2_flexgen,
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002479 .nflexgen = DT_FLEXGEN_CLK_MAX,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002480 .busclk = mp2_busclk,
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002481 .nbusclk = DT_BUS_CLK_MAX,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002482 .kernelclk = mp2_kernelclk,
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002483 .nkernelclk = DT_KERNEL_CLK_MAX,
2484};
2485
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002486static uint8_t refcounts_mp2[CK_LAST];
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002487
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002488static struct stm32_clk_priv stm32mp2_clock_data = {
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002489 .base = RCC_BASE,
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002490 .num = ARRAY_SIZE(stm32mp2_clk),
2491 .clks = stm32mp2_clk,
2492 .parents = parent_mp2,
2493 .nb_parents = ARRAY_SIZE(parent_mp2),
2494 .gates = gates_mp2,
2495 .nb_gates = ARRAY_SIZE(gates_mp2),
2496 .div = dividers_mp2,
2497 .nb_div = ARRAY_SIZE(dividers_mp2),
2498 .osci_data = stm32mp2_osc_data,
2499 .nb_osci_data = ARRAY_SIZE(stm32mp2_osc_data),
2500 .gate_refcounts = refcounts_mp2,
2501 .pdata = &stm32mp2_pdata,
2502 .ops_array = ops_array_mp2,
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002503};
2504
2505int stm32mp2_clk_init(void)
2506{
2507 uintptr_t base = RCC_BASE;
2508 int ret;
2509
2510#ifdef IMAGE_BL2
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002511 ret = stm32_clk_parse_fdt(&stm32mp2_pdata);
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002512 if (ret != 0) {
2513 return ret;
2514 }
2515#endif
2516
Nicolas Le Bayon088238a2023-09-29 16:50:37 +02002517 ret = clk_stm32_init(&stm32mp2_clock_data, base);
Gabriel Fernandez615f31f2022-04-20 10:08:49 +02002518 if (ret != 0) {
2519 return ret;
2520 }
2521
2522#ifdef IMAGE_BL2
2523 ret = stm32mp2_init_clock_tree();
2524 if (ret != 0) {
2525 return ret;
2526 }
2527
2528 clk_stm32_enable_critical_clocks();
2529#endif
2530
2531 return 0;
2532}
2533
2534int stm32mp2_pll1_disable(void)
2535{
2536#ifdef IMAGE_BL2
2537 return -EPERM;
2538#else
2539 uintptr_t a35_ss_address = A35SSC_BASE;
2540 uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
2541
2542 stm32mp2_a35_ss_on_hsi();
2543
2544 mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD);
2545
2546 return 0;
2547#endif
2548}