xref: /rk3399_ARM-atf/drivers/st/clk/clk-stm32mp13.c (revision 9be88e75c198b08c508d8e470964720a781294b3)
1*9be88e75SGabriel Fernandez /*
2*9be88e75SGabriel Fernandez  * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
3*9be88e75SGabriel Fernandez  *
4*9be88e75SGabriel Fernandez  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
5*9be88e75SGabriel Fernandez  */
6*9be88e75SGabriel Fernandez 
7*9be88e75SGabriel Fernandez #include <assert.h>
8*9be88e75SGabriel Fernandez #include <errno.h>
9*9be88e75SGabriel Fernandez #include <limits.h>
10*9be88e75SGabriel Fernandez #include <stdint.h>
11*9be88e75SGabriel Fernandez #include <stdio.h>
12*9be88e75SGabriel Fernandez 
13*9be88e75SGabriel Fernandez #include <arch.h>
14*9be88e75SGabriel Fernandez #include <arch_helpers.h>
15*9be88e75SGabriel Fernandez #include "clk-stm32-core.h"
16*9be88e75SGabriel Fernandez #include <common/debug.h>
17*9be88e75SGabriel Fernandez #include <common/fdt_wrappers.h>
18*9be88e75SGabriel Fernandez #include <drivers/clk.h>
19*9be88e75SGabriel Fernandez #include <drivers/delay_timer.h>
20*9be88e75SGabriel Fernandez #include <drivers/st/stm32mp13_rcc.h>
21*9be88e75SGabriel Fernandez #include <drivers/st/stm32mp1_clk.h>
22*9be88e75SGabriel Fernandez #include <drivers/st/stm32mp_clkfunc.h>
23*9be88e75SGabriel Fernandez #include <dt-bindings/clock/stm32mp13-clksrc.h>
24*9be88e75SGabriel Fernandez #include <lib/mmio.h>
25*9be88e75SGabriel Fernandez #include <lib/spinlock.h>
26*9be88e75SGabriel Fernandez #include <lib/utils_def.h>
27*9be88e75SGabriel Fernandez #include <libfdt.h>
28*9be88e75SGabriel Fernandez #include <plat/common/platform.h>
29*9be88e75SGabriel Fernandez 
30*9be88e75SGabriel Fernandez #include <platform_def.h>
31*9be88e75SGabriel Fernandez 
32*9be88e75SGabriel Fernandez struct stm32_osci_dt_cfg {
33*9be88e75SGabriel Fernandez 	unsigned long freq;
34*9be88e75SGabriel Fernandez 	bool bypass;
35*9be88e75SGabriel Fernandez 	bool digbyp;
36*9be88e75SGabriel Fernandez 	bool css;
37*9be88e75SGabriel Fernandez 	uint32_t drive;
38*9be88e75SGabriel Fernandez };
39*9be88e75SGabriel Fernandez 
40*9be88e75SGabriel Fernandez enum pll_mn {
41*9be88e75SGabriel Fernandez 	PLL_CFG_M,
42*9be88e75SGabriel Fernandez 	PLL_CFG_N,
43*9be88e75SGabriel Fernandez 	PLL_DIV_MN_NB
44*9be88e75SGabriel Fernandez };
45*9be88e75SGabriel Fernandez 
46*9be88e75SGabriel Fernandez enum pll_pqr {
47*9be88e75SGabriel Fernandez 	PLL_CFG_P,
48*9be88e75SGabriel Fernandez 	PLL_CFG_Q,
49*9be88e75SGabriel Fernandez 	PLL_CFG_R,
50*9be88e75SGabriel Fernandez 	PLL_DIV_PQR_NB
51*9be88e75SGabriel Fernandez };
52*9be88e75SGabriel Fernandez 
53*9be88e75SGabriel Fernandez enum pll_csg {
54*9be88e75SGabriel Fernandez 	PLL_CSG_MOD_PER,
55*9be88e75SGabriel Fernandez 	PLL_CSG_INC_STEP,
56*9be88e75SGabriel Fernandez 	PLL_CSG_SSCG_MODE,
57*9be88e75SGabriel Fernandez 	PLL_CSG_NB
58*9be88e75SGabriel Fernandez };
59*9be88e75SGabriel Fernandez 
60*9be88e75SGabriel Fernandez struct stm32_pll_vco {
61*9be88e75SGabriel Fernandez 	uint32_t status;
62*9be88e75SGabriel Fernandez 	uint32_t src;
63*9be88e75SGabriel Fernandez 	uint32_t div_mn[PLL_DIV_MN_NB];
64*9be88e75SGabriel Fernandez 	uint32_t frac;
65*9be88e75SGabriel Fernandez 	bool csg_enabled;
66*9be88e75SGabriel Fernandez 	uint32_t csg[PLL_CSG_NB];
67*9be88e75SGabriel Fernandez };
68*9be88e75SGabriel Fernandez 
69*9be88e75SGabriel Fernandez struct stm32_pll_output {
70*9be88e75SGabriel Fernandez 	uint32_t output[PLL_DIV_PQR_NB];
71*9be88e75SGabriel Fernandez };
72*9be88e75SGabriel Fernandez 
73*9be88e75SGabriel Fernandez struct stm32_pll_dt_cfg {
74*9be88e75SGabriel Fernandez 	struct stm32_pll_vco vco;
75*9be88e75SGabriel Fernandez 	struct stm32_pll_output output;
76*9be88e75SGabriel Fernandez };
77*9be88e75SGabriel Fernandez 
78*9be88e75SGabriel Fernandez struct stm32_clk_platdata {
79*9be88e75SGabriel Fernandez 	uint32_t nosci;
80*9be88e75SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci;
81*9be88e75SGabriel Fernandez 	uint32_t npll;
82*9be88e75SGabriel Fernandez 	struct stm32_pll_dt_cfg *pll;
83*9be88e75SGabriel Fernandez 	uint32_t nclksrc;
84*9be88e75SGabriel Fernandez 	uint32_t *clksrc;
85*9be88e75SGabriel Fernandez 	uint32_t nclkdiv;
86*9be88e75SGabriel Fernandez 	uint32_t *clkdiv;
87*9be88e75SGabriel Fernandez };
88*9be88e75SGabriel Fernandez 
89*9be88e75SGabriel Fernandez enum stm32_clock {
90*9be88e75SGabriel Fernandez 	/* ROOT CLOCKS */
91*9be88e75SGabriel Fernandez 	_CK_OFF,
92*9be88e75SGabriel Fernandez 	_CK_HSI,
93*9be88e75SGabriel Fernandez 	_CK_HSE,
94*9be88e75SGabriel Fernandez 	_CK_CSI,
95*9be88e75SGabriel Fernandez 	_CK_LSI,
96*9be88e75SGabriel Fernandez 	_CK_LSE,
97*9be88e75SGabriel Fernandez 	_I2SCKIN,
98*9be88e75SGabriel Fernandez 	_CSI_DIV122,
99*9be88e75SGabriel Fernandez 	_HSE_DIV,
100*9be88e75SGabriel Fernandez 	_HSE_DIV2,
101*9be88e75SGabriel Fernandez 	_CK_PLL1,
102*9be88e75SGabriel Fernandez 	_CK_PLL2,
103*9be88e75SGabriel Fernandez 	_CK_PLL3,
104*9be88e75SGabriel Fernandez 	_CK_PLL4,
105*9be88e75SGabriel Fernandez 	_PLL1P,
106*9be88e75SGabriel Fernandez 	_PLL1P_DIV,
107*9be88e75SGabriel Fernandez 	_PLL2P,
108*9be88e75SGabriel Fernandez 	_PLL2Q,
109*9be88e75SGabriel Fernandez 	_PLL2R,
110*9be88e75SGabriel Fernandez 	_PLL3P,
111*9be88e75SGabriel Fernandez 	_PLL3Q,
112*9be88e75SGabriel Fernandez 	_PLL3R,
113*9be88e75SGabriel Fernandez 	_PLL4P,
114*9be88e75SGabriel Fernandez 	_PLL4Q,
115*9be88e75SGabriel Fernandez 	_PLL4R,
116*9be88e75SGabriel Fernandez 	_PCLK1,
117*9be88e75SGabriel Fernandez 	_PCLK2,
118*9be88e75SGabriel Fernandez 	_PCLK3,
119*9be88e75SGabriel Fernandez 	_PCLK4,
120*9be88e75SGabriel Fernandez 	_PCLK5,
121*9be88e75SGabriel Fernandez 	_PCLK6,
122*9be88e75SGabriel Fernandez 	_CKMPU,
123*9be88e75SGabriel Fernandez 	_CKAXI,
124*9be88e75SGabriel Fernandez 	_CKMLAHB,
125*9be88e75SGabriel Fernandez 	_CKPER,
126*9be88e75SGabriel Fernandez 	_CKTIMG1,
127*9be88e75SGabriel Fernandez 	_CKTIMG2,
128*9be88e75SGabriel Fernandez 	_CKTIMG3,
129*9be88e75SGabriel Fernandez 	_USB_PHY_48,
130*9be88e75SGabriel Fernandez 	_MCO1_K,
131*9be88e75SGabriel Fernandez 	_MCO2_K,
132*9be88e75SGabriel Fernandez 	_TRACECK,
133*9be88e75SGabriel Fernandez 	/* BUS and KERNEL CLOCKS */
134*9be88e75SGabriel Fernandez 	_DDRC1,
135*9be88e75SGabriel Fernandez 	_DDRC1LP,
136*9be88e75SGabriel Fernandez 	_DDRPHYC,
137*9be88e75SGabriel Fernandez 	_DDRPHYCLP,
138*9be88e75SGabriel Fernandez 	_DDRCAPB,
139*9be88e75SGabriel Fernandez 	_DDRCAPBLP,
140*9be88e75SGabriel Fernandez 	_AXIDCG,
141*9be88e75SGabriel Fernandez 	_DDRPHYCAPB,
142*9be88e75SGabriel Fernandez 	_DDRPHYCAPBLP,
143*9be88e75SGabriel Fernandez 	_SYSCFG,
144*9be88e75SGabriel Fernandez 	_DDRPERFM,
145*9be88e75SGabriel Fernandez 	_IWDG2APB,
146*9be88e75SGabriel Fernandez 	_USBPHY_K,
147*9be88e75SGabriel Fernandez 	_USBO_K,
148*9be88e75SGabriel Fernandez 	_RTCAPB,
149*9be88e75SGabriel Fernandez 	_TZC,
150*9be88e75SGabriel Fernandez 	_ETZPC,
151*9be88e75SGabriel Fernandez 	_IWDG1APB,
152*9be88e75SGabriel Fernandez 	_BSEC,
153*9be88e75SGabriel Fernandez 	_STGENC,
154*9be88e75SGabriel Fernandez 	_USART1_K,
155*9be88e75SGabriel Fernandez 	_USART2_K,
156*9be88e75SGabriel Fernandez 	_I2C3_K,
157*9be88e75SGabriel Fernandez 	_I2C4_K,
158*9be88e75SGabriel Fernandez 	_I2C5_K,
159*9be88e75SGabriel Fernandez 	_TIM12,
160*9be88e75SGabriel Fernandez 	_TIM15,
161*9be88e75SGabriel Fernandez 	_RTCCK,
162*9be88e75SGabriel Fernandez 	_GPIOA,
163*9be88e75SGabriel Fernandez 	_GPIOB,
164*9be88e75SGabriel Fernandez 	_GPIOC,
165*9be88e75SGabriel Fernandez 	_GPIOD,
166*9be88e75SGabriel Fernandez 	_GPIOE,
167*9be88e75SGabriel Fernandez 	_GPIOF,
168*9be88e75SGabriel Fernandez 	_GPIOG,
169*9be88e75SGabriel Fernandez 	_GPIOH,
170*9be88e75SGabriel Fernandez 	_GPIOI,
171*9be88e75SGabriel Fernandez 	_PKA,
172*9be88e75SGabriel Fernandez 	_SAES_K,
173*9be88e75SGabriel Fernandez 	_CRYP1,
174*9be88e75SGabriel Fernandez 	_HASH1,
175*9be88e75SGabriel Fernandez 	_RNG1_K,
176*9be88e75SGabriel Fernandez 	_BKPSRAM,
177*9be88e75SGabriel Fernandez 	_SDMMC1_K,
178*9be88e75SGabriel Fernandez 	_SDMMC2_K,
179*9be88e75SGabriel Fernandez 	_DBGCK,
180*9be88e75SGabriel Fernandez 	_USART3_K,
181*9be88e75SGabriel Fernandez 	_UART4_K,
182*9be88e75SGabriel Fernandez 	_UART5_K,
183*9be88e75SGabriel Fernandez 	_UART7_K,
184*9be88e75SGabriel Fernandez 	_UART8_K,
185*9be88e75SGabriel Fernandez 	_USART6_K,
186*9be88e75SGabriel Fernandez 	_MCE,
187*9be88e75SGabriel Fernandez 	_FMC_K,
188*9be88e75SGabriel Fernandez 	_QSPI_K,
189*9be88e75SGabriel Fernandez #if defined(IMAGE_BL32)
190*9be88e75SGabriel Fernandez 	_LTDC,
191*9be88e75SGabriel Fernandez 	_DMA1,
192*9be88e75SGabriel Fernandez 	_DMA2,
193*9be88e75SGabriel Fernandez 	_MDMA,
194*9be88e75SGabriel Fernandez 	_ETH1MAC,
195*9be88e75SGabriel Fernandez 	_USBH,
196*9be88e75SGabriel Fernandez 	_TIM2,
197*9be88e75SGabriel Fernandez 	_TIM3,
198*9be88e75SGabriel Fernandez 	_TIM4,
199*9be88e75SGabriel Fernandez 	_TIM5,
200*9be88e75SGabriel Fernandez 	_TIM6,
201*9be88e75SGabriel Fernandez 	_TIM7,
202*9be88e75SGabriel Fernandez 	_LPTIM1_K,
203*9be88e75SGabriel Fernandez 	_SPI2_K,
204*9be88e75SGabriel Fernandez 	_SPI3_K,
205*9be88e75SGabriel Fernandez 	_SPDIF_K,
206*9be88e75SGabriel Fernandez 	_TIM1,
207*9be88e75SGabriel Fernandez 	_TIM8,
208*9be88e75SGabriel Fernandez 	_SPI1_K,
209*9be88e75SGabriel Fernandez 	_SAI1_K,
210*9be88e75SGabriel Fernandez 	_SAI2_K,
211*9be88e75SGabriel Fernandez 	_DFSDM,
212*9be88e75SGabriel Fernandez 	_FDCAN_K,
213*9be88e75SGabriel Fernandez 	_TIM13,
214*9be88e75SGabriel Fernandez 	_TIM14,
215*9be88e75SGabriel Fernandez 	_TIM16,
216*9be88e75SGabriel Fernandez 	_TIM17,
217*9be88e75SGabriel Fernandez 	_SPI4_K,
218*9be88e75SGabriel Fernandez 	_SPI5_K,
219*9be88e75SGabriel Fernandez 	_I2C1_K,
220*9be88e75SGabriel Fernandez 	_I2C2_K,
221*9be88e75SGabriel Fernandez 	_ADFSDM,
222*9be88e75SGabriel Fernandez 	_LPTIM2_K,
223*9be88e75SGabriel Fernandez 	_LPTIM3_K,
224*9be88e75SGabriel Fernandez 	_LPTIM4_K,
225*9be88e75SGabriel Fernandez 	_LPTIM5_K,
226*9be88e75SGabriel Fernandez 	_VREF,
227*9be88e75SGabriel Fernandez 	_DTS,
228*9be88e75SGabriel Fernandez 	_PMBCTRL,
229*9be88e75SGabriel Fernandez 	_HDP,
230*9be88e75SGabriel Fernandez 	_STGENRO,
231*9be88e75SGabriel Fernandez 	_DCMIPP_K,
232*9be88e75SGabriel Fernandez 	_DMAMUX1,
233*9be88e75SGabriel Fernandez 	_DMAMUX2,
234*9be88e75SGabriel Fernandez 	_DMA3,
235*9be88e75SGabriel Fernandez 	_ADC1_K,
236*9be88e75SGabriel Fernandez 	_ADC2_K,
237*9be88e75SGabriel Fernandez 	_TSC,
238*9be88e75SGabriel Fernandez 	_AXIMC,
239*9be88e75SGabriel Fernandez 	_ETH1CK,
240*9be88e75SGabriel Fernandez 	_ETH1TX,
241*9be88e75SGabriel Fernandez 	_ETH1RX,
242*9be88e75SGabriel Fernandez 	_CRC1,
243*9be88e75SGabriel Fernandez 	_ETH2CK,
244*9be88e75SGabriel Fernandez 	_ETH2TX,
245*9be88e75SGabriel Fernandez 	_ETH2RX,
246*9be88e75SGabriel Fernandez 	_ETH2MAC,
247*9be88e75SGabriel Fernandez #endif
248*9be88e75SGabriel Fernandez 	CK_LAST
249*9be88e75SGabriel Fernandez };
250*9be88e75SGabriel Fernandez 
251*9be88e75SGabriel Fernandez /* PARENT CONFIG */
252*9be88e75SGabriel Fernandez static const uint16_t RTC_src[] = {
253*9be88e75SGabriel Fernandez 	 _CK_OFF, _CK_LSE, _CK_LSI, _CK_HSE
254*9be88e75SGabriel Fernandez };
255*9be88e75SGabriel Fernandez 
256*9be88e75SGabriel Fernandez static const uint16_t MCO1_src[] = {
257*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_HSE, _CK_CSI, _CK_LSI, _CK_LSE
258*9be88e75SGabriel Fernandez };
259*9be88e75SGabriel Fernandez 
260*9be88e75SGabriel Fernandez static const uint16_t MCO2_src[] = {
261*9be88e75SGabriel Fernandez 	 _CKMPU, _CKAXI, _CKMLAHB, _PLL4P, _CK_HSE, _CK_HSI
262*9be88e75SGabriel Fernandez };
263*9be88e75SGabriel Fernandez 
264*9be88e75SGabriel Fernandez static const uint16_t PLL12_src[] = {
265*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_HSE
266*9be88e75SGabriel Fernandez };
267*9be88e75SGabriel Fernandez 
268*9be88e75SGabriel Fernandez static const uint16_t PLL3_src[] = {
269*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_HSE, _CK_CSI
270*9be88e75SGabriel Fernandez };
271*9be88e75SGabriel Fernandez 
272*9be88e75SGabriel Fernandez static const uint16_t PLL4_src[] = {
273*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_HSE, _CK_CSI, _I2SCKIN
274*9be88e75SGabriel Fernandez };
275*9be88e75SGabriel Fernandez 
276*9be88e75SGabriel Fernandez static const uint16_t MPU_src[] = {
277*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_HSE, _PLL1P, _PLL1P_DIV
278*9be88e75SGabriel Fernandez };
279*9be88e75SGabriel Fernandez 
280*9be88e75SGabriel Fernandez static const uint16_t AXI_src[] = {
281*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_HSE, _PLL2P
282*9be88e75SGabriel Fernandez };
283*9be88e75SGabriel Fernandez 
284*9be88e75SGabriel Fernandez static const uint16_t MLAHBS_src[] = {
285*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_HSE, _CK_CSI, _PLL3P
286*9be88e75SGabriel Fernandez };
287*9be88e75SGabriel Fernandez 
288*9be88e75SGabriel Fernandez static const uint16_t CKPER_src[] = {
289*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_CSI, _CK_HSE, _CK_OFF
290*9be88e75SGabriel Fernandez };
291*9be88e75SGabriel Fernandez 
292*9be88e75SGabriel Fernandez static const uint16_t I2C12_src[] = {
293*9be88e75SGabriel Fernandez 	 _PCLK1, _PLL4R, _CK_HSI, _CK_CSI
294*9be88e75SGabriel Fernandez };
295*9be88e75SGabriel Fernandez 
296*9be88e75SGabriel Fernandez static const uint16_t I2C3_src[] = {
297*9be88e75SGabriel Fernandez 	 _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
298*9be88e75SGabriel Fernandez };
299*9be88e75SGabriel Fernandez 
300*9be88e75SGabriel Fernandez static const uint16_t I2C4_src[] = {
301*9be88e75SGabriel Fernandez 	 _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
302*9be88e75SGabriel Fernandez };
303*9be88e75SGabriel Fernandez 
304*9be88e75SGabriel Fernandez static const uint16_t I2C5_src[] = {
305*9be88e75SGabriel Fernandez 	 _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
306*9be88e75SGabriel Fernandez };
307*9be88e75SGabriel Fernandez 
308*9be88e75SGabriel Fernandez static const uint16_t SPI1_src[] = {
309*9be88e75SGabriel Fernandez 	 _PLL4P, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
310*9be88e75SGabriel Fernandez };
311*9be88e75SGabriel Fernandez 
312*9be88e75SGabriel Fernandez static const uint16_t SPI23_src[] = {
313*9be88e75SGabriel Fernandez 	 _PLL4P, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
314*9be88e75SGabriel Fernandez };
315*9be88e75SGabriel Fernandez 
316*9be88e75SGabriel Fernandez static const uint16_t SPI4_src[] = {
317*9be88e75SGabriel Fernandez 	 _PCLK6, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE, _I2SCKIN
318*9be88e75SGabriel Fernandez };
319*9be88e75SGabriel Fernandez 
320*9be88e75SGabriel Fernandez static const uint16_t SPI5_src[] = {
321*9be88e75SGabriel Fernandez 	 _PCLK6, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
322*9be88e75SGabriel Fernandez };
323*9be88e75SGabriel Fernandez 
324*9be88e75SGabriel Fernandez static const uint16_t UART1_src[] = {
325*9be88e75SGabriel Fernandez 	 _PCLK6, _PLL3Q, _CK_HSI, _CK_CSI, _PLL4Q, _CK_HSE
326*9be88e75SGabriel Fernandez };
327*9be88e75SGabriel Fernandez 
328*9be88e75SGabriel Fernandez static const uint16_t UART2_src[] = {
329*9be88e75SGabriel Fernandez 	 _PCLK6, _PLL3Q, _CK_HSI, _CK_CSI, _PLL4Q, _CK_HSE
330*9be88e75SGabriel Fernandez };
331*9be88e75SGabriel Fernandez 
332*9be88e75SGabriel Fernandez static const uint16_t UART35_src[] = {
333*9be88e75SGabriel Fernandez 	 _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
334*9be88e75SGabriel Fernandez };
335*9be88e75SGabriel Fernandez 
336*9be88e75SGabriel Fernandez static const uint16_t UART4_src[] = {
337*9be88e75SGabriel Fernandez 	 _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
338*9be88e75SGabriel Fernandez };
339*9be88e75SGabriel Fernandez 
340*9be88e75SGabriel Fernandez static const uint16_t UART6_src[] = {
341*9be88e75SGabriel Fernandez 	 _PCLK2, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
342*9be88e75SGabriel Fernandez };
343*9be88e75SGabriel Fernandez 
344*9be88e75SGabriel Fernandez static const uint16_t UART78_src[] = {
345*9be88e75SGabriel Fernandez 	 _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
346*9be88e75SGabriel Fernandez };
347*9be88e75SGabriel Fernandez 
348*9be88e75SGabriel Fernandez static const uint16_t LPTIM1_src[] = {
349*9be88e75SGabriel Fernandez 	 _PCLK1, _PLL4P, _PLL3Q, _CK_LSE, _CK_LSI, _CKPER
350*9be88e75SGabriel Fernandez };
351*9be88e75SGabriel Fernandez 
352*9be88e75SGabriel Fernandez static const uint16_t LPTIM2_src[] = {
353*9be88e75SGabriel Fernandez 	 _PCLK3, _PLL4Q, _CKPER, _CK_LSE, _CK_LSI
354*9be88e75SGabriel Fernandez };
355*9be88e75SGabriel Fernandez 
356*9be88e75SGabriel Fernandez static const uint16_t LPTIM3_src[] = {
357*9be88e75SGabriel Fernandez 	 _PCLK3, _PLL4Q, _CKPER, _CK_LSE, _CK_LSI
358*9be88e75SGabriel Fernandez };
359*9be88e75SGabriel Fernandez 
360*9be88e75SGabriel Fernandez static const uint16_t LPTIM45_src[] = {
361*9be88e75SGabriel Fernandez 	 _PCLK3, _PLL4P, _PLL3Q, _CK_LSE, _CK_LSI, _CKPER
362*9be88e75SGabriel Fernandez };
363*9be88e75SGabriel Fernandez 
364*9be88e75SGabriel Fernandez static const uint16_t SAI1_src[] = {
365*9be88e75SGabriel Fernandez 	 _PLL4Q, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
366*9be88e75SGabriel Fernandez };
367*9be88e75SGabriel Fernandez 
368*9be88e75SGabriel Fernandez static const uint16_t SAI2_src[] = {
369*9be88e75SGabriel Fernandez 	 _PLL4Q, _PLL3Q, _I2SCKIN, _CKPER, _NO_ID, _PLL3R
370*9be88e75SGabriel Fernandez };
371*9be88e75SGabriel Fernandez 
372*9be88e75SGabriel Fernandez static const uint16_t FDCAN_src[] = {
373*9be88e75SGabriel Fernandez 	 _CK_HSE, _PLL3Q, _PLL4Q, _PLL4R
374*9be88e75SGabriel Fernandez };
375*9be88e75SGabriel Fernandez 
376*9be88e75SGabriel Fernandez static const uint16_t SPDIF_src[] = {
377*9be88e75SGabriel Fernandez 	 _PLL4P, _PLL3Q, _CK_HSI
378*9be88e75SGabriel Fernandez };
379*9be88e75SGabriel Fernandez 
380*9be88e75SGabriel Fernandez static const uint16_t ADC1_src[] = {
381*9be88e75SGabriel Fernandez 	 _PLL4R, _CKPER, _PLL3Q
382*9be88e75SGabriel Fernandez };
383*9be88e75SGabriel Fernandez 
384*9be88e75SGabriel Fernandez static const uint16_t ADC2_src[] = {
385*9be88e75SGabriel Fernandez 	 _PLL4R, _CKPER, _PLL3Q
386*9be88e75SGabriel Fernandez };
387*9be88e75SGabriel Fernandez 
388*9be88e75SGabriel Fernandez static const uint16_t SDMMC1_src[] = {
389*9be88e75SGabriel Fernandez 	 _CKAXI, _PLL3R, _PLL4P, _CK_HSI
390*9be88e75SGabriel Fernandez };
391*9be88e75SGabriel Fernandez 
392*9be88e75SGabriel Fernandez static const uint16_t SDMMC2_src[] = {
393*9be88e75SGabriel Fernandez 	 _CKAXI, _PLL3R, _PLL4P, _CK_HSI
394*9be88e75SGabriel Fernandez };
395*9be88e75SGabriel Fernandez 
396*9be88e75SGabriel Fernandez static const uint16_t ETH1_src[] = {
397*9be88e75SGabriel Fernandez 	 _PLL4P, _PLL3Q
398*9be88e75SGabriel Fernandez };
399*9be88e75SGabriel Fernandez 
400*9be88e75SGabriel Fernandez static const uint16_t ETH2_src[] = {
401*9be88e75SGabriel Fernandez 	 _PLL4P, _PLL3Q
402*9be88e75SGabriel Fernandez };
403*9be88e75SGabriel Fernandez 
404*9be88e75SGabriel Fernandez static const uint16_t USBPHY_src[] = {
405*9be88e75SGabriel Fernandez 	 _CK_HSE, _PLL4R, _HSE_DIV2
406*9be88e75SGabriel Fernandez };
407*9be88e75SGabriel Fernandez 
408*9be88e75SGabriel Fernandez static const uint16_t USBO_src[] = {
409*9be88e75SGabriel Fernandez 	 _PLL4R, _USB_PHY_48
410*9be88e75SGabriel Fernandez };
411*9be88e75SGabriel Fernandez 
412*9be88e75SGabriel Fernandez static const uint16_t QSPI_src[] = {
413*9be88e75SGabriel Fernandez 	 _CKAXI, _PLL3R, _PLL4P, _CKPER
414*9be88e75SGabriel Fernandez };
415*9be88e75SGabriel Fernandez 
416*9be88e75SGabriel Fernandez static const uint16_t FMC_src[] = {
417*9be88e75SGabriel Fernandez 	 _CKAXI, _PLL3R, _PLL4P, _CKPER
418*9be88e75SGabriel Fernandez };
419*9be88e75SGabriel Fernandez 
420*9be88e75SGabriel Fernandez /* Position 2 of RNG1 mux is reserved */
421*9be88e75SGabriel Fernandez static const uint16_t RNG1_src[] = {
422*9be88e75SGabriel Fernandez 	 _CK_CSI, _PLL4R, _CK_OFF, _CK_LSI
423*9be88e75SGabriel Fernandez };
424*9be88e75SGabriel Fernandez 
425*9be88e75SGabriel Fernandez static const uint16_t STGEN_src[] = {
426*9be88e75SGabriel Fernandez 	 _CK_HSI, _CK_HSE
427*9be88e75SGabriel Fernandez };
428*9be88e75SGabriel Fernandez 
429*9be88e75SGabriel Fernandez static const uint16_t DCMIPP_src[] = {
430*9be88e75SGabriel Fernandez 	 _CKAXI, _PLL2Q, _PLL4P, _CKPER
431*9be88e75SGabriel Fernandez };
432*9be88e75SGabriel Fernandez 
433*9be88e75SGabriel Fernandez static const uint16_t SAES_src[] = {
434*9be88e75SGabriel Fernandez 	 _CKAXI, _CKPER, _PLL4R, _CK_LSI
435*9be88e75SGabriel Fernandez };
436*9be88e75SGabriel Fernandez 
437*9be88e75SGabriel Fernandez #define MUX_CFG(id, src, _offset, _shift, _witdh)[id] = {\
438*9be88e75SGabriel Fernandez 	.id_parents	= src,\
439*9be88e75SGabriel Fernandez 	.num_parents	= ARRAY_SIZE(src),\
440*9be88e75SGabriel Fernandez 	.mux		= &(struct mux_cfg) {\
441*9be88e75SGabriel Fernandez 		.offset	= (_offset),\
442*9be88e75SGabriel Fernandez 		.shift	= (_shift),\
443*9be88e75SGabriel Fernandez 		.width	= (_witdh),\
444*9be88e75SGabriel Fernandez 		.bitrdy = MUX_NO_BIT_RDY,\
445*9be88e75SGabriel Fernandez 	},\
446*9be88e75SGabriel Fernandez }
447*9be88e75SGabriel Fernandez 
448*9be88e75SGabriel Fernandez #define MUX_RDY_CFG(id, src, _offset, _shift, _witdh)[id] = {\
449*9be88e75SGabriel Fernandez 	.id_parents	= src,\
450*9be88e75SGabriel Fernandez 	.num_parents	= ARRAY_SIZE(src),\
451*9be88e75SGabriel Fernandez 	.mux		= &(struct mux_cfg) {\
452*9be88e75SGabriel Fernandez 		.offset	= (_offset),\
453*9be88e75SGabriel Fernandez 		.shift	= (_shift),\
454*9be88e75SGabriel Fernandez 		.width	= (_witdh),\
455*9be88e75SGabriel Fernandez 		.bitrdy = 31,\
456*9be88e75SGabriel Fernandez 	},\
457*9be88e75SGabriel Fernandez }
458*9be88e75SGabriel Fernandez 
459*9be88e75SGabriel Fernandez static const struct parent_cfg parent_mp13[] = {
460*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_ADC1,	ADC1_src,	RCC_ADC12CKSELR, 0, 2),
461*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_ADC2,	ADC2_src,	RCC_ADC12CKSELR, 2, 2),
462*9be88e75SGabriel Fernandez 	MUX_RDY_CFG(MUX_AXI,	AXI_src,	RCC_ASSCKSELR, 0, 3),
463*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_CKPER,	CKPER_src,	RCC_CPERCKSELR, 0, 2),
464*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_DCMIPP,	DCMIPP_src,	RCC_DCMIPPCKSELR, 0, 2),
465*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_ETH1,	ETH1_src,	RCC_ETH12CKSELR, 0, 2),
466*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_ETH2,	ETH2_src,	RCC_ETH12CKSELR, 8, 2),
467*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_FDCAN,	FDCAN_src,	RCC_FDCANCKSELR, 0, 2),
468*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_FMC,	FMC_src,	RCC_FMCCKSELR, 0, 2),
469*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_I2C12,	I2C12_src,	RCC_I2C12CKSELR, 0, 3),
470*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_I2C3,	I2C3_src,	RCC_I2C345CKSELR, 0, 3),
471*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_I2C4,	I2C4_src,	RCC_I2C345CKSELR, 3, 3),
472*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_I2C5,	I2C5_src,	RCC_I2C345CKSELR, 6, 3),
473*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_LPTIM1,	LPTIM1_src,	RCC_LPTIM1CKSELR, 0, 3),
474*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_LPTIM2,	LPTIM2_src,	RCC_LPTIM23CKSELR, 0, 3),
475*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_LPTIM3,	LPTIM3_src,	RCC_LPTIM23CKSELR, 3, 3),
476*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_LPTIM45,	LPTIM45_src,	RCC_LPTIM45CKSELR, 0, 3),
477*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_MCO1,	MCO1_src,	RCC_MCO1CFGR, 0, 3),
478*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_MCO2,	MCO2_src,	RCC_MCO2CFGR, 0, 3),
479*9be88e75SGabriel Fernandez 	MUX_RDY_CFG(MUX_MLAHB,	MLAHBS_src,	RCC_MSSCKSELR, 0, 2),
480*9be88e75SGabriel Fernandez 	MUX_RDY_CFG(MUX_MPU,	MPU_src,	RCC_MPCKSELR, 0, 2),
481*9be88e75SGabriel Fernandez 	MUX_RDY_CFG(MUX_PLL12,	PLL12_src,	RCC_RCK12SELR, 0, 2),
482*9be88e75SGabriel Fernandez 	MUX_RDY_CFG(MUX_PLL3,	PLL3_src,	RCC_RCK3SELR, 0, 2),
483*9be88e75SGabriel Fernandez 	MUX_RDY_CFG(MUX_PLL4,	PLL4_src,	RCC_RCK4SELR, 0, 2),
484*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_QSPI,	QSPI_src,	RCC_QSPICKSELR, 0, 2),
485*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_RNG1,	RNG1_src,	RCC_RNG1CKSELR, 0, 2),
486*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_RTC,	RTC_src,	RCC_BDCR, 16, 2),
487*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SAES,	SAES_src,	RCC_SAESCKSELR, 0, 2),
488*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SAI1,	SAI1_src,	RCC_SAI1CKSELR, 0, 3),
489*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SAI2,	SAI2_src,	RCC_SAI2CKSELR, 0, 3),
490*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SDMMC1,	SDMMC1_src,	RCC_SDMMC12CKSELR, 0, 3),
491*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SDMMC2,	SDMMC2_src,	RCC_SDMMC12CKSELR, 3, 3),
492*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SPDIF,	SPDIF_src,	RCC_SPDIFCKSELR, 0, 2),
493*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SPI1,	SPI1_src,	RCC_SPI2S1CKSELR, 0, 3),
494*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SPI23,	SPI23_src,	RCC_SPI2S23CKSELR, 0, 3),
495*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SPI4,	SPI4_src,	RCC_SPI45CKSELR, 0, 3),
496*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_SPI5,	SPI5_src,	RCC_SPI45CKSELR, 3, 3),
497*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_STGEN,	STGEN_src,	RCC_STGENCKSELR, 0, 2),
498*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_UART1,	UART1_src,	RCC_UART12CKSELR, 0, 3),
499*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_UART2,	UART2_src,	RCC_UART12CKSELR, 3, 3),
500*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_UART35,	UART35_src,	RCC_UART35CKSELR, 0, 3),
501*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_UART4,	UART4_src,	RCC_UART4CKSELR, 0, 3),
502*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_UART6,	UART6_src,	RCC_UART6CKSELR, 0, 3),
503*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_UART78,	UART78_src,	RCC_UART78CKSELR, 0, 3),
504*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_USBO,	USBO_src,	RCC_USBCKSELR, 4, 1),
505*9be88e75SGabriel Fernandez 	MUX_CFG(MUX_USBPHY,	USBPHY_src,	RCC_USBCKSELR, 0, 2),
506*9be88e75SGabriel Fernandez };
507*9be88e75SGabriel Fernandez 
508*9be88e75SGabriel Fernandez /*
509*9be88e75SGabriel Fernandez  * GATE CONFIG
510*9be88e75SGabriel Fernandez  */
511*9be88e75SGabriel Fernandez 
512*9be88e75SGabriel Fernandez enum enum_gate_cfg {
513*9be88e75SGabriel Fernandez 	GATE_ZERO, /* reserved for no gate */
514*9be88e75SGabriel Fernandez 	GATE_LSE,
515*9be88e75SGabriel Fernandez 	GATE_RTCCK,
516*9be88e75SGabriel Fernandez 	GATE_LSI,
517*9be88e75SGabriel Fernandez 	GATE_HSI,
518*9be88e75SGabriel Fernandez 	GATE_CSI,
519*9be88e75SGabriel Fernandez 	GATE_HSE,
520*9be88e75SGabriel Fernandez 	GATE_LSI_RDY,
521*9be88e75SGabriel Fernandez 	GATE_CSI_RDY,
522*9be88e75SGabriel Fernandez 	GATE_LSE_RDY,
523*9be88e75SGabriel Fernandez 	GATE_HSE_RDY,
524*9be88e75SGabriel Fernandez 	GATE_HSI_RDY,
525*9be88e75SGabriel Fernandez 	GATE_MCO1,
526*9be88e75SGabriel Fernandez 	GATE_MCO2,
527*9be88e75SGabriel Fernandez 	GATE_DBGCK,
528*9be88e75SGabriel Fernandez 	GATE_TRACECK,
529*9be88e75SGabriel Fernandez 	GATE_PLL1,
530*9be88e75SGabriel Fernandez 	GATE_PLL1_DIVP,
531*9be88e75SGabriel Fernandez 	GATE_PLL1_DIVQ,
532*9be88e75SGabriel Fernandez 	GATE_PLL1_DIVR,
533*9be88e75SGabriel Fernandez 	GATE_PLL2,
534*9be88e75SGabriel Fernandez 	GATE_PLL2_DIVP,
535*9be88e75SGabriel Fernandez 	GATE_PLL2_DIVQ,
536*9be88e75SGabriel Fernandez 	GATE_PLL2_DIVR,
537*9be88e75SGabriel Fernandez 	GATE_PLL3,
538*9be88e75SGabriel Fernandez 	GATE_PLL3_DIVP,
539*9be88e75SGabriel Fernandez 	GATE_PLL3_DIVQ,
540*9be88e75SGabriel Fernandez 	GATE_PLL3_DIVR,
541*9be88e75SGabriel Fernandez 	GATE_PLL4,
542*9be88e75SGabriel Fernandez 	GATE_PLL4_DIVP,
543*9be88e75SGabriel Fernandez 	GATE_PLL4_DIVQ,
544*9be88e75SGabriel Fernandez 	GATE_PLL4_DIVR,
545*9be88e75SGabriel Fernandez 	GATE_DDRC1,
546*9be88e75SGabriel Fernandez 	GATE_DDRC1LP,
547*9be88e75SGabriel Fernandez 	GATE_DDRPHYC,
548*9be88e75SGabriel Fernandez 	GATE_DDRPHYCLP,
549*9be88e75SGabriel Fernandez 	GATE_DDRCAPB,
550*9be88e75SGabriel Fernandez 	GATE_DDRCAPBLP,
551*9be88e75SGabriel Fernandez 	GATE_AXIDCG,
552*9be88e75SGabriel Fernandez 	GATE_DDRPHYCAPB,
553*9be88e75SGabriel Fernandez 	GATE_DDRPHYCAPBLP,
554*9be88e75SGabriel Fernandez 	GATE_TIM2,
555*9be88e75SGabriel Fernandez 	GATE_TIM3,
556*9be88e75SGabriel Fernandez 	GATE_TIM4,
557*9be88e75SGabriel Fernandez 	GATE_TIM5,
558*9be88e75SGabriel Fernandez 	GATE_TIM6,
559*9be88e75SGabriel Fernandez 	GATE_TIM7,
560*9be88e75SGabriel Fernandez 	GATE_LPTIM1,
561*9be88e75SGabriel Fernandez 	GATE_SPI2,
562*9be88e75SGabriel Fernandez 	GATE_SPI3,
563*9be88e75SGabriel Fernandez 	GATE_USART3,
564*9be88e75SGabriel Fernandez 	GATE_UART4,
565*9be88e75SGabriel Fernandez 	GATE_UART5,
566*9be88e75SGabriel Fernandez 	GATE_UART7,
567*9be88e75SGabriel Fernandez 	GATE_UART8,
568*9be88e75SGabriel Fernandez 	GATE_I2C1,
569*9be88e75SGabriel Fernandez 	GATE_I2C2,
570*9be88e75SGabriel Fernandez 	GATE_SPDIF,
571*9be88e75SGabriel Fernandez 	GATE_TIM1,
572*9be88e75SGabriel Fernandez 	GATE_TIM8,
573*9be88e75SGabriel Fernandez 	GATE_SPI1,
574*9be88e75SGabriel Fernandez 	GATE_USART6,
575*9be88e75SGabriel Fernandez 	GATE_SAI1,
576*9be88e75SGabriel Fernandez 	GATE_SAI2,
577*9be88e75SGabriel Fernandez 	GATE_DFSDM,
578*9be88e75SGabriel Fernandez 	GATE_ADFSDM,
579*9be88e75SGabriel Fernandez 	GATE_FDCAN,
580*9be88e75SGabriel Fernandez 	GATE_LPTIM2,
581*9be88e75SGabriel Fernandez 	GATE_LPTIM3,
582*9be88e75SGabriel Fernandez 	GATE_LPTIM4,
583*9be88e75SGabriel Fernandez 	GATE_LPTIM5,
584*9be88e75SGabriel Fernandez 	GATE_VREF,
585*9be88e75SGabriel Fernandez 	GATE_DTS,
586*9be88e75SGabriel Fernandez 	GATE_PMBCTRL,
587*9be88e75SGabriel Fernandez 	GATE_HDP,
588*9be88e75SGabriel Fernandez 	GATE_SYSCFG,
589*9be88e75SGabriel Fernandez 	GATE_DCMIPP,
590*9be88e75SGabriel Fernandez 	GATE_DDRPERFM,
591*9be88e75SGabriel Fernandez 	GATE_IWDG2APB,
592*9be88e75SGabriel Fernandez 	GATE_USBPHY,
593*9be88e75SGabriel Fernandez 	GATE_STGENRO,
594*9be88e75SGabriel Fernandez 	GATE_LTDC,
595*9be88e75SGabriel Fernandez 	GATE_RTCAPB,
596*9be88e75SGabriel Fernandez 	GATE_TZC,
597*9be88e75SGabriel Fernandez 	GATE_ETZPC,
598*9be88e75SGabriel Fernandez 	GATE_IWDG1APB,
599*9be88e75SGabriel Fernandez 	GATE_BSEC,
600*9be88e75SGabriel Fernandez 	GATE_STGENC,
601*9be88e75SGabriel Fernandez 	GATE_USART1,
602*9be88e75SGabriel Fernandez 	GATE_USART2,
603*9be88e75SGabriel Fernandez 	GATE_SPI4,
604*9be88e75SGabriel Fernandez 	GATE_SPI5,
605*9be88e75SGabriel Fernandez 	GATE_I2C3,
606*9be88e75SGabriel Fernandez 	GATE_I2C4,
607*9be88e75SGabriel Fernandez 	GATE_I2C5,
608*9be88e75SGabriel Fernandez 	GATE_TIM12,
609*9be88e75SGabriel Fernandez 	GATE_TIM13,
610*9be88e75SGabriel Fernandez 	GATE_TIM14,
611*9be88e75SGabriel Fernandez 	GATE_TIM15,
612*9be88e75SGabriel Fernandez 	GATE_TIM16,
613*9be88e75SGabriel Fernandez 	GATE_TIM17,
614*9be88e75SGabriel Fernandez 	GATE_DMA1,
615*9be88e75SGabriel Fernandez 	GATE_DMA2,
616*9be88e75SGabriel Fernandez 	GATE_DMAMUX1,
617*9be88e75SGabriel Fernandez 	GATE_DMA3,
618*9be88e75SGabriel Fernandez 	GATE_DMAMUX2,
619*9be88e75SGabriel Fernandez 	GATE_ADC1,
620*9be88e75SGabriel Fernandez 	GATE_ADC2,
621*9be88e75SGabriel Fernandez 	GATE_USBO,
622*9be88e75SGabriel Fernandez 	GATE_TSC,
623*9be88e75SGabriel Fernandez 	GATE_GPIOA,
624*9be88e75SGabriel Fernandez 	GATE_GPIOB,
625*9be88e75SGabriel Fernandez 	GATE_GPIOC,
626*9be88e75SGabriel Fernandez 	GATE_GPIOD,
627*9be88e75SGabriel Fernandez 	GATE_GPIOE,
628*9be88e75SGabriel Fernandez 	GATE_GPIOF,
629*9be88e75SGabriel Fernandez 	GATE_GPIOG,
630*9be88e75SGabriel Fernandez 	GATE_GPIOH,
631*9be88e75SGabriel Fernandez 	GATE_GPIOI,
632*9be88e75SGabriel Fernandez 	GATE_PKA,
633*9be88e75SGabriel Fernandez 	GATE_SAES,
634*9be88e75SGabriel Fernandez 	GATE_CRYP1,
635*9be88e75SGabriel Fernandez 	GATE_HASH1,
636*9be88e75SGabriel Fernandez 	GATE_RNG1,
637*9be88e75SGabriel Fernandez 	GATE_BKPSRAM,
638*9be88e75SGabriel Fernandez 	GATE_AXIMC,
639*9be88e75SGabriel Fernandez 	GATE_MCE,
640*9be88e75SGabriel Fernandez 	GATE_ETH1CK,
641*9be88e75SGabriel Fernandez 	GATE_ETH1TX,
642*9be88e75SGabriel Fernandez 	GATE_ETH1RX,
643*9be88e75SGabriel Fernandez 	GATE_ETH1MAC,
644*9be88e75SGabriel Fernandez 	GATE_FMC,
645*9be88e75SGabriel Fernandez 	GATE_QSPI,
646*9be88e75SGabriel Fernandez 	GATE_SDMMC1,
647*9be88e75SGabriel Fernandez 	GATE_SDMMC2,
648*9be88e75SGabriel Fernandez 	GATE_CRC1,
649*9be88e75SGabriel Fernandez 	GATE_USBH,
650*9be88e75SGabriel Fernandez 	GATE_ETH2CK,
651*9be88e75SGabriel Fernandez 	GATE_ETH2TX,
652*9be88e75SGabriel Fernandez 	GATE_ETH2RX,
653*9be88e75SGabriel Fernandez 	GATE_ETH2MAC,
654*9be88e75SGabriel Fernandez 	GATE_MDMA,
655*9be88e75SGabriel Fernandez 
656*9be88e75SGabriel Fernandez 	LAST_GATE
657*9be88e75SGabriel Fernandez };
658*9be88e75SGabriel Fernandez 
659*9be88e75SGabriel Fernandez #define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\
660*9be88e75SGabriel Fernandez 	.offset		= (_offset),\
661*9be88e75SGabriel Fernandez 	.bit_idx	= (_bit_idx),\
662*9be88e75SGabriel Fernandez 	.set_clr	= (_offset_clr),\
663*9be88e75SGabriel Fernandez }
664*9be88e75SGabriel Fernandez 
665*9be88e75SGabriel Fernandez static const struct gate_cfg gates_mp13[LAST_GATE] = {
666*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LSE,		RCC_BDCR,	0,	0),
667*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_RTCCK,		RCC_BDCR,	20,	0),
668*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LSI,		RCC_RDLSICR,	0,	0),
669*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_HSI,		RCC_OCENSETR,	0,	1),
670*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_CSI,		RCC_OCENSETR,	4,	1),
671*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_HSE,		RCC_OCENSETR,	8,	1),
672*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LSI_RDY,		RCC_RDLSICR,	1,	0),
673*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_CSI_RDY,		RCC_OCRDYR,	4,	0),
674*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LSE_RDY,		RCC_BDCR,	2,	0),
675*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_HSE_RDY,		RCC_OCRDYR,	8,	0),
676*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_HSI_RDY,		RCC_OCRDYR,	0,	0),
677*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_MCO1,		RCC_MCO1CFGR,	12,	0),
678*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_MCO2,		RCC_MCO2CFGR,	12,	0),
679*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DBGCK,		RCC_DBGCFGR,	8,	0),
680*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TRACECK,		RCC_DBGCFGR,	9,	0),
681*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL1,		RCC_PLL1CR,	0,	0),
682*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL1_DIVP,	RCC_PLL1CR,	4,	0),
683*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL1_DIVQ,	RCC_PLL1CR,	5,	0),
684*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL1_DIVR,	RCC_PLL1CR,	6,	0),
685*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL2,		RCC_PLL2CR,	0,	0),
686*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL2_DIVP,	RCC_PLL2CR,	4,	0),
687*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL2_DIVQ,	RCC_PLL2CR,	5,	0),
688*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL2_DIVR,	RCC_PLL2CR,	6,	0),
689*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL3,		RCC_PLL3CR,	0,	0),
690*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL3_DIVP,	RCC_PLL3CR,	4,	0),
691*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL3_DIVQ,	RCC_PLL3CR,	5,	0),
692*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL3_DIVR,	RCC_PLL3CR,	6,	0),
693*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL4,		RCC_PLL4CR,	0,	0),
694*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL4_DIVP,	RCC_PLL4CR,	4,	0),
695*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL4_DIVQ,	RCC_PLL4CR,	5,	0),
696*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PLL4_DIVR,	RCC_PLL4CR,	6,	0),
697*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRC1,		RCC_DDRITFCR,	0,	0),
698*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRC1LP,		RCC_DDRITFCR,	1,	0),
699*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRPHYC,		RCC_DDRITFCR,	4,	0),
700*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRPHYCLP,	RCC_DDRITFCR,	5,	0),
701*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRCAPB,		RCC_DDRITFCR,	6,	0),
702*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRCAPBLP,	RCC_DDRITFCR,	7,	0),
703*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_AXIDCG,		RCC_DDRITFCR,	8,	0),
704*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRPHYCAPB,	RCC_DDRITFCR,	9,	0),
705*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRPHYCAPBLP,	RCC_DDRITFCR,	10,	0),
706*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM2,		RCC_MP_APB1ENSETR,	0,	1),
707*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM3,		RCC_MP_APB1ENSETR,	1,	1),
708*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM4,		RCC_MP_APB1ENSETR,	2,	1),
709*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM5,		RCC_MP_APB1ENSETR,	3,	1),
710*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM6,		RCC_MP_APB1ENSETR,	4,	1),
711*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM7,		RCC_MP_APB1ENSETR,	5,	1),
712*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LPTIM1,		RCC_MP_APB1ENSETR,	9,	1),
713*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SPI2,		RCC_MP_APB1ENSETR,	11,	1),
714*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SPI3,		RCC_MP_APB1ENSETR,	12,	1),
715*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_USART3,		RCC_MP_APB1ENSETR,	15,	1),
716*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_UART4,		RCC_MP_APB1ENSETR,	16,	1),
717*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_UART5,		RCC_MP_APB1ENSETR,	17,	1),
718*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_UART7,		RCC_MP_APB1ENSETR,	18,	1),
719*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_UART8,		RCC_MP_APB1ENSETR,	19,	1),
720*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_I2C1,		RCC_MP_APB1ENSETR,	21,	1),
721*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_I2C2,		RCC_MP_APB1ENSETR,	22,	1),
722*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SPDIF,		RCC_MP_APB1ENSETR,	26,	1),
723*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM1,		RCC_MP_APB2ENSETR,	0,	1),
724*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM8,		RCC_MP_APB2ENSETR,	1,	1),
725*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SPI1,		RCC_MP_APB2ENSETR,	8,	1),
726*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_USART6,		RCC_MP_APB2ENSETR,	13,	1),
727*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SAI1,		RCC_MP_APB2ENSETR,	16,	1),
728*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SAI2,		RCC_MP_APB2ENSETR,	17,	1),
729*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DFSDM,		RCC_MP_APB2ENSETR,	20,	1),
730*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ADFSDM,		RCC_MP_APB2ENSETR,	21,	1),
731*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_FDCAN,		RCC_MP_APB2ENSETR,	24,	1),
732*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LPTIM2,		RCC_MP_APB3ENSETR,	0,	1),
733*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LPTIM3,		RCC_MP_APB3ENSETR,	1,	1),
734*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LPTIM4,		RCC_MP_APB3ENSETR,	2,	1),
735*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LPTIM5,		RCC_MP_APB3ENSETR,	3,	1),
736*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_VREF,		RCC_MP_APB3ENSETR,	13,	1),
737*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DTS,		RCC_MP_APB3ENSETR,	16,	1),
738*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PMBCTRL,		RCC_MP_APB3ENSETR,	17,	1),
739*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_HDP,		RCC_MP_APB3ENSETR,	20,	1),
740*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SYSCFG,		RCC_MP_S_APB3ENSETR,	0,	1),
741*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DCMIPP,		RCC_MP_APB4ENSETR,	1,	1),
742*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DDRPERFM,		RCC_MP_APB4ENSETR,	8,	1),
743*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_IWDG2APB,		RCC_MP_APB4ENSETR,	15,	1),
744*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_USBPHY,		RCC_MP_APB4ENSETR,	16,	1),
745*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_STGENRO,		RCC_MP_APB4ENSETR,	20,	1),
746*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_LTDC,		RCC_MP_S_APB4ENSETR,	0,	1),
747*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_RTCAPB,		RCC_MP_APB5ENSETR,	8,	1),
748*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TZC,		RCC_MP_APB5ENSETR,	11,	1),
749*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETZPC,		RCC_MP_APB5ENSETR,	13,	1),
750*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_IWDG1APB,		RCC_MP_APB5ENSETR,	15,	1),
751*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_BSEC,		RCC_MP_APB5ENSETR,	16,	1),
752*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_STGENC,		RCC_MP_APB5ENSETR,	20,	1),
753*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_USART1,		RCC_MP_APB6ENSETR,	0,	1),
754*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_USART2,		RCC_MP_APB6ENSETR,	1,	1),
755*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SPI4,		RCC_MP_APB6ENSETR,	2,	1),
756*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SPI5,		RCC_MP_APB6ENSETR,	3,	1),
757*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_I2C3,		RCC_MP_APB6ENSETR,	4,	1),
758*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_I2C4,		RCC_MP_APB6ENSETR,	5,	1),
759*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_I2C5,		RCC_MP_APB6ENSETR,	6,	1),
760*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM12,		RCC_MP_APB6ENSETR,	7,	1),
761*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM13,		RCC_MP_APB6ENSETR,	8,	1),
762*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM14,		RCC_MP_APB6ENSETR,	9,	1),
763*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM15,		RCC_MP_APB6ENSETR,	10,	1),
764*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM16,		RCC_MP_APB6ENSETR,	11,	1),
765*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TIM17,		RCC_MP_APB6ENSETR,	12,	1),
766*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DMA1,		RCC_MP_AHB2ENSETR,	0,	1),
767*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DMA2,		RCC_MP_AHB2ENSETR,	1,	1),
768*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DMAMUX1,		RCC_MP_AHB2ENSETR,	2,	1),
769*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DMA3,		RCC_MP_AHB2ENSETR,	3,	1),
770*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_DMAMUX2,		RCC_MP_AHB2ENSETR,	4,	1),
771*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ADC1,		RCC_MP_AHB2ENSETR,	5,	1),
772*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ADC2,		RCC_MP_AHB2ENSETR,	6,	1),
773*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_USBO,		RCC_MP_AHB2ENSETR,	8,	1),
774*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_TSC,		RCC_MP_AHB4ENSETR,	15,	1),
775*9be88e75SGabriel Fernandez 
776*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOA,		RCC_MP_S_AHB4ENSETR,	0,	1),
777*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOB,		RCC_MP_S_AHB4ENSETR,	1,	1),
778*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOC,		RCC_MP_S_AHB4ENSETR,	2,	1),
779*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOD,		RCC_MP_S_AHB4ENSETR,	3,	1),
780*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOE,		RCC_MP_S_AHB4ENSETR,	4,	1),
781*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOF,		RCC_MP_S_AHB4ENSETR,	5,	1),
782*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOG,		RCC_MP_S_AHB4ENSETR,	6,	1),
783*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOH,		RCC_MP_S_AHB4ENSETR,	7,	1),
784*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_GPIOI,		RCC_MP_S_AHB4ENSETR,	8,	1),
785*9be88e75SGabriel Fernandez 
786*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_PKA,		RCC_MP_AHB5ENSETR,	2,	1),
787*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SAES,		RCC_MP_AHB5ENSETR,	3,	1),
788*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_CRYP1,		RCC_MP_AHB5ENSETR,	4,	1),
789*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_HASH1,		RCC_MP_AHB5ENSETR,	5,	1),
790*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_RNG1,		RCC_MP_AHB5ENSETR,	6,	1),
791*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_BKPSRAM,		RCC_MP_AHB5ENSETR,	8,	1),
792*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_AXIMC,		RCC_MP_AHB5ENSETR,	16,	1),
793*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_MCE,		RCC_MP_AHB6ENSETR,	1,	1),
794*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETH1CK,		RCC_MP_AHB6ENSETR,	7,	1),
795*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETH1TX,		RCC_MP_AHB6ENSETR,	8,	1),
796*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETH1RX,		RCC_MP_AHB6ENSETR,	9,	1),
797*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETH1MAC,		RCC_MP_AHB6ENSETR,	10,	1),
798*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_FMC,		RCC_MP_AHB6ENSETR,	12,	1),
799*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_QSPI,		RCC_MP_AHB6ENSETR,	14,	1),
800*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SDMMC1,		RCC_MP_AHB6ENSETR,	16,	1),
801*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_SDMMC2,		RCC_MP_AHB6ENSETR,	17,	1),
802*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_CRC1,		RCC_MP_AHB6ENSETR,	20,	1),
803*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_USBH,		RCC_MP_AHB6ENSETR,	24,	1),
804*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETH2CK,		RCC_MP_AHB6ENSETR,	27,	1),
805*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETH2TX,		RCC_MP_AHB6ENSETR,	28,	1),
806*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETH2RX,		RCC_MP_AHB6ENSETR,	29,	1),
807*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_ETH2MAC,		RCC_MP_AHB6ENSETR,	30,	1),
808*9be88e75SGabriel Fernandez 	GATE_CFG(GATE_MDMA,		RCC_MP_S_AHB6ENSETR,	0,	1),
809*9be88e75SGabriel Fernandez };
810*9be88e75SGabriel Fernandez 
811*9be88e75SGabriel Fernandez /*
812*9be88e75SGabriel Fernandez  * DIV CONFIG
813*9be88e75SGabriel Fernandez  */
814*9be88e75SGabriel Fernandez 
815*9be88e75SGabriel Fernandez static const struct clk_div_table axi_div_table[] = {
816*9be88e75SGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
817*9be88e75SGabriel Fernandez 	{ 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
818*9be88e75SGabriel Fernandez 	{ 0 },
819*9be88e75SGabriel Fernandez };
820*9be88e75SGabriel Fernandez 
821*9be88e75SGabriel Fernandez static const struct clk_div_table mlahb_div_table[] = {
822*9be88e75SGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
823*9be88e75SGabriel Fernandez 	{ 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
824*9be88e75SGabriel Fernandez 	{ 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 },
825*9be88e75SGabriel Fernandez 	{ 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
826*9be88e75SGabriel Fernandez 	{ 0 },
827*9be88e75SGabriel Fernandez };
828*9be88e75SGabriel Fernandez 
829*9be88e75SGabriel Fernandez static const struct clk_div_table apb_div_table[] = {
830*9be88e75SGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
831*9be88e75SGabriel Fernandez 	{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
832*9be88e75SGabriel Fernandez 	{ 0 },
833*9be88e75SGabriel Fernandez };
834*9be88e75SGabriel Fernandez 
835*9be88e75SGabriel Fernandez #define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\
836*9be88e75SGabriel Fernandez 		.offset	= _offset,\
837*9be88e75SGabriel Fernandez 		.shift	= _shift,\
838*9be88e75SGabriel Fernandez 		.width	= _width,\
839*9be88e75SGabriel Fernandez 		.flags	= _flags,\
840*9be88e75SGabriel Fernandez 		.table	= _table,\
841*9be88e75SGabriel Fernandez 		.bitrdy	= _bitrdy,\
842*9be88e75SGabriel Fernandez }
843*9be88e75SGabriel Fernandez 
844*9be88e75SGabriel Fernandez static const struct div_cfg dividers_mp13[] = {
845*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
846*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
847*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
848*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL2DIVR, RCC_PLL2CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
849*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL3DIVP, RCC_PLL3CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
850*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL3DIVQ, RCC_PLL3CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
851*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL3DIVR, RCC_PLL3CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
852*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL4DIVP, RCC_PLL4CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
853*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL4DIVQ, RCC_PLL4CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
854*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_PLL4DIVR, RCC_PLL4CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
855*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 0, NULL, DIV_NO_BIT_RDY),
856*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 0, axi_div_table, 31),
857*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_MLAHB, RCC_MLAHBDIVR, 0, 4, 0, mlahb_div_table, 31),
858*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31),
859*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31),
860*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31),
861*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31),
862*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, 31),
863*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_APB6, RCC_APB6DIVR, 0, 3, 0, apb_div_table, 31),
864*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, DIV_NO_BIT_RDY),
865*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
866*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
867*9be88e75SGabriel Fernandez 
868*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_HSI, RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_BIT_RDY),
869*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_BIT_RDY),
870*9be88e75SGabriel Fernandez 
871*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
872*9be88e75SGabriel Fernandez 	DIV_CFG(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL, DIV_NO_BIT_RDY),
873*9be88e75SGabriel Fernandez };
874*9be88e75SGabriel Fernandez 
875*9be88e75SGabriel Fernandez #define MAX_HSI_HZ		64000000
876*9be88e75SGabriel Fernandez #define USB_PHY_48_MHZ		48000000
877*9be88e75SGabriel Fernandez 
878*9be88e75SGabriel Fernandez #define TIMEOUT_US_200MS	U(200000)
879*9be88e75SGabriel Fernandez #define TIMEOUT_US_1S		U(1000000)
880*9be88e75SGabriel Fernandez 
881*9be88e75SGabriel Fernandez #define PLLRDY_TIMEOUT		TIMEOUT_US_200MS
882*9be88e75SGabriel Fernandez #define CLKSRC_TIMEOUT		TIMEOUT_US_200MS
883*9be88e75SGabriel Fernandez #define CLKDIV_TIMEOUT		TIMEOUT_US_200MS
884*9be88e75SGabriel Fernandez #define HSIDIV_TIMEOUT		TIMEOUT_US_200MS
885*9be88e75SGabriel Fernandez #define OSCRDY_TIMEOUT		TIMEOUT_US_1S
886*9be88e75SGabriel Fernandez 
887*9be88e75SGabriel Fernandez enum stm32_osc {
888*9be88e75SGabriel Fernandez 	OSC_HSI,
889*9be88e75SGabriel Fernandez 	OSC_HSE,
890*9be88e75SGabriel Fernandez 	OSC_CSI,
891*9be88e75SGabriel Fernandez 	OSC_LSI,
892*9be88e75SGabriel Fernandez 	OSC_LSE,
893*9be88e75SGabriel Fernandez 	OSC_I2SCKIN,
894*9be88e75SGabriel Fernandez 	NB_OSCILLATOR
895*9be88e75SGabriel Fernandez };
896*9be88e75SGabriel Fernandez 
897*9be88e75SGabriel Fernandez enum stm32mp1_pll_id {
898*9be88e75SGabriel Fernandez 	_PLL1,
899*9be88e75SGabriel Fernandez 	_PLL2,
900*9be88e75SGabriel Fernandez 	_PLL3,
901*9be88e75SGabriel Fernandez 	_PLL4,
902*9be88e75SGabriel Fernandez 	_PLL_NB
903*9be88e75SGabriel Fernandez };
904*9be88e75SGabriel Fernandez 
905*9be88e75SGabriel Fernandez enum stm32mp1_plltype {
906*9be88e75SGabriel Fernandez 	PLL_800,
907*9be88e75SGabriel Fernandez 	PLL_1600,
908*9be88e75SGabriel Fernandez 	PLL_2000,
909*9be88e75SGabriel Fernandez 	PLL_TYPE_NB
910*9be88e75SGabriel Fernandez };
911*9be88e75SGabriel Fernandez 
912*9be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXCR		0
913*9be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXCFGR1		4
914*9be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXCFGR2		8
915*9be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXFRACR		12
916*9be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXCSGR		16
917*9be88e75SGabriel Fernandez 
918*9be88e75SGabriel Fernandez struct stm32_clk_pll {
919*9be88e75SGabriel Fernandez 	enum stm32mp1_plltype plltype;
920*9be88e75SGabriel Fernandez 	uint16_t clk_id;
921*9be88e75SGabriel Fernandez 	uint16_t reg_pllxcr;
922*9be88e75SGabriel Fernandez };
923*9be88e75SGabriel Fernandez 
924*9be88e75SGabriel Fernandez struct stm32mp1_pll {
925*9be88e75SGabriel Fernandez 	uint8_t refclk_min;
926*9be88e75SGabriel Fernandez 	uint8_t refclk_max;
927*9be88e75SGabriel Fernandez };
928*9be88e75SGabriel Fernandez 
929*9be88e75SGabriel Fernandez /* Define characteristic of PLL according type */
930*9be88e75SGabriel Fernandez static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
931*9be88e75SGabriel Fernandez 	[PLL_800] = {
932*9be88e75SGabriel Fernandez 		.refclk_min = 4,
933*9be88e75SGabriel Fernandez 		.refclk_max = 16,
934*9be88e75SGabriel Fernandez 	},
935*9be88e75SGabriel Fernandez 	[PLL_1600] = {
936*9be88e75SGabriel Fernandez 		.refclk_min = 8,
937*9be88e75SGabriel Fernandez 		.refclk_max = 16,
938*9be88e75SGabriel Fernandez 	},
939*9be88e75SGabriel Fernandez 	[PLL_2000] = {
940*9be88e75SGabriel Fernandez 		.refclk_min = 8,
941*9be88e75SGabriel Fernandez 		.refclk_max = 16,
942*9be88e75SGabriel Fernandez 	},
943*9be88e75SGabriel Fernandez };
944*9be88e75SGabriel Fernandez 
945*9be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER
946*9be88e75SGabriel Fernandez static bool pll4_bootrom;
947*9be88e75SGabriel Fernandez #endif
948*9be88e75SGabriel Fernandez 
949*9be88e75SGabriel Fernandez /* RCC clock device driver private */
950*9be88e75SGabriel Fernandez static unsigned int refcounts_mp13[CK_LAST];
951*9be88e75SGabriel Fernandez 
952*9be88e75SGabriel Fernandez static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx);
953*9be88e75SGabriel Fernandez 
954*9be88e75SGabriel Fernandez #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
955*9be88e75SGabriel Fernandez static void clk_oscillator_check_bypass(struct stm32_clk_priv *priv, int idx,
956*9be88e75SGabriel Fernandez 					bool digbyp, bool bypass)
957*9be88e75SGabriel Fernandez {
958*9be88e75SGabriel Fernandez 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, idx);
959*9be88e75SGabriel Fernandez 	struct stm32_clk_bypass *bypass_data = osc_data->bypass;
960*9be88e75SGabriel Fernandez 	uintptr_t address;
961*9be88e75SGabriel Fernandez 
962*9be88e75SGabriel Fernandez 	if (bypass_data == NULL) {
963*9be88e75SGabriel Fernandez 		return;
964*9be88e75SGabriel Fernandez 	}
965*9be88e75SGabriel Fernandez 
966*9be88e75SGabriel Fernandez 	address = priv->base + bypass_data->offset;
967*9be88e75SGabriel Fernandez 	if ((mmio_read_32(address) & RCC_OCENR_HSEBYP) &&
968*9be88e75SGabriel Fernandez 	    (!(digbyp || bypass))) {
969*9be88e75SGabriel Fernandez 		panic();
970*9be88e75SGabriel Fernandez 	}
971*9be88e75SGabriel Fernandez }
972*9be88e75SGabriel Fernandez #endif
973*9be88e75SGabriel Fernandez 
974*9be88e75SGabriel Fernandez static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv)
975*9be88e75SGabriel Fernandez {
976*9be88e75SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
977*9be88e75SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE];
978*9be88e75SGabriel Fernandez 	bool digbyp =  osci->digbyp;
979*9be88e75SGabriel Fernandez 	bool bypass = osci->bypass;
980*9be88e75SGabriel Fernandez 	bool css = osci->css;
981*9be88e75SGabriel Fernandez 
982*9be88e75SGabriel Fernandez 	if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) {
983*9be88e75SGabriel Fernandez 		return;
984*9be88e75SGabriel Fernandez 	}
985*9be88e75SGabriel Fernandez 
986*9be88e75SGabriel Fernandez 	clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass);
987*9be88e75SGabriel Fernandez 
988*9be88e75SGabriel Fernandez 	_clk_stm32_enable(priv, _CK_HSE);
989*9be88e75SGabriel Fernandez 
990*9be88e75SGabriel Fernandez #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
991*9be88e75SGabriel Fernandez 	clk_oscillator_check_bypass(priv, _CK_HSE, digbyp, bypass);
992*9be88e75SGabriel Fernandez #endif
993*9be88e75SGabriel Fernandez 
994*9be88e75SGabriel Fernandez 	clk_oscillator_set_css(priv, _CK_HSE, css);
995*9be88e75SGabriel Fernandez }
996*9be88e75SGabriel Fernandez 
997*9be88e75SGabriel Fernandez static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv)
998*9be88e75SGabriel Fernandez {
999*9be88e75SGabriel Fernandez 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE);
1000*9be88e75SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1001*9be88e75SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
1002*9be88e75SGabriel Fernandez 	bool digbyp =  osci->digbyp;
1003*9be88e75SGabriel Fernandez 	bool bypass = osci->bypass;
1004*9be88e75SGabriel Fernandez 	uint8_t drive = osci->drive;
1005*9be88e75SGabriel Fernandez 
1006*9be88e75SGabriel Fernandez 	if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) {
1007*9be88e75SGabriel Fernandez 		return;
1008*9be88e75SGabriel Fernandez 	}
1009*9be88e75SGabriel Fernandez 
1010*9be88e75SGabriel Fernandez 	clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
1011*9be88e75SGabriel Fernandez 
1012*9be88e75SGabriel Fernandez 	clk_oscillator_set_drive(priv, _CK_LSE, drive);
1013*9be88e75SGabriel Fernandez 
1014*9be88e75SGabriel Fernandez 	_clk_stm32_gate_enable(priv, osc_data->gate_id);
1015*9be88e75SGabriel Fernandez }
1016*9be88e75SGabriel Fernandez 
1017*9be88e75SGabriel Fernandez static int stm32mp1_set_hsidiv(uint8_t hsidiv)
1018*9be88e75SGabriel Fernandez {
1019*9be88e75SGabriel Fernandez 	uint64_t timeout;
1020*9be88e75SGabriel Fernandez 	uintptr_t rcc_base = stm32mp_rcc_base();
1021*9be88e75SGabriel Fernandez 	uintptr_t address = rcc_base + RCC_OCRDYR;
1022*9be88e75SGabriel Fernandez 
1023*9be88e75SGabriel Fernandez 	mmio_clrsetbits_32(rcc_base + RCC_HSICFGR,
1024*9be88e75SGabriel Fernandez 			   RCC_HSICFGR_HSIDIV_MASK,
1025*9be88e75SGabriel Fernandez 			   RCC_HSICFGR_HSIDIV_MASK & (uint32_t)hsidiv);
1026*9be88e75SGabriel Fernandez 
1027*9be88e75SGabriel Fernandez 	timeout = timeout_init_us(HSIDIV_TIMEOUT);
1028*9be88e75SGabriel Fernandez 	while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) {
1029*9be88e75SGabriel Fernandez 		if (timeout_elapsed(timeout)) {
1030*9be88e75SGabriel Fernandez 			ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
1031*9be88e75SGabriel Fernandez 			      address, mmio_read_32(address));
1032*9be88e75SGabriel Fernandez 			return -ETIMEDOUT;
1033*9be88e75SGabriel Fernandez 		}
1034*9be88e75SGabriel Fernandez 	}
1035*9be88e75SGabriel Fernandez 
1036*9be88e75SGabriel Fernandez 	return 0;
1037*9be88e75SGabriel Fernandez }
1038*9be88e75SGabriel Fernandez 
1039*9be88e75SGabriel Fernandez static int stm32mp1_hsidiv(unsigned long hsifreq)
1040*9be88e75SGabriel Fernandez {
1041*9be88e75SGabriel Fernandez 	uint8_t hsidiv;
1042*9be88e75SGabriel Fernandez 	uint32_t hsidivfreq = MAX_HSI_HZ;
1043*9be88e75SGabriel Fernandez 
1044*9be88e75SGabriel Fernandez 	for (hsidiv = 0; hsidiv < 4U; hsidiv++) {
1045*9be88e75SGabriel Fernandez 		if (hsidivfreq == hsifreq) {
1046*9be88e75SGabriel Fernandez 			break;
1047*9be88e75SGabriel Fernandez 		}
1048*9be88e75SGabriel Fernandez 
1049*9be88e75SGabriel Fernandez 		hsidivfreq /= 2U;
1050*9be88e75SGabriel Fernandez 	}
1051*9be88e75SGabriel Fernandez 
1052*9be88e75SGabriel Fernandez 	if (hsidiv == 4U) {
1053*9be88e75SGabriel Fernandez 		ERROR("Invalid clk-hsi frequency\n");
1054*9be88e75SGabriel Fernandez 		return -EINVAL;
1055*9be88e75SGabriel Fernandez 	}
1056*9be88e75SGabriel Fernandez 
1057*9be88e75SGabriel Fernandez 	if (hsidiv != 0U) {
1058*9be88e75SGabriel Fernandez 		return stm32mp1_set_hsidiv(hsidiv);
1059*9be88e75SGabriel Fernandez 	}
1060*9be88e75SGabriel Fernandez 
1061*9be88e75SGabriel Fernandez 	return 0;
1062*9be88e75SGabriel Fernandez }
1063*9be88e75SGabriel Fernandez 
1064*9be88e75SGabriel Fernandez static int stm32_clk_oscillators_lse_set_css(struct stm32_clk_priv *priv)
1065*9be88e75SGabriel Fernandez {
1066*9be88e75SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1067*9be88e75SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
1068*9be88e75SGabriel Fernandez 
1069*9be88e75SGabriel Fernandez 	clk_oscillator_set_css(priv, _CK_LSE, osci->css);
1070*9be88e75SGabriel Fernandez 
1071*9be88e75SGabriel Fernandez 	return 0;
1072*9be88e75SGabriel Fernandez }
1073*9be88e75SGabriel Fernandez 
1074*9be88e75SGabriel Fernandez static int stm32mp1_come_back_to_hsi(void)
1075*9be88e75SGabriel Fernandez {
1076*9be88e75SGabriel Fernandez 	int ret;
1077*9be88e75SGabriel Fernandez 	struct stm32_clk_priv *priv = clk_stm32_get_priv();
1078*9be88e75SGabriel Fernandez 
1079*9be88e75SGabriel Fernandez 	/* Come back to HSI */
1080*9be88e75SGabriel Fernandez 	ret = _clk_stm32_set_parent(priv, _CKMPU, _CK_HSI);
1081*9be88e75SGabriel Fernandez 	if (ret != 0) {
1082*9be88e75SGabriel Fernandez 		return ret;
1083*9be88e75SGabriel Fernandez 	}
1084*9be88e75SGabriel Fernandez 
1085*9be88e75SGabriel Fernandez 	ret = _clk_stm32_set_parent(priv, _CKAXI, _CK_HSI);
1086*9be88e75SGabriel Fernandez 	if (ret != 0) {
1087*9be88e75SGabriel Fernandez 		return ret;
1088*9be88e75SGabriel Fernandez 	}
1089*9be88e75SGabriel Fernandez 
1090*9be88e75SGabriel Fernandez 	ret = _clk_stm32_set_parent(priv, _CKMLAHB, _CK_HSI);
1091*9be88e75SGabriel Fernandez 	if (ret != 0) {
1092*9be88e75SGabriel Fernandez 		return ret;
1093*9be88e75SGabriel Fernandez 	}
1094*9be88e75SGabriel Fernandez 
1095*9be88e75SGabriel Fernandez 	return 0;
1096*9be88e75SGabriel Fernandez }
1097*9be88e75SGabriel Fernandez 
1098*9be88e75SGabriel Fernandez static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data)
1099*9be88e75SGabriel Fernandez {
1100*9be88e75SGabriel Fernandez 	unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
1101*9be88e75SGabriel Fernandez 
1102*9be88e75SGabriel Fernandez 	return clk_get_index(priv, binding_id);
1103*9be88e75SGabriel Fernandez }
1104*9be88e75SGabriel Fernandez 
1105*9be88e75SGabriel Fernandez static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
1106*9be88e75SGabriel Fernandez {
1107*9be88e75SGabriel Fernandez 	int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
1108*9be88e75SGabriel Fernandez 	int enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT;
1109*9be88e75SGabriel Fernandez 	int clk_id;
1110*9be88e75SGabriel Fernandez 	int ret;
1111*9be88e75SGabriel Fernandez 
1112*9be88e75SGabriel Fernandez 	clk_id = stm32_clk_configure_clk_get_binding_id(priv, data);
1113*9be88e75SGabriel Fernandez 	if (clk_id < 0) {
1114*9be88e75SGabriel Fernandez 		return clk_id;
1115*9be88e75SGabriel Fernandez 	}
1116*9be88e75SGabriel Fernandez 
1117*9be88e75SGabriel Fernandez 	ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel);
1118*9be88e75SGabriel Fernandez 	if (ret != 0) {
1119*9be88e75SGabriel Fernandez 		return ret;
1120*9be88e75SGabriel Fernandez 	}
1121*9be88e75SGabriel Fernandez 
1122*9be88e75SGabriel Fernandez 	if (enable) {
1123*9be88e75SGabriel Fernandez 		clk_stm32_enable_call_ops(priv, clk_id);
1124*9be88e75SGabriel Fernandez 	} else {
1125*9be88e75SGabriel Fernandez 		clk_stm32_disable_call_ops(priv, clk_id);
1126*9be88e75SGabriel Fernandez 	}
1127*9be88e75SGabriel Fernandez 
1128*9be88e75SGabriel Fernandez 	return 0;
1129*9be88e75SGabriel Fernandez }
1130*9be88e75SGabriel Fernandez 
1131*9be88e75SGabriel Fernandez static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data)
1132*9be88e75SGabriel Fernandez {
1133*9be88e75SGabriel Fernandez 	int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
1134*9be88e75SGabriel Fernandez 	int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
1135*9be88e75SGabriel Fernandez 
1136*9be88e75SGabriel Fernandez 	return clk_mux_set_parent(priv, mux, sel);
1137*9be88e75SGabriel Fernandez }
1138*9be88e75SGabriel Fernandez 
1139*9be88e75SGabriel Fernandez static int stm32_clk_dividers_configure(struct stm32_clk_priv *priv)
1140*9be88e75SGabriel Fernandez {
1141*9be88e75SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1142*9be88e75SGabriel Fernandez 	uint32_t i;
1143*9be88e75SGabriel Fernandez 
1144*9be88e75SGabriel Fernandez 	for (i = 0; i < pdata->nclkdiv; i++) {
1145*9be88e75SGabriel Fernandez 		int div_id, div_n;
1146*9be88e75SGabriel Fernandez 		int val;
1147*9be88e75SGabriel Fernandez 		int ret;
1148*9be88e75SGabriel Fernandez 
1149*9be88e75SGabriel Fernandez 		val = pdata->clkdiv[i] & CMD_DATA_MASK;
1150*9be88e75SGabriel Fernandez 		div_id = (val & DIV_ID_MASK) >> DIV_ID_SHIFT;
1151*9be88e75SGabriel Fernandez 		div_n = (val & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
1152*9be88e75SGabriel Fernandez 
1153*9be88e75SGabriel Fernandez 		ret = clk_stm32_set_div(priv, div_id, div_n);
1154*9be88e75SGabriel Fernandez 		if (ret != 0) {
1155*9be88e75SGabriel Fernandez 			return ret;
1156*9be88e75SGabriel Fernandez 		}
1157*9be88e75SGabriel Fernandez 	}
1158*9be88e75SGabriel Fernandez 
1159*9be88e75SGabriel Fernandez 	return 0;
1160*9be88e75SGabriel Fernandez }
1161*9be88e75SGabriel Fernandez 
1162*9be88e75SGabriel Fernandez static int stm32_clk_source_configure(struct stm32_clk_priv *priv)
1163*9be88e75SGabriel Fernandez {
1164*9be88e75SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1165*9be88e75SGabriel Fernandez 	bool ckper_disabled = false;
1166*9be88e75SGabriel Fernandez 	int clk_id;
1167*9be88e75SGabriel Fernandez 	int ret;
1168*9be88e75SGabriel Fernandez 	uint32_t i;
1169*9be88e75SGabriel Fernandez 
1170*9be88e75SGabriel Fernandez 	for (i = 0; i < pdata->nclksrc; i++) {
1171*9be88e75SGabriel Fernandez 		uint32_t val = pdata->clksrc[i];
1172*9be88e75SGabriel Fernandez 		uint32_t cmd, cmd_data;
1173*9be88e75SGabriel Fernandez 
1174*9be88e75SGabriel Fernandez 		if (val == (uint32_t)CLK_CKPER_DISABLED) {
1175*9be88e75SGabriel Fernandez 			ckper_disabled = true;
1176*9be88e75SGabriel Fernandez 			continue;
1177*9be88e75SGabriel Fernandez 		}
1178*9be88e75SGabriel Fernandez 
1179*9be88e75SGabriel Fernandez 		if (val == (uint32_t)CLK_RTC_DISABLED) {
1180*9be88e75SGabriel Fernandez 			continue;
1181*9be88e75SGabriel Fernandez 		}
1182*9be88e75SGabriel Fernandez 
1183*9be88e75SGabriel Fernandez 		cmd = (val & CMD_MASK) >> CMD_SHIFT;
1184*9be88e75SGabriel Fernandez 		cmd_data = val & ~CMD_MASK;
1185*9be88e75SGabriel Fernandez 
1186*9be88e75SGabriel Fernandez 		switch (cmd) {
1187*9be88e75SGabriel Fernandez 		case CMD_MUX:
1188*9be88e75SGabriel Fernandez 			ret = stm32_clk_configure_mux(priv, cmd_data);
1189*9be88e75SGabriel Fernandez 			break;
1190*9be88e75SGabriel Fernandez 
1191*9be88e75SGabriel Fernandez 		case CMD_CLK:
1192*9be88e75SGabriel Fernandez 			clk_id = stm32_clk_configure_clk_get_binding_id(priv, cmd_data);
1193*9be88e75SGabriel Fernandez 
1194*9be88e75SGabriel Fernandez 			if (clk_id == _RTCCK) {
1195*9be88e75SGabriel Fernandez 				if ((_clk_stm32_is_enabled(priv, _RTCCK) == true)) {
1196*9be88e75SGabriel Fernandez 					continue;
1197*9be88e75SGabriel Fernandez 				}
1198*9be88e75SGabriel Fernandez 			}
1199*9be88e75SGabriel Fernandez 
1200*9be88e75SGabriel Fernandez 			ret = stm32_clk_configure_clk(priv, cmd_data);
1201*9be88e75SGabriel Fernandez 			break;
1202*9be88e75SGabriel Fernandez 		default:
1203*9be88e75SGabriel Fernandez 			ret = -EINVAL;
1204*9be88e75SGabriel Fernandez 			break;
1205*9be88e75SGabriel Fernandez 		}
1206*9be88e75SGabriel Fernandez 
1207*9be88e75SGabriel Fernandez 		if (ret != 0) {
1208*9be88e75SGabriel Fernandez 			return ret;
1209*9be88e75SGabriel Fernandez 		}
1210*9be88e75SGabriel Fernandez 	}
1211*9be88e75SGabriel Fernandez 
1212*9be88e75SGabriel Fernandez 	/*
1213*9be88e75SGabriel Fernandez 	 * CKPER is source for some peripheral clocks
1214*9be88e75SGabriel Fernandez 	 * (FMC-NAND / QPSI-NOR) and switching source is allowed
1215*9be88e75SGabriel Fernandez 	 * only if previous clock is still ON
1216*9be88e75SGabriel Fernandez 	 * => deactivate CKPER only after switching clock
1217*9be88e75SGabriel Fernandez 	 */
1218*9be88e75SGabriel Fernandez 	if (ckper_disabled) {
1219*9be88e75SGabriel Fernandez 		ret = stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED & CMD_MASK);
1220*9be88e75SGabriel Fernandez 		if (ret != 0) {
1221*9be88e75SGabriel Fernandez 			return ret;
1222*9be88e75SGabriel Fernandez 		}
1223*9be88e75SGabriel Fernandez 	}
1224*9be88e75SGabriel Fernandez 
1225*9be88e75SGabriel Fernandez 	return 0;
1226*9be88e75SGabriel Fernandez }
1227*9be88e75SGabriel Fernandez 
1228*9be88e75SGabriel Fernandez static int stm32_clk_stgen_configure(struct stm32_clk_priv *priv, int id)
1229*9be88e75SGabriel Fernandez {
1230*9be88e75SGabriel Fernandez 	unsigned long stgen_freq;
1231*9be88e75SGabriel Fernandez 
1232*9be88e75SGabriel Fernandez 	stgen_freq = _clk_stm32_get_rate(priv, id);
1233*9be88e75SGabriel Fernandez 
1234*9be88e75SGabriel Fernandez 	stm32mp_stgen_config(stgen_freq);
1235*9be88e75SGabriel Fernandez 
1236*9be88e75SGabriel Fernandez 	return 0;
1237*9be88e75SGabriel Fernandez }
1238*9be88e75SGabriel Fernandez 
1239*9be88e75SGabriel Fernandez #define CLK_PLL_CFG(_idx, _clk_id, _type, _reg)\
1240*9be88e75SGabriel Fernandez 	[(_idx)] = {\
1241*9be88e75SGabriel Fernandez 		.clk_id = (_clk_id),\
1242*9be88e75SGabriel Fernandez 		.plltype = (_type),\
1243*9be88e75SGabriel Fernandez 		.reg_pllxcr = (_reg),\
1244*9be88e75SGabriel Fernandez 	}
1245*9be88e75SGabriel Fernandez 
1246*9be88e75SGabriel Fernandez static int clk_stm32_pll_compute_cfgr1(struct stm32_clk_priv *priv,
1247*9be88e75SGabriel Fernandez 				       const struct stm32_clk_pll *pll,
1248*9be88e75SGabriel Fernandez 				       struct stm32_pll_vco *vco,
1249*9be88e75SGabriel Fernandez 				       uint32_t *value)
1250*9be88e75SGabriel Fernandez {
1251*9be88e75SGabriel Fernandez 	uint32_t divm = vco->div_mn[PLL_CFG_M];
1252*9be88e75SGabriel Fernandez 	uint32_t divn = vco->div_mn[PLL_CFG_N];
1253*9be88e75SGabriel Fernandez 	unsigned long prate = 0UL;
1254*9be88e75SGabriel Fernandez 	unsigned long refclk = 0UL;
1255*9be88e75SGabriel Fernandez 
1256*9be88e75SGabriel Fernandez 	prate = _clk_stm32_get_parent_rate(priv, pll->clk_id);
1257*9be88e75SGabriel Fernandez 	refclk = prate / (divm + 1U);
1258*9be88e75SGabriel Fernandez 
1259*9be88e75SGabriel Fernandez 	if ((refclk < (stm32mp1_pll[pll->plltype].refclk_min * 1000000U)) ||
1260*9be88e75SGabriel Fernandez 	    (refclk > (stm32mp1_pll[pll->plltype].refclk_max * 1000000U))) {
1261*9be88e75SGabriel Fernandez 		return -EINVAL;
1262*9be88e75SGabriel Fernandez 	}
1263*9be88e75SGabriel Fernandez 
1264*9be88e75SGabriel Fernandez 	*value = 0;
1265*9be88e75SGabriel Fernandez 
1266*9be88e75SGabriel Fernandez 	if ((pll->plltype == PLL_800) && (refclk >= 8000000U)) {
1267*9be88e75SGabriel Fernandez 		*value = 1U << RCC_PLLNCFGR1_IFRGE_SHIFT;
1268*9be88e75SGabriel Fernandez 	}
1269*9be88e75SGabriel Fernandez 
1270*9be88e75SGabriel Fernandez 	*value |= (divn << RCC_PLLNCFGR1_DIVN_SHIFT) & RCC_PLLNCFGR1_DIVN_MASK;
1271*9be88e75SGabriel Fernandez 	*value |= (divm << RCC_PLLNCFGR1_DIVM_SHIFT) & RCC_PLLNCFGR1_DIVM_MASK;
1272*9be88e75SGabriel Fernandez 
1273*9be88e75SGabriel Fernandez 	return 0;
1274*9be88e75SGabriel Fernandez }
1275*9be88e75SGabriel Fernandez 
1276*9be88e75SGabriel Fernandez static uint32_t  clk_stm32_pll_compute_cfgr2(struct stm32_pll_output *out)
1277*9be88e75SGabriel Fernandez {
1278*9be88e75SGabriel Fernandez 	uint32_t value = 0;
1279*9be88e75SGabriel Fernandez 
1280*9be88e75SGabriel Fernandez 	value |= (out->output[PLL_CFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) & RCC_PLLNCFGR2_DIVP_MASK;
1281*9be88e75SGabriel Fernandez 	value |= (out->output[PLL_CFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) & RCC_PLLNCFGR2_DIVQ_MASK;
1282*9be88e75SGabriel Fernandez 	value |= (out->output[PLL_CFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) & RCC_PLLNCFGR2_DIVR_MASK;
1283*9be88e75SGabriel Fernandez 
1284*9be88e75SGabriel Fernandez 	return value;
1285*9be88e75SGabriel Fernandez }
1286*9be88e75SGabriel Fernandez 
1287*9be88e75SGabriel Fernandez static void clk_stm32_pll_config_vco(struct stm32_clk_priv *priv,
1288*9be88e75SGabriel Fernandez 				     const struct stm32_clk_pll *pll,
1289*9be88e75SGabriel Fernandez 				     struct stm32_pll_vco *vco)
1290*9be88e75SGabriel Fernandez {
1291*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1292*9be88e75SGabriel Fernandez 	uint32_t value = 0;
1293*9be88e75SGabriel Fernandez 
1294*9be88e75SGabriel Fernandez 	if (clk_stm32_pll_compute_cfgr1(priv, pll, vco, &value) != 0) {
1295*9be88e75SGabriel Fernandez 		ERROR("Invalid Vref clock !\n");
1296*9be88e75SGabriel Fernandez 		panic();
1297*9be88e75SGabriel Fernandez 	}
1298*9be88e75SGabriel Fernandez 
1299*9be88e75SGabriel Fernandez 	/* Write N / M / IFREGE fields */
1300*9be88e75SGabriel Fernandez 	mmio_write_32(pll_base + RCC_OFFSET_PLLXCFGR1, value);
1301*9be88e75SGabriel Fernandez 
1302*9be88e75SGabriel Fernandez 	/* Fractional configuration */
1303*9be88e75SGabriel Fernandez 	mmio_write_32(pll_base + RCC_OFFSET_PLLXFRACR, 0);
1304*9be88e75SGabriel Fernandez 
1305*9be88e75SGabriel Fernandez 	/* Frac must be enabled only once its configuration is loaded */
1306*9be88e75SGabriel Fernandez 	mmio_write_32(pll_base + RCC_OFFSET_PLLXFRACR, vco->frac << RCC_PLLNFRACR_FRACV_SHIFT);
1307*9be88e75SGabriel Fernandez 	mmio_setbits_32(pll_base + RCC_OFFSET_PLLXFRACR, RCC_PLLNFRACR_FRACLE);
1308*9be88e75SGabriel Fernandez }
1309*9be88e75SGabriel Fernandez 
1310*9be88e75SGabriel Fernandez static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv,
1311*9be88e75SGabriel Fernandez 				     const struct stm32_clk_pll *pll,
1312*9be88e75SGabriel Fernandez 				     struct stm32_pll_vco *vco)
1313*9be88e75SGabriel Fernandez {
1314*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1315*9be88e75SGabriel Fernandez 	uint32_t mod_per = 0;
1316*9be88e75SGabriel Fernandez 	uint32_t inc_step = 0;
1317*9be88e75SGabriel Fernandez 	uint32_t sscg_mode = 0;
1318*9be88e75SGabriel Fernandez 	uint32_t value = 0;
1319*9be88e75SGabriel Fernandez 
1320*9be88e75SGabriel Fernandez 	if (!vco->csg_enabled) {
1321*9be88e75SGabriel Fernandez 		return;
1322*9be88e75SGabriel Fernandez 	}
1323*9be88e75SGabriel Fernandez 
1324*9be88e75SGabriel Fernandez 	mod_per = vco->csg[PLL_CSG_MOD_PER];
1325*9be88e75SGabriel Fernandez 	inc_step = vco->csg[PLL_CSG_INC_STEP];
1326*9be88e75SGabriel Fernandez 	sscg_mode = vco->csg[PLL_CSG_SSCG_MODE];
1327*9be88e75SGabriel Fernandez 
1328*9be88e75SGabriel Fernandez 	value |= (mod_per << RCC_PLLNCSGR_MOD_PER_SHIFT) & RCC_PLLNCSGR_MOD_PER_MASK;
1329*9be88e75SGabriel Fernandez 	value |= (inc_step << RCC_PLLNCSGR_INC_STEP_SHIFT) & RCC_PLLNCSGR_INC_STEP_MASK;
1330*9be88e75SGabriel Fernandez 	value |= (sscg_mode << RCC_PLLNCSGR_SSCG_MODE_SHIFT) & RCC_PLLNCSGR_SSCG_MODE_MASK;
1331*9be88e75SGabriel Fernandez 
1332*9be88e75SGabriel Fernandez 	mmio_write_32(pll_base + RCC_OFFSET_PLLXCSGR, value);
1333*9be88e75SGabriel Fernandez 	mmio_setbits_32(pll_base + RCC_OFFSET_PLLXCR, RCC_PLLNCR_SSCG_CTRL);
1334*9be88e75SGabriel Fernandez }
1335*9be88e75SGabriel Fernandez 
1336*9be88e75SGabriel Fernandez static void clk_stm32_pll_config_out(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll,
1337*9be88e75SGabriel Fernandez 				     struct stm32_pll_output *out)
1338*9be88e75SGabriel Fernandez {
1339*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1340*9be88e75SGabriel Fernandez 	uint32_t value = 0;
1341*9be88e75SGabriel Fernandez 
1342*9be88e75SGabriel Fernandez 	value = clk_stm32_pll_compute_cfgr2(out);
1343*9be88e75SGabriel Fernandez 
1344*9be88e75SGabriel Fernandez 	mmio_write_32(pll_base + RCC_OFFSET_PLLXCFGR2, value);
1345*9be88e75SGabriel Fernandez }
1346*9be88e75SGabriel Fernandez 
1347*9be88e75SGabriel Fernandez static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx)
1348*9be88e75SGabriel Fernandez {
1349*9be88e75SGabriel Fernandez 	struct stm32_clk_priv *priv = clk_stm32_get_priv();
1350*9be88e75SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1351*9be88e75SGabriel Fernandez 
1352*9be88e75SGabriel Fernandez 	return &pdata->pll[pll_idx];
1353*9be88e75SGabriel Fernandez }
1354*9be88e75SGabriel Fernandez 
1355*9be88e75SGabriel Fernandez static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
1356*9be88e75SGabriel Fernandez {
1357*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1358*9be88e75SGabriel Fernandez 
1359*9be88e75SGabriel Fernandez 	return ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLON) != 0U);
1360*9be88e75SGabriel Fernandez }
1361*9be88e75SGabriel Fernandez 
1362*9be88e75SGabriel Fernandez static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
1363*9be88e75SGabriel Fernandez {
1364*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1365*9be88e75SGabriel Fernandez 
1366*9be88e75SGabriel Fernandez 	/* Preserve RCC_PLLNCR_SSCG_CTRL value */
1367*9be88e75SGabriel Fernandez 	mmio_clrsetbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN,
1368*9be88e75SGabriel Fernandez 			   RCC_PLLNCR_PLLON);
1369*9be88e75SGabriel Fernandez }
1370*9be88e75SGabriel Fernandez 
1371*9be88e75SGabriel Fernandez static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
1372*9be88e75SGabriel Fernandez {
1373*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1374*9be88e75SGabriel Fernandez 
1375*9be88e75SGabriel Fernandez 	/* Stop all output */
1376*9be88e75SGabriel Fernandez 	mmio_clrbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
1377*9be88e75SGabriel Fernandez 
1378*9be88e75SGabriel Fernandez 	/* Stop PLL */
1379*9be88e75SGabriel Fernandez 	mmio_clrbits_32(pll_base, RCC_PLLNCR_PLLON);
1380*9be88e75SGabriel Fernandez }
1381*9be88e75SGabriel Fernandez 
1382*9be88e75SGabriel Fernandez static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv,
1383*9be88e75SGabriel Fernandez 					const struct stm32_clk_pll *pll)
1384*9be88e75SGabriel Fernandez {
1385*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1386*9be88e75SGabriel Fernandez 	uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
1387*9be88e75SGabriel Fernandez 
1388*9be88e75SGabriel Fernandez 	/* Wait PLL lock */
1389*9be88e75SGabriel Fernandez 	while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) == 0U) {
1390*9be88e75SGabriel Fernandez 		if (timeout_elapsed(timeout)) {
1391*9be88e75SGabriel Fernandez 			ERROR("%d clock start failed @ 0x%x: 0x%x\n",
1392*9be88e75SGabriel Fernandez 			      pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
1393*9be88e75SGabriel Fernandez 			return -EINVAL;
1394*9be88e75SGabriel Fernandez 		}
1395*9be88e75SGabriel Fernandez 	}
1396*9be88e75SGabriel Fernandez 
1397*9be88e75SGabriel Fernandez 	return 0;
1398*9be88e75SGabriel Fernandez }
1399*9be88e75SGabriel Fernandez 
1400*9be88e75SGabriel Fernandez static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv,
1401*9be88e75SGabriel Fernandez 					 const struct stm32_clk_pll *pll)
1402*9be88e75SGabriel Fernandez {
1403*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1404*9be88e75SGabriel Fernandez 	uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
1405*9be88e75SGabriel Fernandez 
1406*9be88e75SGabriel Fernandez 	/* Wait PLL lock */
1407*9be88e75SGabriel Fernandez 	while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) != 0U) {
1408*9be88e75SGabriel Fernandez 		if (timeout_elapsed(timeout)) {
1409*9be88e75SGabriel Fernandez 			ERROR("%d clock stop failed @ 0x%x: 0x%x\n",
1410*9be88e75SGabriel Fernandez 			      pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
1411*9be88e75SGabriel Fernandez 			return -EINVAL;
1412*9be88e75SGabriel Fernandez 		}
1413*9be88e75SGabriel Fernandez 	}
1414*9be88e75SGabriel Fernandez 
1415*9be88e75SGabriel Fernandez 	return 0;
1416*9be88e75SGabriel Fernandez }
1417*9be88e75SGabriel Fernandez 
1418*9be88e75SGabriel Fernandez static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
1419*9be88e75SGabriel Fernandez {
1420*9be88e75SGabriel Fernandez 	if (_clk_stm32_pll_is_enabled(priv, pll)) {
1421*9be88e75SGabriel Fernandez 		return 0;
1422*9be88e75SGabriel Fernandez 	}
1423*9be88e75SGabriel Fernandez 
1424*9be88e75SGabriel Fernandez 	/* Preserve RCC_PLLNCR_SSCG_CTRL value */
1425*9be88e75SGabriel Fernandez 	_clk_stm32_pll_set_on(priv, pll);
1426*9be88e75SGabriel Fernandez 
1427*9be88e75SGabriel Fernandez 	/* Wait PLL lock */
1428*9be88e75SGabriel Fernandez 	return _clk_stm32_pll_wait_ready_on(priv, pll);
1429*9be88e75SGabriel Fernandez }
1430*9be88e75SGabriel Fernandez 
1431*9be88e75SGabriel Fernandez static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
1432*9be88e75SGabriel Fernandez {
1433*9be88e75SGabriel Fernandez 	if (!_clk_stm32_pll_is_enabled(priv, pll)) {
1434*9be88e75SGabriel Fernandez 		return;
1435*9be88e75SGabriel Fernandez 	}
1436*9be88e75SGabriel Fernandez 
1437*9be88e75SGabriel Fernandez 	/* Stop all outputs and the PLL */
1438*9be88e75SGabriel Fernandez 	_clk_stm32_pll_set_off(priv, pll);
1439*9be88e75SGabriel Fernandez 
1440*9be88e75SGabriel Fernandez 	/* Wait PLL stopped */
1441*9be88e75SGabriel Fernandez 	_clk_stm32_pll_wait_ready_off(priv, pll);
1442*9be88e75SGabriel Fernandez }
1443*9be88e75SGabriel Fernandez 
1444*9be88e75SGabriel Fernandez static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx,
1445*9be88e75SGabriel Fernandez 			       struct stm32_pll_dt_cfg *pll_conf)
1446*9be88e75SGabriel Fernandez {
1447*9be88e75SGabriel Fernandez 	const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_idx);
1448*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1449*9be88e75SGabriel Fernandez 	int ret = 0;
1450*9be88e75SGabriel Fernandez 
1451*9be88e75SGabriel Fernandez 	/* Configure PLLs source */
1452*9be88e75SGabriel Fernandez 	ret = stm32_clk_configure_mux(priv, pll_conf->vco.src);
1453*9be88e75SGabriel Fernandez 	if (ret) {
1454*9be88e75SGabriel Fernandez 		return ret;
1455*9be88e75SGabriel Fernandez 	}
1456*9be88e75SGabriel Fernandez 
1457*9be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER
1458*9be88e75SGabriel Fernandez 	if ((pll_idx == _PLL4) && pll4_bootrom) {
1459*9be88e75SGabriel Fernandez 		clk_stm32_pll_config_out(priv, pll, &pll_conf->output);
1460*9be88e75SGabriel Fernandez 
1461*9be88e75SGabriel Fernandez 		mmio_setbits_32(pll_base,
1462*9be88e75SGabriel Fernandez 				RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
1463*9be88e75SGabriel Fernandez 
1464*9be88e75SGabriel Fernandez 		return 0;
1465*9be88e75SGabriel Fernandez 	}
1466*9be88e75SGabriel Fernandez #endif
1467*9be88e75SGabriel Fernandez 	/* Stop the PLL before */
1468*9be88e75SGabriel Fernandez 	_clk_stm32_pll_disable(priv, pll);
1469*9be88e75SGabriel Fernandez 
1470*9be88e75SGabriel Fernandez 	clk_stm32_pll_config_vco(priv, pll, &pll_conf->vco);
1471*9be88e75SGabriel Fernandez 	clk_stm32_pll_config_out(priv, pll, &pll_conf->output);
1472*9be88e75SGabriel Fernandez 	clk_stm32_pll_config_csg(priv, pll, &pll_conf->vco);
1473*9be88e75SGabriel Fernandez 
1474*9be88e75SGabriel Fernandez 	ret = _clk_stm32_pll_enable(priv, pll);
1475*9be88e75SGabriel Fernandez 	if (ret != 0) {
1476*9be88e75SGabriel Fernandez 		return ret;
1477*9be88e75SGabriel Fernandez 	}
1478*9be88e75SGabriel Fernandez 
1479*9be88e75SGabriel Fernandez 	mmio_setbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
1480*9be88e75SGabriel Fernandez 
1481*9be88e75SGabriel Fernandez 	return 0;
1482*9be88e75SGabriel Fernandez }
1483*9be88e75SGabriel Fernandez 
1484*9be88e75SGabriel Fernandez static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx)
1485*9be88e75SGabriel Fernandez {
1486*9be88e75SGabriel Fernandez 	struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx);
1487*9be88e75SGabriel Fernandez 
1488*9be88e75SGabriel Fernandez 	if (pll_conf->vco.status) {
1489*9be88e75SGabriel Fernandez 		return _clk_stm32_pll_init(priv, pll_idx, pll_conf);
1490*9be88e75SGabriel Fernandez 	}
1491*9be88e75SGabriel Fernandez 
1492*9be88e75SGabriel Fernandez 	return 0;
1493*9be88e75SGabriel Fernandez }
1494*9be88e75SGabriel Fernandez 
1495*9be88e75SGabriel Fernandez static int stm32_clk_pll_configure(struct stm32_clk_priv *priv)
1496*9be88e75SGabriel Fernandez {
1497*9be88e75SGabriel Fernandez 	int err = 0;
1498*9be88e75SGabriel Fernandez 
1499*9be88e75SGabriel Fernandez 	err = clk_stm32_pll_init(priv, _PLL1);
1500*9be88e75SGabriel Fernandez 	if (err) {
1501*9be88e75SGabriel Fernandez 		return err;
1502*9be88e75SGabriel Fernandez 	}
1503*9be88e75SGabriel Fernandez 
1504*9be88e75SGabriel Fernandez 	err = clk_stm32_pll_init(priv, _PLL2);
1505*9be88e75SGabriel Fernandez 	if (err) {
1506*9be88e75SGabriel Fernandez 		return err;
1507*9be88e75SGabriel Fernandez 	}
1508*9be88e75SGabriel Fernandez 
1509*9be88e75SGabriel Fernandez 	err = clk_stm32_pll_init(priv, _PLL3);
1510*9be88e75SGabriel Fernandez 	if (err) {
1511*9be88e75SGabriel Fernandez 		return err;
1512*9be88e75SGabriel Fernandez 	}
1513*9be88e75SGabriel Fernandez 
1514*9be88e75SGabriel Fernandez 	err = clk_stm32_pll_init(priv, _PLL4);
1515*9be88e75SGabriel Fernandez 	if (err) {
1516*9be88e75SGabriel Fernandez 		return err;
1517*9be88e75SGabriel Fernandez 	}
1518*9be88e75SGabriel Fernandez 
1519*9be88e75SGabriel Fernandez 	return 0;
1520*9be88e75SGabriel Fernandez }
1521*9be88e75SGabriel Fernandez 
1522*9be88e75SGabriel Fernandez static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv)
1523*9be88e75SGabriel Fernandez {
1524*9be88e75SGabriel Fernandez 	int ret = 0;
1525*9be88e75SGabriel Fernandez 
1526*9be88e75SGabriel Fernandez 	if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) {
1527*9be88e75SGabriel Fernandez 		ret = clk_oscillator_wait_ready_on(priv, _CK_LSE);
1528*9be88e75SGabriel Fernandez 	}
1529*9be88e75SGabriel Fernandez 
1530*9be88e75SGabriel Fernandez 	return ret;
1531*9be88e75SGabriel Fernandez }
1532*9be88e75SGabriel Fernandez 
1533*9be88e75SGabriel Fernandez static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv)
1534*9be88e75SGabriel Fernandez {
1535*9be88e75SGabriel Fernandez 	stm32_enable_oscillator_hse(priv);
1536*9be88e75SGabriel Fernandez 	stm32_enable_oscillator_lse(priv);
1537*9be88e75SGabriel Fernandez 	_clk_stm32_enable(priv, _CK_LSI);
1538*9be88e75SGabriel Fernandez 	_clk_stm32_enable(priv, _CK_CSI);
1539*9be88e75SGabriel Fernandez }
1540*9be88e75SGabriel Fernandez 
1541*9be88e75SGabriel Fernandez static int stm32_clk_hsidiv_configure(struct stm32_clk_priv *priv)
1542*9be88e75SGabriel Fernandez {
1543*9be88e75SGabriel Fernandez 	return stm32mp1_hsidiv(_clk_stm32_get_rate(priv, _CK_HSI));
1544*9be88e75SGabriel Fernandez }
1545*9be88e75SGabriel Fernandez 
1546*9be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER
1547*9be88e75SGabriel Fernandez static bool stm32mp1_clk_is_pll4_used_by_bootrom(struct stm32_clk_priv *priv, int usbphy_p)
1548*9be88e75SGabriel Fernandez {
1549*9be88e75SGabriel Fernandez 	/* Don't initialize PLL4, when used by BOOTROM */
1550*9be88e75SGabriel Fernandez 	if ((stm32mp_get_boot_itf_selected() ==
1551*9be88e75SGabriel Fernandez 	     BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB) &&
1552*9be88e75SGabriel Fernandez 	    (usbphy_p == _PLL4R)) {
1553*9be88e75SGabriel Fernandez 		return true;
1554*9be88e75SGabriel Fernandez 	}
1555*9be88e75SGabriel Fernandez 
1556*9be88e75SGabriel Fernandez 	return false;
1557*9be88e75SGabriel Fernandez }
1558*9be88e75SGabriel Fernandez 
1559*9be88e75SGabriel Fernandez static int stm32mp1_clk_check_usb_conflict(struct stm32_clk_priv *priv, int usbphy_p, int usbo_p)
1560*9be88e75SGabriel Fernandez {
1561*9be88e75SGabriel Fernandez 	int _usbo_p;
1562*9be88e75SGabriel Fernandez 	int _usbphy_p;
1563*9be88e75SGabriel Fernandez 
1564*9be88e75SGabriel Fernandez 	if (!pll4_bootrom) {
1565*9be88e75SGabriel Fernandez 		return 0;
1566*9be88e75SGabriel Fernandez 	}
1567*9be88e75SGabriel Fernandez 
1568*9be88e75SGabriel Fernandez 	_usbo_p = _clk_stm32_get_parent(priv, _USBO_K);
1569*9be88e75SGabriel Fernandez 	_usbphy_p = _clk_stm32_get_parent(priv, _USBPHY_K);
1570*9be88e75SGabriel Fernandez 
1571*9be88e75SGabriel Fernandez 	if ((_usbo_p != usbo_p) || (_usbphy_p != usbphy_p)) {
1572*9be88e75SGabriel Fernandez 		return -FDT_ERR_BADVALUE;
1573*9be88e75SGabriel Fernandez 	}
1574*9be88e75SGabriel Fernandez 
1575*9be88e75SGabriel Fernandez 	return 0;
1576*9be88e75SGabriel Fernandez }
1577*9be88e75SGabriel Fernandez #endif
1578*9be88e75SGabriel Fernandez 
1579*9be88e75SGabriel Fernandez static struct clk_oscillator_data stm32mp13_osc_data[NB_OSCILLATOR] = {
1580*9be88e75SGabriel Fernandez 	OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY,
1581*9be88e75SGabriel Fernandez 		   NULL, NULL, NULL),
1582*9be88e75SGabriel Fernandez 
1583*9be88e75SGabriel Fernandez 	OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY,
1584*9be88e75SGabriel Fernandez 		   NULL, NULL, NULL),
1585*9be88e75SGabriel Fernandez 
1586*9be88e75SGabriel Fernandez 	OSCILLATOR(OSC_CSI, _CK_CSI, "clk-csi", GATE_CSI, GATE_CSI_RDY,
1587*9be88e75SGabriel Fernandez 		   NULL, NULL, NULL),
1588*9be88e75SGabriel Fernandez 
1589*9be88e75SGabriel Fernandez 	OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY,
1590*9be88e75SGabriel Fernandez 		   BYPASS(RCC_BDCR, 1, 3),
1591*9be88e75SGabriel Fernandez 		   CSS(RCC_BDCR, 8),
1592*9be88e75SGabriel Fernandez 		   DRIVE(RCC_BDCR, 4, 2, 2)),
1593*9be88e75SGabriel Fernandez 
1594*9be88e75SGabriel Fernandez 	OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY,
1595*9be88e75SGabriel Fernandez 		   BYPASS(RCC_OCENSETR, 10, 7),
1596*9be88e75SGabriel Fernandez 		   CSS(RCC_OCENSETR, 11),
1597*9be88e75SGabriel Fernandez 		   NULL),
1598*9be88e75SGabriel Fernandez 
1599*9be88e75SGabriel Fernandez 	OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE,
1600*9be88e75SGabriel Fernandez 		   NULL, NULL, NULL),
1601*9be88e75SGabriel Fernandez };
1602*9be88e75SGabriel Fernandez 
1603*9be88e75SGabriel Fernandez static const char *clk_stm32_get_oscillator_name(enum stm32_osc id)
1604*9be88e75SGabriel Fernandez {
1605*9be88e75SGabriel Fernandez 	if (id < NB_OSCILLATOR) {
1606*9be88e75SGabriel Fernandez 		return stm32mp13_osc_data[id].name;
1607*9be88e75SGabriel Fernandez 	}
1608*9be88e75SGabriel Fernandez 
1609*9be88e75SGabriel Fernandez 	return NULL;
1610*9be88e75SGabriel Fernandez }
1611*9be88e75SGabriel Fernandez 
1612*9be88e75SGabriel Fernandez #define CLK_PLL_CFG(_idx, _clk_id, _type, _reg)\
1613*9be88e75SGabriel Fernandez 	[(_idx)] = {\
1614*9be88e75SGabriel Fernandez 		.clk_id = (_clk_id),\
1615*9be88e75SGabriel Fernandez 		.plltype = (_type),\
1616*9be88e75SGabriel Fernandez 		.reg_pllxcr = (_reg),\
1617*9be88e75SGabriel Fernandez 	}
1618*9be88e75SGabriel Fernandez 
1619*9be88e75SGabriel Fernandez static const struct stm32_clk_pll stm32_mp13_clk_pll[_PLL_NB] = {
1620*9be88e75SGabriel Fernandez 	CLK_PLL_CFG(_PLL1, _CK_PLL1, PLL_2000, RCC_PLL1CR),
1621*9be88e75SGabriel Fernandez 	CLK_PLL_CFG(_PLL2, _CK_PLL2, PLL_1600, RCC_PLL2CR),
1622*9be88e75SGabriel Fernandez 	CLK_PLL_CFG(_PLL3, _CK_PLL3, PLL_800, RCC_PLL3CR),
1623*9be88e75SGabriel Fernandez 	CLK_PLL_CFG(_PLL4, _CK_PLL4, PLL_800, RCC_PLL4CR),
1624*9be88e75SGabriel Fernandez };
1625*9be88e75SGabriel Fernandez 
1626*9be88e75SGabriel Fernandez static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx)
1627*9be88e75SGabriel Fernandez {
1628*9be88e75SGabriel Fernandez 	return &stm32_mp13_clk_pll[idx];
1629*9be88e75SGabriel Fernandez }
1630*9be88e75SGabriel Fernandez 
1631*9be88e75SGabriel Fernandez struct stm32_pll_cfg {
1632*9be88e75SGabriel Fernandez 	int pll_id;
1633*9be88e75SGabriel Fernandez };
1634*9be88e75SGabriel Fernandez 
1635*9be88e75SGabriel Fernandez static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv,  int id,
1636*9be88e75SGabriel Fernandez 					       unsigned long prate)
1637*9be88e75SGabriel Fernandez {
1638*9be88e75SGabriel Fernandez 	const struct clk_stm32 *clk = _clk_get(priv, id);
1639*9be88e75SGabriel Fernandez 	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
1640*9be88e75SGabriel Fernandez 	const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
1641*9be88e75SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1642*9be88e75SGabriel Fernandez 	uint32_t cfgr1, fracr, divm, divn;
1643*9be88e75SGabriel Fernandez 	unsigned long fvco;
1644*9be88e75SGabriel Fernandez 
1645*9be88e75SGabriel Fernandez 	cfgr1 = mmio_read_32(pll_base + RCC_OFFSET_PLLXCFGR1);
1646*9be88e75SGabriel Fernandez 	fracr = mmio_read_32(pll_base + RCC_OFFSET_PLLXFRACR);
1647*9be88e75SGabriel Fernandez 
1648*9be88e75SGabriel Fernandez 	divm = (cfgr1 & (RCC_PLLNCFGR1_DIVM_MASK)) >> RCC_PLLNCFGR1_DIVM_SHIFT;
1649*9be88e75SGabriel Fernandez 	divn = cfgr1 & RCC_PLLNCFGR1_DIVN_MASK;
1650*9be88e75SGabriel Fernandez 
1651*9be88e75SGabriel Fernandez 	/*
1652*9be88e75SGabriel Fernandez 	 * With FRACV :
1653*9be88e75SGabriel Fernandez 	 *   Fvco = Fck_ref * ((DIVN + 1) + FRACV / 2^13) / (DIVM + 1)
1654*9be88e75SGabriel Fernandez 	 * Without FRACV
1655*9be88e75SGabriel Fernandez 	 *   Fvco = Fck_ref * ((DIVN + 1) / (DIVM + 1)
1656*9be88e75SGabriel Fernandez 	 */
1657*9be88e75SGabriel Fernandez 	if ((fracr & RCC_PLLNFRACR_FRACLE) != 0U) {
1658*9be88e75SGabriel Fernandez 		uint32_t fracv = (fracr & RCC_PLLNFRACR_FRACV_MASK) >>
1659*9be88e75SGabriel Fernandez 				 RCC_PLLNFRACR_FRACV_SHIFT;
1660*9be88e75SGabriel Fernandez 		unsigned long long numerator, denominator;
1661*9be88e75SGabriel Fernandez 
1662*9be88e75SGabriel Fernandez 		numerator = (((unsigned long long)divn + 1U) << 13) + fracv;
1663*9be88e75SGabriel Fernandez 		numerator = prate * numerator;
1664*9be88e75SGabriel Fernandez 		denominator = ((unsigned long long)divm + 1U) << 13;
1665*9be88e75SGabriel Fernandez 		fvco = (unsigned long)(numerator / denominator);
1666*9be88e75SGabriel Fernandez 	} else {
1667*9be88e75SGabriel Fernandez 		fvco = (unsigned long)(prate * (divn + 1U) / (divm + 1U));
1668*9be88e75SGabriel Fernandez 	}
1669*9be88e75SGabriel Fernandez 
1670*9be88e75SGabriel Fernandez 	return fvco;
1671*9be88e75SGabriel Fernandez };
1672*9be88e75SGabriel Fernandez 
1673*9be88e75SGabriel Fernandez static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id)
1674*9be88e75SGabriel Fernandez {
1675*9be88e75SGabriel Fernandez 	const struct clk_stm32 *clk = _clk_get(priv, id);
1676*9be88e75SGabriel Fernandez 	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
1677*9be88e75SGabriel Fernandez 	const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
1678*9be88e75SGabriel Fernandez 
1679*9be88e75SGabriel Fernandez 	return _clk_stm32_pll_is_enabled(priv, pll);
1680*9be88e75SGabriel Fernandez }
1681*9be88e75SGabriel Fernandez 
1682*9be88e75SGabriel Fernandez static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id)
1683*9be88e75SGabriel Fernandez {
1684*9be88e75SGabriel Fernandez 	const struct clk_stm32 *clk = _clk_get(priv, id);
1685*9be88e75SGabriel Fernandez 	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
1686*9be88e75SGabriel Fernandez 	const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
1687*9be88e75SGabriel Fernandez 
1688*9be88e75SGabriel Fernandez 	return _clk_stm32_pll_enable(priv, pll);
1689*9be88e75SGabriel Fernandez }
1690*9be88e75SGabriel Fernandez 
1691*9be88e75SGabriel Fernandez static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id)
1692*9be88e75SGabriel Fernandez {
1693*9be88e75SGabriel Fernandez 	const struct clk_stm32 *clk = _clk_get(priv, id);
1694*9be88e75SGabriel Fernandez 	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
1695*9be88e75SGabriel Fernandez 	const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
1696*9be88e75SGabriel Fernandez 
1697*9be88e75SGabriel Fernandez 	_clk_stm32_pll_disable(priv, pll);
1698*9be88e75SGabriel Fernandez }
1699*9be88e75SGabriel Fernandez 
1700*9be88e75SGabriel Fernandez static const struct stm32_clk_ops clk_stm32_pll_ops = {
1701*9be88e75SGabriel Fernandez 	.recalc_rate	= clk_stm32_pll_recalc_rate,
1702*9be88e75SGabriel Fernandez 	.enable		= clk_stm32_pll_enable,
1703*9be88e75SGabriel Fernandez 	.disable	= clk_stm32_pll_disable,
1704*9be88e75SGabriel Fernandez 	.is_enabled	= clk_stm32_pll_is_enabled,
1705*9be88e75SGabriel Fernandez };
1706*9be88e75SGabriel Fernandez 
1707*9be88e75SGabriel Fernandez #define CLK_PLL(idx, _idx, _parent, _gate, _pll_id, _flags)[idx] = {\
1708*9be88e75SGabriel Fernandez 	.name = #idx,\
1709*9be88e75SGabriel Fernandez 	.binding = _idx,\
1710*9be88e75SGabriel Fernandez 	.parent = _parent,\
1711*9be88e75SGabriel Fernandez 	.flags = (_flags),\
1712*9be88e75SGabriel Fernandez 	.clock_cfg	= &(struct stm32_pll_cfg) {\
1713*9be88e75SGabriel Fernandez 		.pll_id = _pll_id,\
1714*9be88e75SGabriel Fernandez 	},\
1715*9be88e75SGabriel Fernandez 	.ops = &clk_stm32_pll_ops,\
1716*9be88e75SGabriel Fernandez }
1717*9be88e75SGabriel Fernandez 
1718*9be88e75SGabriel Fernandez struct clk_stm32_composite_cfg {
1719*9be88e75SGabriel Fernandez 	int gate_id;
1720*9be88e75SGabriel Fernandez 	int div_id;
1721*9be88e75SGabriel Fernandez };
1722*9be88e75SGabriel Fernandez 
1723*9be88e75SGabriel Fernandez static unsigned long clk_stm32_composite_recalc_rate(struct stm32_clk_priv *priv,
1724*9be88e75SGabriel Fernandez 						     int idx, unsigned long prate)
1725*9be88e75SGabriel Fernandez {
1726*9be88e75SGabriel Fernandez 	const struct clk_stm32 *clk = _clk_get(priv, idx);
1727*9be88e75SGabriel Fernandez 	struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
1728*9be88e75SGabriel Fernandez 
1729*9be88e75SGabriel Fernandez 	return _clk_stm32_divider_recalc(priv, composite_cfg->div_id, prate);
1730*9be88e75SGabriel Fernandez };
1731*9be88e75SGabriel Fernandez 
1732*9be88e75SGabriel Fernandez static bool clk_stm32_composite_gate_is_enabled(struct stm32_clk_priv *priv, int idx)
1733*9be88e75SGabriel Fernandez {
1734*9be88e75SGabriel Fernandez 	const struct clk_stm32 *clk = _clk_get(priv, idx);
1735*9be88e75SGabriel Fernandez 	struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
1736*9be88e75SGabriel Fernandez 
1737*9be88e75SGabriel Fernandez 	return _clk_stm32_gate_is_enabled(priv, composite_cfg->gate_id);
1738*9be88e75SGabriel Fernandez }
1739*9be88e75SGabriel Fernandez 
1740*9be88e75SGabriel Fernandez static int clk_stm32_composite_gate_enable(struct stm32_clk_priv *priv, int idx)
1741*9be88e75SGabriel Fernandez {
1742*9be88e75SGabriel Fernandez 	const struct clk_stm32 *clk = _clk_get(priv, idx);
1743*9be88e75SGabriel Fernandez 	struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
1744*9be88e75SGabriel Fernandez 
1745*9be88e75SGabriel Fernandez 	return _clk_stm32_gate_enable(priv, composite_cfg->gate_id);
1746*9be88e75SGabriel Fernandez }
1747*9be88e75SGabriel Fernandez 
1748*9be88e75SGabriel Fernandez static void clk_stm32_composite_gate_disable(struct stm32_clk_priv *priv, int idx)
1749*9be88e75SGabriel Fernandez {
1750*9be88e75SGabriel Fernandez 	const struct clk_stm32 *clk = _clk_get(priv, idx);
1751*9be88e75SGabriel Fernandez 	struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
1752*9be88e75SGabriel Fernandez 
1753*9be88e75SGabriel Fernandez 	_clk_stm32_gate_disable(priv, composite_cfg->gate_id);
1754*9be88e75SGabriel Fernandez }
1755*9be88e75SGabriel Fernandez 
1756*9be88e75SGabriel Fernandez static const struct stm32_clk_ops clk_stm32_composite_ops = {
1757*9be88e75SGabriel Fernandez 	.recalc_rate = clk_stm32_composite_recalc_rate,
1758*9be88e75SGabriel Fernandez 	.is_enabled = clk_stm32_composite_gate_is_enabled,
1759*9be88e75SGabriel Fernandez 	.enable = clk_stm32_composite_gate_enable,
1760*9be88e75SGabriel Fernandez 	.disable = clk_stm32_composite_gate_disable,
1761*9be88e75SGabriel Fernandez };
1762*9be88e75SGabriel Fernandez 
1763*9be88e75SGabriel Fernandez #define STM32_COMPOSITE(idx, _binding, _parent, _flags, _gate_id,\
1764*9be88e75SGabriel Fernandez 			_div_id)[idx] = {\
1765*9be88e75SGabriel Fernandez 	.name = #idx,\
1766*9be88e75SGabriel Fernandez 	.binding = (_binding),\
1767*9be88e75SGabriel Fernandez 	.parent =  (_parent),\
1768*9be88e75SGabriel Fernandez 	.flags = (_flags),\
1769*9be88e75SGabriel Fernandez 	.clock_cfg	= &(struct clk_stm32_composite_cfg) {\
1770*9be88e75SGabriel Fernandez 		.gate_id	= (_gate_id),\
1771*9be88e75SGabriel Fernandez 		.div_id	= (_div_id),\
1772*9be88e75SGabriel Fernandez 	},\
1773*9be88e75SGabriel Fernandez 	.ops = &clk_stm32_composite_ops,\
1774*9be88e75SGabriel Fernandez }
1775*9be88e75SGabriel Fernandez 
1776*9be88e75SGabriel Fernandez static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
1777*9be88e75SGabriel Fernandez 	/* ROOT CLOCKS */
1778*9be88e75SGabriel Fernandez 	CLK_FIXED_RATE(_CK_OFF, _NO_ID, 0),
1779*9be88e75SGabriel Fernandez 	CLK_OSC(_CK_HSE, CK_HSE, CLK_IS_ROOT, OSC_HSE),
1780*9be88e75SGabriel Fernandez 	CLK_OSC(_CK_HSI, CK_HSI, CLK_IS_ROOT, OSC_HSI),
1781*9be88e75SGabriel Fernandez 	CLK_OSC(_CK_CSI, CK_CSI, CLK_IS_ROOT, OSC_CSI),
1782*9be88e75SGabriel Fernandez 	CLK_OSC(_CK_LSI, CK_LSI, CLK_IS_ROOT, OSC_LSI),
1783*9be88e75SGabriel Fernandez 	CLK_OSC(_CK_LSE, CK_LSE, CLK_IS_ROOT, OSC_LSE),
1784*9be88e75SGabriel Fernandez 
1785*9be88e75SGabriel Fernandez 	CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN),
1786*9be88e75SGabriel Fernandez 
1787*9be88e75SGabriel Fernandez 	CLK_FIXED_RATE(_USB_PHY_48, _NO_ID, USB_PHY_48_MHZ),
1788*9be88e75SGabriel Fernandez 
1789*9be88e75SGabriel Fernandez 	STM32_DIV(_HSE_DIV, _NO_ID, _CK_HSE, 0, DIV_RTC),
1790*9be88e75SGabriel Fernandez 
1791*9be88e75SGabriel Fernandez 	FIXED_FACTOR(_HSE_DIV2, CK_HSE_DIV2, _CK_HSE, 1, 2),
1792*9be88e75SGabriel Fernandez 	FIXED_FACTOR(_CSI_DIV122, _NO_ID, _CK_CSI, 1, 122),
1793*9be88e75SGabriel Fernandez 
1794*9be88e75SGabriel Fernandez 	CLK_PLL(_CK_PLL1, PLL1, MUX(MUX_PLL12), GATE_PLL1, _PLL1, 0),
1795*9be88e75SGabriel Fernandez 	CLK_PLL(_CK_PLL2, PLL2, MUX(MUX_PLL12), GATE_PLL2, _PLL2, 0),
1796*9be88e75SGabriel Fernandez 	CLK_PLL(_CK_PLL3, PLL3, MUX(MUX_PLL3), GATE_PLL3, _PLL3, 0),
1797*9be88e75SGabriel Fernandez 	CLK_PLL(_CK_PLL4, PLL4, MUX(MUX_PLL4), GATE_PLL4, _PLL4, 0),
1798*9be88e75SGabriel Fernandez 
1799*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL1P, PLL1_P, _CK_PLL1, CLK_IS_CRITICAL, GATE_PLL1_DIVP, DIV_PLL1DIVP),
1800*9be88e75SGabriel Fernandez 	STM32_DIV(_PLL1P_DIV, _NO_ID, _CK_PLL1, 0, DIV_MPU),
1801*9be88e75SGabriel Fernandez 
1802*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL2P, PLL2_P, _CK_PLL2, CLK_IS_CRITICAL, GATE_PLL2_DIVP, DIV_PLL2DIVP),
1803*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL2Q, PLL2_Q, _CK_PLL2, 0, GATE_PLL2_DIVQ, DIV_PLL2DIVQ),
1804*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL2R, PLL2_R, _CK_PLL2, CLK_IS_CRITICAL, GATE_PLL2_DIVR, DIV_PLL2DIVR),
1805*9be88e75SGabriel Fernandez 
1806*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL3P, PLL3_P, _CK_PLL3, 0, GATE_PLL3_DIVP, DIV_PLL3DIVP),
1807*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL3Q, PLL3_Q, _CK_PLL3, 0, GATE_PLL3_DIVQ, DIV_PLL3DIVQ),
1808*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL3R, PLL3_R, _CK_PLL3, 0, GATE_PLL3_DIVR, DIV_PLL3DIVR),
1809*9be88e75SGabriel Fernandez 
1810*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL4P, PLL4_P, _CK_PLL4, 0, GATE_PLL4_DIVP, DIV_PLL4DIVP),
1811*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL4Q, PLL4_Q, _CK_PLL4, 0, GATE_PLL4_DIVQ, DIV_PLL4DIVQ),
1812*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_PLL4R, PLL4_R, _CK_PLL4, 0, GATE_PLL4_DIVR, DIV_PLL4DIVR),
1813*9be88e75SGabriel Fernandez 
1814*9be88e75SGabriel Fernandez 	STM32_MUX(_CKMPU, CK_MPU, MUX_MPU, 0),
1815*9be88e75SGabriel Fernandez 	STM32_DIV(_CKAXI, CK_AXI, MUX(MUX_AXI), 0, DIV_AXI),
1816*9be88e75SGabriel Fernandez 	STM32_DIV(_CKMLAHB, CK_MLAHB, MUX(MUX_MLAHB), CLK_IS_CRITICAL, DIV_MLAHB),
1817*9be88e75SGabriel Fernandez 	STM32_MUX(_CKPER, CK_PER, MUX(MUX_CKPER), 0),
1818*9be88e75SGabriel Fernandez 
1819*9be88e75SGabriel Fernandez 	STM32_DIV(_PCLK1, PCLK1, _CKMLAHB, 0, DIV_APB1),
1820*9be88e75SGabriel Fernandez 	STM32_DIV(_PCLK2, PCLK2, _CKMLAHB, 0, DIV_APB2),
1821*9be88e75SGabriel Fernandez 	STM32_DIV(_PCLK3, PCLK3, _CKMLAHB, 0, DIV_APB3),
1822*9be88e75SGabriel Fernandez 	STM32_DIV(_PCLK4, PCLK4, _CKAXI, 0, DIV_APB4),
1823*9be88e75SGabriel Fernandez 	STM32_DIV(_PCLK5, PCLK5, _CKAXI, 0, DIV_APB5),
1824*9be88e75SGabriel Fernandez 	STM32_DIV(_PCLK6, PCLK6, _CKMLAHB, 0, DIV_APB6),
1825*9be88e75SGabriel Fernandez 
1826*9be88e75SGabriel Fernandez 	CK_TIMER(_CKTIMG1, CK_TIMG1, _PCLK1, 0, RCC_APB1DIVR, RCC_TIMG1PRER),
1827*9be88e75SGabriel Fernandez 	CK_TIMER(_CKTIMG2, CK_TIMG2, _PCLK2, 0, RCC_APB2DIVR, RCC_TIMG2PRER),
1828*9be88e75SGabriel Fernandez 	CK_TIMER(_CKTIMG3, CK_TIMG3, _PCLK6, 0, RCC_APB6DIVR, RCC_TIMG3PRER),
1829*9be88e75SGabriel Fernandez 
1830*9be88e75SGabriel Fernandez 	/* END ROOT CLOCKS */
1831*9be88e75SGabriel Fernandez 
1832*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRC1, DDRC1, _CKAXI, CLK_IS_CRITICAL, GATE_DDRC1),
1833*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRC1LP, DDRC1LP, _CKAXI, CLK_IS_CRITICAL, GATE_DDRC1LP),
1834*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRPHYC, DDRPHYC, _PLL2R, CLK_IS_CRITICAL, GATE_DDRPHYC),
1835*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRPHYCLP, DDRPHYCLP, _PLL2R, CLK_IS_CRITICAL, GATE_DDRPHYCLP),
1836*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRCAPB, DDRCAPB, _PCLK4, CLK_IS_CRITICAL, GATE_DDRCAPB),
1837*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRCAPBLP, DDRCAPBLP, _PCLK4, CLK_IS_CRITICAL, GATE_DDRCAPBLP),
1838*9be88e75SGabriel Fernandez 	STM32_GATE(_AXIDCG, AXIDCG, _CKAXI, CLK_IS_CRITICAL, GATE_AXIDCG),
1839*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRPHYCAPB, DDRPHYCAPB, _PCLK4, CLK_IS_CRITICAL, GATE_DDRPHYCAPB),
1840*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRPHYCAPBLP, DDRPHYCAPBLP, _PCLK4, CLK_IS_CRITICAL,  GATE_DDRPHYCAPBLP),
1841*9be88e75SGabriel Fernandez 
1842*9be88e75SGabriel Fernandez 	STM32_GATE(_SYSCFG, SYSCFG, _PCLK3, 0, GATE_SYSCFG),
1843*9be88e75SGabriel Fernandez 	STM32_GATE(_DDRPERFM, DDRPERFM, _PCLK4, 0, GATE_DDRPERFM),
1844*9be88e75SGabriel Fernandez 	STM32_GATE(_IWDG2APB, IWDG2, _PCLK4, 0, GATE_IWDG2APB),
1845*9be88e75SGabriel Fernandez 	STM32_GATE(_USBPHY_K, USBPHY_K, MUX(MUX_USBPHY), 0, GATE_USBPHY),
1846*9be88e75SGabriel Fernandez 	STM32_GATE(_USBO_K, USBO_K, MUX(MUX_USBO), 0, GATE_USBO),
1847*9be88e75SGabriel Fernandez 
1848*9be88e75SGabriel Fernandez 	STM32_GATE(_RTCAPB, RTCAPB, _PCLK5, CLK_IS_CRITICAL, GATE_RTCAPB),
1849*9be88e75SGabriel Fernandez 	STM32_GATE(_TZC, TZC, _PCLK5, CLK_IS_CRITICAL, GATE_TZC),
1850*9be88e75SGabriel Fernandez 	STM32_GATE(_ETZPC, TZPC, _PCLK5, CLK_IS_CRITICAL, GATE_ETZPC),
1851*9be88e75SGabriel Fernandez 	STM32_GATE(_IWDG1APB, IWDG1, _PCLK5, 0, GATE_IWDG1APB),
1852*9be88e75SGabriel Fernandez 	STM32_GATE(_BSEC, BSEC, _PCLK5, CLK_IS_CRITICAL, GATE_BSEC),
1853*9be88e75SGabriel Fernandez 	STM32_GATE(_STGENC, STGEN_K, MUX(MUX_STGEN), CLK_IS_CRITICAL, GATE_STGENC),
1854*9be88e75SGabriel Fernandez 
1855*9be88e75SGabriel Fernandez 	STM32_GATE(_USART1_K, USART1_K, MUX(MUX_UART1), 0, GATE_USART1),
1856*9be88e75SGabriel Fernandez 	STM32_GATE(_USART2_K, USART2_K, MUX(MUX_UART2), 0, GATE_USART2),
1857*9be88e75SGabriel Fernandez 	STM32_GATE(_I2C3_K, I2C3_K, MUX(MUX_I2C3), 0, GATE_I2C3),
1858*9be88e75SGabriel Fernandez 	STM32_GATE(_I2C4_K, I2C4_K, MUX(MUX_I2C4), 0, GATE_I2C4),
1859*9be88e75SGabriel Fernandez 	STM32_GATE(_I2C5_K, I2C5_K, MUX(MUX_I2C5), 0, GATE_I2C5),
1860*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM12, TIM12_K, _CKTIMG3, 0, GATE_TIM12),
1861*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM15, TIM15_K, _CKTIMG3, 0, GATE_TIM15),
1862*9be88e75SGabriel Fernandez 
1863*9be88e75SGabriel Fernandez 	STM32_GATE(_RTCCK, RTC, MUX(MUX_RTC), 0, GATE_RTCCK),
1864*9be88e75SGabriel Fernandez 
1865*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOA, GPIOA, _CKMLAHB, 0, GATE_GPIOA),
1866*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOB, GPIOB, _CKMLAHB, 0, GATE_GPIOB),
1867*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOC, GPIOC, _CKMLAHB, 0, GATE_GPIOC),
1868*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOD, GPIOD, _CKMLAHB, 0, GATE_GPIOD),
1869*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOE, GPIOE, _CKMLAHB, 0, GATE_GPIOE),
1870*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOF, GPIOF, _CKMLAHB, 0, GATE_GPIOF),
1871*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOG, GPIOG, _CKMLAHB, 0, GATE_GPIOG),
1872*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOH, GPIOH, _CKMLAHB, 0, GATE_GPIOH),
1873*9be88e75SGabriel Fernandez 	STM32_GATE(_GPIOI, GPIOI, _CKMLAHB, 0, GATE_GPIOI),
1874*9be88e75SGabriel Fernandez 
1875*9be88e75SGabriel Fernandez 	STM32_GATE(_PKA, PKA, _CKAXI, 0, GATE_PKA),
1876*9be88e75SGabriel Fernandez 	STM32_GATE(_SAES_K, SAES_K, MUX(MUX_SAES), 0, GATE_SAES),
1877*9be88e75SGabriel Fernandez 	STM32_GATE(_CRYP1, CRYP1, _PCLK5, 0, GATE_CRYP1),
1878*9be88e75SGabriel Fernandez 	STM32_GATE(_HASH1, HASH1, _PCLK5, 0, GATE_HASH1),
1879*9be88e75SGabriel Fernandez 
1880*9be88e75SGabriel Fernandez 	STM32_GATE(_RNG1_K, RNG1_K, MUX(MUX_RNG1), 0, GATE_RNG1),
1881*9be88e75SGabriel Fernandez 	STM32_GATE(_BKPSRAM, BKPSRAM, _PCLK5, CLK_IS_CRITICAL, GATE_BKPSRAM),
1882*9be88e75SGabriel Fernandez 
1883*9be88e75SGabriel Fernandez 	STM32_GATE(_SDMMC1_K, SDMMC1_K, MUX(MUX_SDMMC1), 0, GATE_SDMMC1),
1884*9be88e75SGabriel Fernandez 	STM32_GATE(_SDMMC2_K, SDMMC2_K, MUX(MUX_SDMMC2), 0, GATE_SDMMC2),
1885*9be88e75SGabriel Fernandez 	STM32_GATE(_DBGCK, CK_DBG, _CKAXI, 0, GATE_DBGCK),
1886*9be88e75SGabriel Fernandez 
1887*9be88e75SGabriel Fernandez /* TODO: CHECK CLOCK FOR BL2/BL32 AND IF ONLY FOR TEST OR NOT */
1888*9be88e75SGabriel Fernandez 	STM32_GATE(_USART3_K, USART3_K, MUX(MUX_UART35), 0, GATE_USART3),
1889*9be88e75SGabriel Fernandez 	STM32_GATE(_UART4_K, UART4_K, MUX(MUX_UART4), 0, GATE_UART4),
1890*9be88e75SGabriel Fernandez 	STM32_GATE(_UART5_K, UART5_K, MUX(MUX_UART35), 0, GATE_UART5),
1891*9be88e75SGabriel Fernandez 	STM32_GATE(_UART7_K, UART7_K, MUX(MUX_UART78), 0, GATE_UART7),
1892*9be88e75SGabriel Fernandez 	STM32_GATE(_UART8_K, UART8_K, MUX(MUX_UART78), 0, GATE_UART8),
1893*9be88e75SGabriel Fernandez 	STM32_GATE(_USART6_K, USART6_K, MUX(MUX_UART6), 0, GATE_USART6),
1894*9be88e75SGabriel Fernandez 	STM32_GATE(_MCE, MCE, _CKAXI, CLK_IS_CRITICAL, GATE_MCE),
1895*9be88e75SGabriel Fernandez 	STM32_GATE(_FMC_K, FMC_K, MUX(MUX_FMC), 0, GATE_FMC),
1896*9be88e75SGabriel Fernandez 	STM32_GATE(_QSPI_K, QSPI_K, MUX(MUX_QSPI), 0, GATE_QSPI),
1897*9be88e75SGabriel Fernandez 
1898*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_MCO1_K, CK_MCO1, MUX(MUX_MCO1), 0, GATE_MCO1, DIV_MCO1),
1899*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_MCO2_K, CK_MCO2, MUX(MUX_MCO2), 0, GATE_MCO2, DIV_MCO2),
1900*9be88e75SGabriel Fernandez 	STM32_COMPOSITE(_TRACECK, CK_TRACE, _CKAXI, 0, GATE_TRACECK, DIV_TRACE),
1901*9be88e75SGabriel Fernandez 
1902*9be88e75SGabriel Fernandez #if defined(IMAGE_BL32)
1903*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM2, TIM2_K, _CKTIMG1, 0, GATE_TIM2),
1904*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM3, TIM3_K, _CKTIMG1, 0, GATE_TIM3),
1905*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM4, TIM4_K, _CKTIMG1, 0, GATE_TIM4),
1906*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM5, TIM5_K, _CKTIMG1, 0, GATE_TIM5),
1907*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM6, TIM6_K, _CKTIMG1, 0, GATE_TIM6),
1908*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM7, TIM7_K, _CKTIMG1, 0, GATE_TIM7),
1909*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM13, TIM13_K, _CKTIMG3, 0, GATE_TIM13),
1910*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM14, TIM14_K, _CKTIMG3, 0, GATE_TIM14),
1911*9be88e75SGabriel Fernandez 	STM32_GATE(_LPTIM1_K, LPTIM1_K, MUX(MUX_LPTIM1), 0, GATE_LPTIM1),
1912*9be88e75SGabriel Fernandez 	STM32_GATE(_SPI2_K, SPI2_K, MUX(MUX_SPI23), 0, GATE_SPI2),
1913*9be88e75SGabriel Fernandez 	STM32_GATE(_SPI3_K, SPI3_K, MUX(MUX_SPI23), 0, GATE_SPI3),
1914*9be88e75SGabriel Fernandez 	STM32_GATE(_SPDIF_K, SPDIF_K, MUX(MUX_SPDIF), 0, GATE_SPDIF),
1915*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM1, TIM1_K, _CKTIMG2, 0, GATE_TIM1),
1916*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM8, TIM8_K, _CKTIMG2, 0, GATE_TIM8),
1917*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM16, TIM16_K, _CKTIMG3, 0, GATE_TIM16),
1918*9be88e75SGabriel Fernandez 	STM32_GATE(_TIM17, TIM17_K, _CKTIMG3, 0, GATE_TIM17),
1919*9be88e75SGabriel Fernandez 	STM32_GATE(_SPI1_K, SPI1_K, MUX(MUX_SPI1), 0, GATE_SPI1),
1920*9be88e75SGabriel Fernandez 	STM32_GATE(_SPI4_K, SPI4_K, MUX(MUX_SPI4), 0, GATE_SPI4),
1921*9be88e75SGabriel Fernandez 	STM32_GATE(_SPI5_K, SPI5_K, MUX(MUX_SPI5), 0, GATE_SPI5),
1922*9be88e75SGabriel Fernandez 	STM32_GATE(_SAI1_K, SAI1_K, MUX(MUX_SAI1), 0, GATE_SAI1),
1923*9be88e75SGabriel Fernandez 	STM32_GATE(_SAI2_K, SAI2_K, MUX(MUX_SAI2), 0, GATE_SAI2),
1924*9be88e75SGabriel Fernandez 	STM32_GATE(_DFSDM, DFSDM_K, MUX(MUX_SAI1), 0, GATE_DFSDM),
1925*9be88e75SGabriel Fernandez 	STM32_GATE(_FDCAN_K, FDCAN_K, MUX(MUX_FDCAN), 0, GATE_FDCAN),
1926*9be88e75SGabriel Fernandez 	STM32_GATE(_USBH, USBH, _CKAXI, 0, GATE_USBH),
1927*9be88e75SGabriel Fernandez 	STM32_GATE(_I2C1_K, I2C1_K, MUX(MUX_I2C12), 0, GATE_I2C1),
1928*9be88e75SGabriel Fernandez 	STM32_GATE(_I2C2_K, I2C2_K, MUX(MUX_I2C12), 0, GATE_I2C2),
1929*9be88e75SGabriel Fernandez 	STM32_GATE(_ADFSDM, ADFSDM_K, MUX(MUX_SAI1), 0, GATE_ADFSDM),
1930*9be88e75SGabriel Fernandez 	STM32_GATE(_LPTIM2_K, LPTIM2_K, MUX(MUX_LPTIM2), 0, GATE_LPTIM2),
1931*9be88e75SGabriel Fernandez 	STM32_GATE(_LPTIM3_K, LPTIM3_K, MUX(MUX_LPTIM3), 0, GATE_LPTIM3),
1932*9be88e75SGabriel Fernandez 	STM32_GATE(_LPTIM4_K, LPTIM4_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM4),
1933*9be88e75SGabriel Fernandez 	STM32_GATE(_LPTIM5_K, LPTIM5_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM5),
1934*9be88e75SGabriel Fernandez 	STM32_GATE(_VREF, VREF, _PCLK3, 0, GATE_VREF),
1935*9be88e75SGabriel Fernandez 	STM32_GATE(_DTS, TMPSENS, _PCLK3, 0, GATE_DTS),
1936*9be88e75SGabriel Fernandez 	STM32_GATE(_PMBCTRL, PMBCTRL, _PCLK3, 0, GATE_HDP),
1937*9be88e75SGabriel Fernandez 	STM32_GATE(_HDP, HDP, _PCLK3, 0, GATE_PMBCTRL),
1938*9be88e75SGabriel Fernandez 	STM32_GATE(_STGENRO, STGENRO, _PCLK4, 0, GATE_DCMIPP),
1939*9be88e75SGabriel Fernandez 	STM32_GATE(_DCMIPP_K, DCMIPP_K, MUX(MUX_DCMIPP), 0, GATE_DCMIPP),
1940*9be88e75SGabriel Fernandez 	STM32_GATE(_DMAMUX1, DMAMUX1, _CKAXI, 0, GATE_DMAMUX1),
1941*9be88e75SGabriel Fernandez 	STM32_GATE(_DMAMUX2, DMAMUX2, _CKAXI, 0, GATE_DMAMUX2),
1942*9be88e75SGabriel Fernandez 	STM32_GATE(_DMA3, DMA3, _CKAXI, 0, GATE_DMAMUX2),
1943*9be88e75SGabriel Fernandez 	STM32_GATE(_ADC1_K, ADC1_K, MUX(MUX_ADC1), 0, GATE_ADC1),
1944*9be88e75SGabriel Fernandez 	STM32_GATE(_ADC2_K, ADC2_K, MUX(MUX_ADC2), 0, GATE_ADC2),
1945*9be88e75SGabriel Fernandez 	STM32_GATE(_TSC, TSC, _CKAXI, 0, GATE_TSC),
1946*9be88e75SGabriel Fernandez 	STM32_GATE(_AXIMC, AXIMC, _CKAXI, 0, GATE_AXIMC),
1947*9be88e75SGabriel Fernandez 	STM32_GATE(_CRC1, CRC1, _CKAXI, 0, GATE_ETH1TX),
1948*9be88e75SGabriel Fernandez 	STM32_GATE(_ETH1CK, ETH1CK_K, MUX(MUX_ETH1), 0, GATE_ETH1CK),
1949*9be88e75SGabriel Fernandez 	STM32_GATE(_ETH1TX, ETH1TX, _CKAXI, 0, GATE_ETH1TX),
1950*9be88e75SGabriel Fernandez 	STM32_GATE(_ETH1RX, ETH1RX, _CKAXI, 0, GATE_ETH1RX),
1951*9be88e75SGabriel Fernandez 	STM32_GATE(_ETH2CK, ETH2CK_K, MUX(MUX_ETH2), 0, GATE_ETH2CK),
1952*9be88e75SGabriel Fernandez 	STM32_GATE(_ETH2TX, ETH2TX, _CKAXI, 0, GATE_ETH2TX),
1953*9be88e75SGabriel Fernandez 	STM32_GATE(_ETH2RX, ETH2RX, _CKAXI, 0, GATE_ETH2RX),
1954*9be88e75SGabriel Fernandez 	STM32_GATE(_ETH2MAC, ETH2MAC, _CKAXI, 0, GATE_ETH2MAC),
1955*9be88e75SGabriel Fernandez #endif
1956*9be88e75SGabriel Fernandez };
1957*9be88e75SGabriel Fernandez 
1958*9be88e75SGabriel Fernandez static struct stm32_pll_dt_cfg mp13_pll[_PLL_NB];
1959*9be88e75SGabriel Fernandez 
1960*9be88e75SGabriel Fernandez static struct stm32_osci_dt_cfg mp13_osci[NB_OSCILLATOR];
1961*9be88e75SGabriel Fernandez 
1962*9be88e75SGabriel Fernandez static uint32_t mp13_clksrc[MUX_MAX];
1963*9be88e75SGabriel Fernandez 
1964*9be88e75SGabriel Fernandez static uint32_t mp13_clkdiv[DIV_MAX];
1965*9be88e75SGabriel Fernandez 
1966*9be88e75SGabriel Fernandez static struct stm32_clk_platdata stm32mp13_clock_pdata = {
1967*9be88e75SGabriel Fernandez 	.osci		= mp13_osci,
1968*9be88e75SGabriel Fernandez 	.nosci		= NB_OSCILLATOR,
1969*9be88e75SGabriel Fernandez 	.pll		= mp13_pll,
1970*9be88e75SGabriel Fernandez 	.npll		= _PLL_NB,
1971*9be88e75SGabriel Fernandez 	.clksrc		= mp13_clksrc,
1972*9be88e75SGabriel Fernandez 	.nclksrc	= MUX_MAX,
1973*9be88e75SGabriel Fernandez 	.clkdiv		= mp13_clkdiv,
1974*9be88e75SGabriel Fernandez 	.nclkdiv	= DIV_MAX,
1975*9be88e75SGabriel Fernandez };
1976*9be88e75SGabriel Fernandez 
1977*9be88e75SGabriel Fernandez static struct stm32_clk_priv stm32mp13_clock_data = {
1978*9be88e75SGabriel Fernandez 	.base		= RCC_BASE,
1979*9be88e75SGabriel Fernandez 	.num		= ARRAY_SIZE(stm32mp13_clk),
1980*9be88e75SGabriel Fernandez 	.clks		= stm32mp13_clk,
1981*9be88e75SGabriel Fernandez 	.parents	= parent_mp13,
1982*9be88e75SGabriel Fernandez 	.nb_parents	= ARRAY_SIZE(parent_mp13),
1983*9be88e75SGabriel Fernandez 	.gates		= gates_mp13,
1984*9be88e75SGabriel Fernandez 	.nb_gates	= ARRAY_SIZE(gates_mp13),
1985*9be88e75SGabriel Fernandez 	.div		= dividers_mp13,
1986*9be88e75SGabriel Fernandez 	.nb_div		= ARRAY_SIZE(dividers_mp13),
1987*9be88e75SGabriel Fernandez 	.osci_data	= stm32mp13_osc_data,
1988*9be88e75SGabriel Fernandez 	.nb_osci_data	= ARRAY_SIZE(stm32mp13_osc_data),
1989*9be88e75SGabriel Fernandez 	.gate_refcounts	= refcounts_mp13,
1990*9be88e75SGabriel Fernandez 	.pdata		= &stm32mp13_clock_pdata,
1991*9be88e75SGabriel Fernandez };
1992*9be88e75SGabriel Fernandez 
1993*9be88e75SGabriel Fernandez static int stm32mp1_init_clock_tree(void)
1994*9be88e75SGabriel Fernandez {
1995*9be88e75SGabriel Fernandez 	struct stm32_clk_priv *priv = clk_stm32_get_priv();
1996*9be88e75SGabriel Fernandez 	int ret;
1997*9be88e75SGabriel Fernandez 
1998*9be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER
1999*9be88e75SGabriel Fernandez 	int usbphy_p = _clk_stm32_get_parent(priv, _USBPHY_K);
2000*9be88e75SGabriel Fernandez 	int usbo_p = _clk_stm32_get_parent(priv, _USBO_K);
2001*9be88e75SGabriel Fernandez 
2002*9be88e75SGabriel Fernandez 	/* Don't initialize PLL4, when used by BOOTROM */
2003*9be88e75SGabriel Fernandez 	pll4_bootrom = stm32mp1_clk_is_pll4_used_by_bootrom(priv, usbphy_p);
2004*9be88e75SGabriel Fernandez #endif
2005*9be88e75SGabriel Fernandez 
2006*9be88e75SGabriel Fernandez 	/*
2007*9be88e75SGabriel Fernandez 	 * Switch ON oscillators found in device-tree.
2008*9be88e75SGabriel Fernandez 	 * Note: HSI already ON after BootROM stage.
2009*9be88e75SGabriel Fernandez 	 */
2010*9be88e75SGabriel Fernandez 	stm32_clk_oscillators_enable(priv);
2011*9be88e75SGabriel Fernandez 
2012*9be88e75SGabriel Fernandez 	/* Come back to HSI */
2013*9be88e75SGabriel Fernandez 	ret = stm32mp1_come_back_to_hsi();
2014*9be88e75SGabriel Fernandez 	if (ret != 0) {
2015*9be88e75SGabriel Fernandez 		return ret;
2016*9be88e75SGabriel Fernandez 	}
2017*9be88e75SGabriel Fernandez 
2018*9be88e75SGabriel Fernandez 	ret = stm32_clk_hsidiv_configure(priv);
2019*9be88e75SGabriel Fernandez 	if (ret != 0) {
2020*9be88e75SGabriel Fernandez 		return ret;
2021*9be88e75SGabriel Fernandez 	}
2022*9be88e75SGabriel Fernandez 
2023*9be88e75SGabriel Fernandez 	ret = stm32_clk_stgen_configure(priv, _STGENC);
2024*9be88e75SGabriel Fernandez 	if (ret != 0) {
2025*9be88e75SGabriel Fernandez 		panic();
2026*9be88e75SGabriel Fernandez 	}
2027*9be88e75SGabriel Fernandez 
2028*9be88e75SGabriel Fernandez 	ret = stm32_clk_dividers_configure(priv);
2029*9be88e75SGabriel Fernandez 	if (ret != 0) {
2030*9be88e75SGabriel Fernandez 		panic();
2031*9be88e75SGabriel Fernandez 	}
2032*9be88e75SGabriel Fernandez 
2033*9be88e75SGabriel Fernandez 	ret = stm32_clk_pll_configure(priv);
2034*9be88e75SGabriel Fernandez 	if (ret != 0) {
2035*9be88e75SGabriel Fernandez 		panic();
2036*9be88e75SGabriel Fernandez 	}
2037*9be88e75SGabriel Fernandez 
2038*9be88e75SGabriel Fernandez 	/* Wait LSE ready before to use it */
2039*9be88e75SGabriel Fernandez 	ret = stm32_clk_oscillators_wait_lse_ready(priv);
2040*9be88e75SGabriel Fernandez 	if (ret != 0) {
2041*9be88e75SGabriel Fernandez 		panic();
2042*9be88e75SGabriel Fernandez 	}
2043*9be88e75SGabriel Fernandez 
2044*9be88e75SGabriel Fernandez 	/* Configure with expected clock source */
2045*9be88e75SGabriel Fernandez 	ret = stm32_clk_source_configure(priv);
2046*9be88e75SGabriel Fernandez 	if (ret != 0) {
2047*9be88e75SGabriel Fernandez 		panic();
2048*9be88e75SGabriel Fernandez 	}
2049*9be88e75SGabriel Fernandez 
2050*9be88e75SGabriel Fernandez 	/* Configure LSE css after RTC source configuration */
2051*9be88e75SGabriel Fernandez 	ret = stm32_clk_oscillators_lse_set_css(priv);
2052*9be88e75SGabriel Fernandez 	if (ret != 0) {
2053*9be88e75SGabriel Fernandez 		panic();
2054*9be88e75SGabriel Fernandez 	}
2055*9be88e75SGabriel Fernandez 
2056*9be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER
2057*9be88e75SGabriel Fernandez 	ret = stm32mp1_clk_check_usb_conflict(priv, usbphy_p, usbo_p);
2058*9be88e75SGabriel Fernandez 	if (ret != 0) {
2059*9be88e75SGabriel Fernandez 		return ret;
2060*9be88e75SGabriel Fernandez 	}
2061*9be88e75SGabriel Fernandez #endif
2062*9be88e75SGabriel Fernandez 	/* reconfigure STGEN with DT config */
2063*9be88e75SGabriel Fernandez 	ret = stm32_clk_stgen_configure(priv, _STGENC);
2064*9be88e75SGabriel Fernandez 	if (ret != 0) {
2065*9be88e75SGabriel Fernandez 		panic();
2066*9be88e75SGabriel Fernandez 	}
2067*9be88e75SGabriel Fernandez 
2068*9be88e75SGabriel Fernandez 	/* Software Self-Refresh mode (SSR) during DDR initilialization */
2069*9be88e75SGabriel Fernandez 	mmio_clrsetbits_32(priv->base + RCC_DDRITFCR,
2070*9be88e75SGabriel Fernandez 			   RCC_DDRITFCR_DDRCKMOD_MASK,
2071*9be88e75SGabriel Fernandez 			   RCC_DDRITFCR_DDRCKMOD_SSR <<
2072*9be88e75SGabriel Fernandez 			   RCC_DDRITFCR_DDRCKMOD_SHIFT);
2073*9be88e75SGabriel Fernandez 
2074*9be88e75SGabriel Fernandez 	return 0;
2075*9be88e75SGabriel Fernandez }
2076*9be88e75SGabriel Fernandez 
2077*9be88e75SGabriel Fernandez #define LSEDRV_MEDIUM_HIGH 2
2078*9be88e75SGabriel Fernandez 
2079*9be88e75SGabriel Fernandez static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
2080*9be88e75SGabriel Fernandez 					  struct stm32_osci_dt_cfg *osci)
2081*9be88e75SGabriel Fernandez {
2082*9be88e75SGabriel Fernandez 	int subnode = 0;
2083*9be88e75SGabriel Fernandez 
2084*9be88e75SGabriel Fernandez 	/* default value oscillator not found, freq=0 */
2085*9be88e75SGabriel Fernandez 	osci->freq = 0;
2086*9be88e75SGabriel Fernandez 
2087*9be88e75SGabriel Fernandez 	fdt_for_each_subnode(subnode, fdt, node) {
2088*9be88e75SGabriel Fernandez 		const char *cchar = NULL;
2089*9be88e75SGabriel Fernandez 		const fdt32_t *cuint = NULL;
2090*9be88e75SGabriel Fernandez 		int ret = 0;
2091*9be88e75SGabriel Fernandez 
2092*9be88e75SGabriel Fernandez 		cchar = fdt_get_name(fdt, subnode, &ret);
2093*9be88e75SGabriel Fernandez 		if (cchar == NULL) {
2094*9be88e75SGabriel Fernandez 			return ret;
2095*9be88e75SGabriel Fernandez 		}
2096*9be88e75SGabriel Fernandez 
2097*9be88e75SGabriel Fernandez 		if (strncmp(cchar, name, (size_t)ret) ||
2098*9be88e75SGabriel Fernandez 		    fdt_get_status(subnode) == DT_DISABLED) {
2099*9be88e75SGabriel Fernandez 			continue;
2100*9be88e75SGabriel Fernandez 		}
2101*9be88e75SGabriel Fernandez 
2102*9be88e75SGabriel Fernandez 		cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret);
2103*9be88e75SGabriel Fernandez 		if (cuint == NULL) {
2104*9be88e75SGabriel Fernandez 			return ret;
2105*9be88e75SGabriel Fernandez 		}
2106*9be88e75SGabriel Fernandez 
2107*9be88e75SGabriel Fernandez 		osci->freq = fdt32_to_cpu(*cuint);
2108*9be88e75SGabriel Fernandez 
2109*9be88e75SGabriel Fernandez 		if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) {
2110*9be88e75SGabriel Fernandez 			osci->bypass = true;
2111*9be88e75SGabriel Fernandez 		}
2112*9be88e75SGabriel Fernandez 
2113*9be88e75SGabriel Fernandez 		if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) {
2114*9be88e75SGabriel Fernandez 			osci->digbyp = true;
2115*9be88e75SGabriel Fernandez 		}
2116*9be88e75SGabriel Fernandez 
2117*9be88e75SGabriel Fernandez 		if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) {
2118*9be88e75SGabriel Fernandez 			osci->css = true;
2119*9be88e75SGabriel Fernandez 		}
2120*9be88e75SGabriel Fernandez 
2121*9be88e75SGabriel Fernandez 		osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH);
2122*9be88e75SGabriel Fernandez 
2123*9be88e75SGabriel Fernandez 		return 0;
2124*9be88e75SGabriel Fernandez 	}
2125*9be88e75SGabriel Fernandez 
2126*9be88e75SGabriel Fernandez 	return 0;
2127*9be88e75SGabriel Fernandez }
2128*9be88e75SGabriel Fernandez 
2129*9be88e75SGabriel Fernandez static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata)
2130*9be88e75SGabriel Fernandez {
2131*9be88e75SGabriel Fernandez 	int fdt_err = 0;
2132*9be88e75SGabriel Fernandez 	uint32_t i = 0;
2133*9be88e75SGabriel Fernandez 	int node = 0;
2134*9be88e75SGabriel Fernandez 
2135*9be88e75SGabriel Fernandez 	node = fdt_path_offset(fdt, "/clocks");
2136*9be88e75SGabriel Fernandez 	if (node < 0) {
2137*9be88e75SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
2138*9be88e75SGabriel Fernandez 	}
2139*9be88e75SGabriel Fernandez 
2140*9be88e75SGabriel Fernandez 	for (i = 0; i < pdata->nosci; i++) {
2141*9be88e75SGabriel Fernandez 		const char *name = NULL;
2142*9be88e75SGabriel Fernandez 
2143*9be88e75SGabriel Fernandez 		name = clk_stm32_get_oscillator_name((enum stm32_osc)i);
2144*9be88e75SGabriel Fernandez 		if (name == NULL) {
2145*9be88e75SGabriel Fernandez 			continue;
2146*9be88e75SGabriel Fernandez 		}
2147*9be88e75SGabriel Fernandez 
2148*9be88e75SGabriel Fernandez 		fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]);
2149*9be88e75SGabriel Fernandez 		if (fdt_err < 0) {
2150*9be88e75SGabriel Fernandez 			panic();
2151*9be88e75SGabriel Fernandez 		}
2152*9be88e75SGabriel Fernandez 	}
2153*9be88e75SGabriel Fernandez 
2154*9be88e75SGabriel Fernandez 	return 0;
2155*9be88e75SGabriel Fernandez }
2156*9be88e75SGabriel Fernandez 
2157*9be88e75SGabriel Fernandez #define RCC_PLL_NAME_SIZE 12
2158*9be88e75SGabriel Fernandez 
2159*9be88e75SGabriel Fernandez static int clk_stm32_load_vco_config(void *fdt, int subnode, struct stm32_pll_vco *vco)
2160*9be88e75SGabriel Fernandez {
2161*9be88e75SGabriel Fernandez 	int err = 0;
2162*9be88e75SGabriel Fernandez 
2163*9be88e75SGabriel Fernandez 	err = fdt_read_uint32_array(fdt, subnode, "divmn", (int)PLL_DIV_MN_NB, vco->div_mn);
2164*9be88e75SGabriel Fernandez 	if (err != 0) {
2165*9be88e75SGabriel Fernandez 		return err;
2166*9be88e75SGabriel Fernandez 	}
2167*9be88e75SGabriel Fernandez 
2168*9be88e75SGabriel Fernandez 	err = fdt_read_uint32_array(fdt, subnode, "csg", (int)PLL_CSG_NB, vco->csg);
2169*9be88e75SGabriel Fernandez 
2170*9be88e75SGabriel Fernandez 	vco->csg_enabled = (err == 0);
2171*9be88e75SGabriel Fernandez 
2172*9be88e75SGabriel Fernandez 	if (err == -FDT_ERR_NOTFOUND) {
2173*9be88e75SGabriel Fernandez 		err = 0;
2174*9be88e75SGabriel Fernandez 	}
2175*9be88e75SGabriel Fernandez 
2176*9be88e75SGabriel Fernandez 	if (err != 0) {
2177*9be88e75SGabriel Fernandez 		return err;
2178*9be88e75SGabriel Fernandez 	}
2179*9be88e75SGabriel Fernandez 
2180*9be88e75SGabriel Fernandez 	vco->status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN | RCC_PLLNCR_PLLON;
2181*9be88e75SGabriel Fernandez 
2182*9be88e75SGabriel Fernandez 	vco->frac = fdt_read_uint32_default(fdt, subnode, "frac", 0);
2183*9be88e75SGabriel Fernandez 
2184*9be88e75SGabriel Fernandez 	vco->src = fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX);
2185*9be88e75SGabriel Fernandez 
2186*9be88e75SGabriel Fernandez 	return 0;
2187*9be88e75SGabriel Fernandez }
2188*9be88e75SGabriel Fernandez 
2189*9be88e75SGabriel Fernandez static int clk_stm32_load_output_config(void *fdt, int subnode, struct stm32_pll_output *output)
2190*9be88e75SGabriel Fernandez {
2191*9be88e75SGabriel Fernandez 	int err = 0;
2192*9be88e75SGabriel Fernandez 
2193*9be88e75SGabriel Fernandez 	err = fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr", (int)PLL_DIV_PQR_NB,
2194*9be88e75SGabriel Fernandez 				    output->output);
2195*9be88e75SGabriel Fernandez 	if (err != 0) {
2196*9be88e75SGabriel Fernandez 		return err;
2197*9be88e75SGabriel Fernandez 	}
2198*9be88e75SGabriel Fernandez 
2199*9be88e75SGabriel Fernandez 	return 0;
2200*9be88e75SGabriel Fernandez }
2201*9be88e75SGabriel Fernandez 
2202*9be88e75SGabriel Fernandez static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
2203*9be88e75SGabriel Fernandez {
2204*9be88e75SGabriel Fernandez 	const fdt32_t *cuint = NULL;
2205*9be88e75SGabriel Fernandez 	int subnode_pll = 0;
2206*9be88e75SGabriel Fernandez 	int subnode_vco = 0;
2207*9be88e75SGabriel Fernandez 	int err = 0;
2208*9be88e75SGabriel Fernandez 
2209*9be88e75SGabriel Fernandez 	cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
2210*9be88e75SGabriel Fernandez 	if (!cuint) {
2211*9be88e75SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
2212*9be88e75SGabriel Fernandez 	}
2213*9be88e75SGabriel Fernandez 
2214*9be88e75SGabriel Fernandez 	subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
2215*9be88e75SGabriel Fernandez 	if (subnode_pll < 0) {
2216*9be88e75SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
2217*9be88e75SGabriel Fernandez 	}
2218*9be88e75SGabriel Fernandez 
2219*9be88e75SGabriel Fernandez 	cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL);
2220*9be88e75SGabriel Fernandez 	if (!cuint) {
2221*9be88e75SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
2222*9be88e75SGabriel Fernandez 	}
2223*9be88e75SGabriel Fernandez 
2224*9be88e75SGabriel Fernandez 	subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
2225*9be88e75SGabriel Fernandez 	if (subnode_vco < 0) {
2226*9be88e75SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
2227*9be88e75SGabriel Fernandez 	}
2228*9be88e75SGabriel Fernandez 
2229*9be88e75SGabriel Fernandez 	err = clk_stm32_load_vco_config(fdt, subnode_vco, &pll->vco);
2230*9be88e75SGabriel Fernandez 	if (err != 0) {
2231*9be88e75SGabriel Fernandez 		return err;
2232*9be88e75SGabriel Fernandez 	}
2233*9be88e75SGabriel Fernandez 
2234*9be88e75SGabriel Fernandez 	err = clk_stm32_load_output_config(fdt, subnode_pll, &pll->output);
2235*9be88e75SGabriel Fernandez 	if (err != 0) {
2236*9be88e75SGabriel Fernandez 		return err;
2237*9be88e75SGabriel Fernandez 	}
2238*9be88e75SGabriel Fernandez 
2239*9be88e75SGabriel Fernandez 	return 0;
2240*9be88e75SGabriel Fernandez }
2241*9be88e75SGabriel Fernandez 
2242*9be88e75SGabriel Fernandez static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
2243*9be88e75SGabriel Fernandez {
2244*9be88e75SGabriel Fernandez 	size_t i = 0U;
2245*9be88e75SGabriel Fernandez 
2246*9be88e75SGabriel Fernandez 	for (i = _PLL1; i < pdata->npll; i++) {
2247*9be88e75SGabriel Fernandez 		struct stm32_pll_dt_cfg *pll = pdata->pll + i;
2248*9be88e75SGabriel Fernandez 		char name[RCC_PLL_NAME_SIZE];
2249*9be88e75SGabriel Fernandez 		int subnode = 0;
2250*9be88e75SGabriel Fernandez 		int err = 0;
2251*9be88e75SGabriel Fernandez 
2252*9be88e75SGabriel Fernandez 		snprintf(name, sizeof(name), "st,pll@%u", i);
2253*9be88e75SGabriel Fernandez 
2254*9be88e75SGabriel Fernandez 		subnode = fdt_subnode_offset(fdt, node, name);
2255*9be88e75SGabriel Fernandez 		if (!fdt_check_node(subnode)) {
2256*9be88e75SGabriel Fernandez 			continue;
2257*9be88e75SGabriel Fernandez 		}
2258*9be88e75SGabriel Fernandez 
2259*9be88e75SGabriel Fernandez 		err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
2260*9be88e75SGabriel Fernandez 		if (err != 0) {
2261*9be88e75SGabriel Fernandez 			panic();
2262*9be88e75SGabriel Fernandez 		}
2263*9be88e75SGabriel Fernandez 	}
2264*9be88e75SGabriel Fernandez 
2265*9be88e75SGabriel Fernandez 	return 0;
2266*9be88e75SGabriel Fernandez }
2267*9be88e75SGabriel Fernandez 
2268*9be88e75SGabriel Fernandez static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
2269*9be88e75SGabriel Fernandez {
2270*9be88e75SGabriel Fernandez 	void *fdt = NULL;
2271*9be88e75SGabriel Fernandez 	int node;
2272*9be88e75SGabriel Fernandez 	uint32_t err;
2273*9be88e75SGabriel Fernandez 
2274*9be88e75SGabriel Fernandez 	if (fdt_get_address(&fdt) == 0) {
2275*9be88e75SGabriel Fernandez 		return -ENOENT;
2276*9be88e75SGabriel Fernandez 	}
2277*9be88e75SGabriel Fernandez 
2278*9be88e75SGabriel Fernandez 	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
2279*9be88e75SGabriel Fernandez 	if (node < 0) {
2280*9be88e75SGabriel Fernandez 		panic();
2281*9be88e75SGabriel Fernandez 	}
2282*9be88e75SGabriel Fernandez 
2283*9be88e75SGabriel Fernandez 	err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata);
2284*9be88e75SGabriel Fernandez 	if (err != 0) {
2285*9be88e75SGabriel Fernandez 		return err;
2286*9be88e75SGabriel Fernandez 	}
2287*9be88e75SGabriel Fernandez 
2288*9be88e75SGabriel Fernandez 	err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
2289*9be88e75SGabriel Fernandez 	if (err != 0) {
2290*9be88e75SGabriel Fernandez 		return err;
2291*9be88e75SGabriel Fernandez 	}
2292*9be88e75SGabriel Fernandez 
2293*9be88e75SGabriel Fernandez 	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv, &pdata->nclkdiv);
2294*9be88e75SGabriel Fernandez 	if (err != 0) {
2295*9be88e75SGabriel Fernandez 		return err;
2296*9be88e75SGabriel Fernandez 	}
2297*9be88e75SGabriel Fernandez 
2298*9be88e75SGabriel Fernandez 	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc, &pdata->nclksrc);
2299*9be88e75SGabriel Fernandez 	if (err != 0) {
2300*9be88e75SGabriel Fernandez 		return err;
2301*9be88e75SGabriel Fernandez 	}
2302*9be88e75SGabriel Fernandez 
2303*9be88e75SGabriel Fernandez 	return 0;
2304*9be88e75SGabriel Fernandez }
2305*9be88e75SGabriel Fernandez 
2306*9be88e75SGabriel Fernandez int stm32mp1_clk_init(void)
2307*9be88e75SGabriel Fernandez {
2308*9be88e75SGabriel Fernandez 	return 0;
2309*9be88e75SGabriel Fernandez }
2310*9be88e75SGabriel Fernandez 
2311*9be88e75SGabriel Fernandez int stm32mp1_clk_probe(void)
2312*9be88e75SGabriel Fernandez {
2313*9be88e75SGabriel Fernandez 	uintptr_t base = RCC_BASE;
2314*9be88e75SGabriel Fernandez 	int ret;
2315*9be88e75SGabriel Fernandez 
2316*9be88e75SGabriel Fernandez 	ret = stm32_clk_parse_fdt(&stm32mp13_clock_pdata);
2317*9be88e75SGabriel Fernandez 	if (ret != 0) {
2318*9be88e75SGabriel Fernandez 		return ret;
2319*9be88e75SGabriel Fernandez 	}
2320*9be88e75SGabriel Fernandez 
2321*9be88e75SGabriel Fernandez 	ret = clk_stm32_init(&stm32mp13_clock_data, base);
2322*9be88e75SGabriel Fernandez 	if (ret != 0) {
2323*9be88e75SGabriel Fernandez 		return ret;
2324*9be88e75SGabriel Fernandez 	}
2325*9be88e75SGabriel Fernandez 
2326*9be88e75SGabriel Fernandez 	ret = stm32mp1_init_clock_tree();
2327*9be88e75SGabriel Fernandez 	if (ret != 0) {
2328*9be88e75SGabriel Fernandez 		return ret;
2329*9be88e75SGabriel Fernandez 	}
2330*9be88e75SGabriel Fernandez 
2331*9be88e75SGabriel Fernandez 	clk_stm32_enable_critical_clocks();
2332*9be88e75SGabriel Fernandez 
2333*9be88e75SGabriel Fernandez 	return 0;
2334*9be88e75SGabriel Fernandez }
2335