xref: /optee_os/core/drivers/clk/clk-stm32mp13.c (revision e5e793a6f1c758c7b43b576fa288127867bd7de1)
1*e5e793a6SGabriel Fernandez // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2*e5e793a6SGabriel Fernandez /*
3*e5e793a6SGabriel Fernandez  * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
4*e5e793a6SGabriel Fernandez  */
5*e5e793a6SGabriel Fernandez 
6*e5e793a6SGabriel Fernandez #include <assert.h>
7*e5e793a6SGabriel Fernandez #include <drivers/clk.h>
8*e5e793a6SGabriel Fernandez #include <drivers/clk_dt.h>
9*e5e793a6SGabriel Fernandez #include <drivers/stm32mp_dt_bindings.h>
10*e5e793a6SGabriel Fernandez #include <drivers/stm32mp13_rcc.h>
11*e5e793a6SGabriel Fernandez #include <io.h>
12*e5e793a6SGabriel Fernandez #include <kernel/boot.h>
13*e5e793a6SGabriel Fernandez #include <libfdt.h>
14*e5e793a6SGabriel Fernandez #include <stdio.h>
15*e5e793a6SGabriel Fernandez 
16*e5e793a6SGabriel Fernandez #include "clk-stm32-core.h"
17*e5e793a6SGabriel Fernandez 
18*e5e793a6SGabriel Fernandez #define MAX_HSI_HZ		64000000
19*e5e793a6SGabriel Fernandez #define USB_PHY_48_MHZ		48000000
20*e5e793a6SGabriel Fernandez 
21*e5e793a6SGabriel Fernandez #define TIMEOUT_US_200MS	U(200000)
22*e5e793a6SGabriel Fernandez #define HSIDIV_TIMEOUT		TIMEOUT_US_200MS
23*e5e793a6SGabriel Fernandez 
24*e5e793a6SGabriel Fernandez #define MAX_OPP		CFG_STM32MP_OPP_COUNT
25*e5e793a6SGabriel Fernandez 
26*e5e793a6SGabriel Fernandez #define RCC_PLL_NAME_SIZE 12
27*e5e793a6SGabriel Fernandez 
28*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg {
29*e5e793a6SGabriel Fernandez 	unsigned long freq;
30*e5e793a6SGabriel Fernandez 	bool bypass;
31*e5e793a6SGabriel Fernandez 	bool digbyp;
32*e5e793a6SGabriel Fernandez 	bool css;
33*e5e793a6SGabriel Fernandez 	uint32_t drive;
34*e5e793a6SGabriel Fernandez };
35*e5e793a6SGabriel Fernandez 
36*e5e793a6SGabriel Fernandez enum pll_mn {
37*e5e793a6SGabriel Fernandez 	PLL_CFG_M,
38*e5e793a6SGabriel Fernandez 	PLL_CFG_N,
39*e5e793a6SGabriel Fernandez 	PLL_DIV_MN_NB
40*e5e793a6SGabriel Fernandez };
41*e5e793a6SGabriel Fernandez 
42*e5e793a6SGabriel Fernandez enum pll_pqr {
43*e5e793a6SGabriel Fernandez 	PLL_CFG_P,
44*e5e793a6SGabriel Fernandez 	PLL_CFG_Q,
45*e5e793a6SGabriel Fernandez 	PLL_CFG_R,
46*e5e793a6SGabriel Fernandez 	PLL_DIV_PQR_NB
47*e5e793a6SGabriel Fernandez };
48*e5e793a6SGabriel Fernandez 
49*e5e793a6SGabriel Fernandez enum pll_csg {
50*e5e793a6SGabriel Fernandez 	PLL_CSG_MOD_PER,
51*e5e793a6SGabriel Fernandez 	PLL_CSG_INC_STEP,
52*e5e793a6SGabriel Fernandez 	PLL_CSG_SSCG_MODE,
53*e5e793a6SGabriel Fernandez 	PLL_CSG_NB
54*e5e793a6SGabriel Fernandez };
55*e5e793a6SGabriel Fernandez 
56*e5e793a6SGabriel Fernandez struct stm32_pll_vco {
57*e5e793a6SGabriel Fernandez 	uint32_t status;
58*e5e793a6SGabriel Fernandez 	uint32_t src;
59*e5e793a6SGabriel Fernandez 	uint32_t div_mn[PLL_DIV_MN_NB];
60*e5e793a6SGabriel Fernandez 	uint32_t frac;
61*e5e793a6SGabriel Fernandez 	bool csg_enabled;
62*e5e793a6SGabriel Fernandez 	uint32_t csg[PLL_CSG_NB];
63*e5e793a6SGabriel Fernandez };
64*e5e793a6SGabriel Fernandez 
65*e5e793a6SGabriel Fernandez struct stm32_pll_output {
66*e5e793a6SGabriel Fernandez 	uint32_t output[PLL_DIV_PQR_NB];
67*e5e793a6SGabriel Fernandez };
68*e5e793a6SGabriel Fernandez 
69*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg {
70*e5e793a6SGabriel Fernandez 	struct stm32_pll_vco vco;
71*e5e793a6SGabriel Fernandez 	struct stm32_pll_output output;
72*e5e793a6SGabriel Fernandez };
73*e5e793a6SGabriel Fernandez 
74*e5e793a6SGabriel Fernandez struct stm32_clk_opp_cfg {
75*e5e793a6SGabriel Fernandez 	uint32_t frq;
76*e5e793a6SGabriel Fernandez 	uint32_t src;
77*e5e793a6SGabriel Fernandez 	uint32_t div;
78*e5e793a6SGabriel Fernandez 	struct stm32_pll_dt_cfg pll_cfg;
79*e5e793a6SGabriel Fernandez };
80*e5e793a6SGabriel Fernandez 
81*e5e793a6SGabriel Fernandez struct stm32_clk_opp_dt_cfg {
82*e5e793a6SGabriel Fernandez 	struct stm32_clk_opp_cfg mpu_opp[MAX_OPP];
83*e5e793a6SGabriel Fernandez 	struct stm32_clk_opp_cfg axi_opp[MAX_OPP];
84*e5e793a6SGabriel Fernandez 	struct stm32_clk_opp_cfg mlahbs_opp[MAX_OPP];
85*e5e793a6SGabriel Fernandez };
86*e5e793a6SGabriel Fernandez 
87*e5e793a6SGabriel Fernandez struct stm32_clk_platdata {
88*e5e793a6SGabriel Fernandez 	uintptr_t rcc_base;
89*e5e793a6SGabriel Fernandez 	uint32_t nosci;
90*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci;
91*e5e793a6SGabriel Fernandez 	uint32_t npll;
92*e5e793a6SGabriel Fernandez 	struct stm32_pll_dt_cfg *pll;
93*e5e793a6SGabriel Fernandez 	struct stm32_clk_opp_dt_cfg *opp;
94*e5e793a6SGabriel Fernandez 	uint32_t nclksrc;
95*e5e793a6SGabriel Fernandez 	uint32_t *clksrc;
96*e5e793a6SGabriel Fernandez 	uint32_t nclkdiv;
97*e5e793a6SGabriel Fernandez 	uint32_t *clkdiv;
98*e5e793a6SGabriel Fernandez };
99*e5e793a6SGabriel Fernandez 
100*e5e793a6SGabriel Fernandez /*
101*e5e793a6SGabriel Fernandez  * GATE CONFIG
102*e5e793a6SGabriel Fernandez  */
103*e5e793a6SGabriel Fernandez 
104*e5e793a6SGabriel Fernandez /* Warning GATE_XXX_RDY must follow GATE_XXX */
105*e5e793a6SGabriel Fernandez enum enum_gate_cfg {
106*e5e793a6SGabriel Fernandez 	GATE_LSE,
107*e5e793a6SGabriel Fernandez 	GATE_LSE_RDY,
108*e5e793a6SGabriel Fernandez 	GATE_LSI,
109*e5e793a6SGabriel Fernandez 	GATE_LSI_RDY,
110*e5e793a6SGabriel Fernandez 	GATE_HSI,
111*e5e793a6SGabriel Fernandez 	GATE_HSI_RDY,
112*e5e793a6SGabriel Fernandez 	GATE_CSI,
113*e5e793a6SGabriel Fernandez 	GATE_CSI_RDY,
114*e5e793a6SGabriel Fernandez 	GATE_HSE,
115*e5e793a6SGabriel Fernandez 	GATE_HSE_RDY,
116*e5e793a6SGabriel Fernandez 	GATE_PLL1,
117*e5e793a6SGabriel Fernandez 	GATE_PLL1_RDY,
118*e5e793a6SGabriel Fernandez 	GATE_PLL2,
119*e5e793a6SGabriel Fernandez 	GATE_PLL2_RDY,
120*e5e793a6SGabriel Fernandez 	GATE_PLL3,
121*e5e793a6SGabriel Fernandez 	GATE_PLL3_RDY,
122*e5e793a6SGabriel Fernandez 	GATE_PLL4,
123*e5e793a6SGabriel Fernandez 	GATE_PLL4_RDY,
124*e5e793a6SGabriel Fernandez 	GATE_HSIDIVRDY,
125*e5e793a6SGabriel Fernandez 	GATE_MPUSRCRDY,
126*e5e793a6SGabriel Fernandez 	GATE_AXISSRCRDY,
127*e5e793a6SGabriel Fernandez 	GATE_MCUSSRCRDY,
128*e5e793a6SGabriel Fernandez 	GATE_PLL12SRCRDY,
129*e5e793a6SGabriel Fernandez 	GATE_PLL3SRCRDY,
130*e5e793a6SGabriel Fernandez 	GATE_PLL4SRCRDY,
131*e5e793a6SGabriel Fernandez 	GATE_MPUDIVRDY,
132*e5e793a6SGabriel Fernandez 	GATE_AXIDIVRDY,
133*e5e793a6SGabriel Fernandez 	GATE_MLAHBDIVRDY,
134*e5e793a6SGabriel Fernandez 	GATE_APB1DIVRDY,
135*e5e793a6SGabriel Fernandez 	GATE_APB2DIVRDY,
136*e5e793a6SGabriel Fernandez 	GATE_APB3DIVRDY,
137*e5e793a6SGabriel Fernandez 	GATE_APB4DIVRDY,
138*e5e793a6SGabriel Fernandez 	GATE_APB5DIVRDY,
139*e5e793a6SGabriel Fernandez 	GATE_APB6DIVRDY,
140*e5e793a6SGabriel Fernandez 	GATE_RTCCK,
141*e5e793a6SGabriel Fernandez 	GATE_MCO1,
142*e5e793a6SGabriel Fernandez 	GATE_MCO2,
143*e5e793a6SGabriel Fernandez 	GATE_DBGCK,
144*e5e793a6SGabriel Fernandez 	GATE_TRACECK,
145*e5e793a6SGabriel Fernandez 	GATE_PLL1_DIVP,
146*e5e793a6SGabriel Fernandez 	GATE_PLL1_DIVQ,
147*e5e793a6SGabriel Fernandez 	GATE_PLL1_DIVR,
148*e5e793a6SGabriel Fernandez 	GATE_PLL2_DIVP,
149*e5e793a6SGabriel Fernandez 	GATE_PLL2_DIVQ,
150*e5e793a6SGabriel Fernandez 	GATE_PLL2_DIVR,
151*e5e793a6SGabriel Fernandez 	GATE_PLL3_DIVP,
152*e5e793a6SGabriel Fernandez 	GATE_PLL3_DIVQ,
153*e5e793a6SGabriel Fernandez 	GATE_PLL3_DIVR,
154*e5e793a6SGabriel Fernandez 	GATE_PLL4_DIVP,
155*e5e793a6SGabriel Fernandez 	GATE_PLL4_DIVQ,
156*e5e793a6SGabriel Fernandez 	GATE_PLL4_DIVR,
157*e5e793a6SGabriel Fernandez 	GATE_DDRC1,
158*e5e793a6SGabriel Fernandez 	GATE_DDRC1LP,
159*e5e793a6SGabriel Fernandez 	GATE_DDRPHYC,
160*e5e793a6SGabriel Fernandez 	GATE_DDRPHYCLP,
161*e5e793a6SGabriel Fernandez 	GATE_DDRCAPB,
162*e5e793a6SGabriel Fernandez 	GATE_DDRCAPBLP,
163*e5e793a6SGabriel Fernandez 	GATE_AXIDCG,
164*e5e793a6SGabriel Fernandez 	GATE_DDRPHYCAPB,
165*e5e793a6SGabriel Fernandez 	GATE_DDRPHYCAPBLP,
166*e5e793a6SGabriel Fernandez 	GATE_TIM2,
167*e5e793a6SGabriel Fernandez 	GATE_TIM3,
168*e5e793a6SGabriel Fernandez 	GATE_TIM4,
169*e5e793a6SGabriel Fernandez 	GATE_TIM5,
170*e5e793a6SGabriel Fernandez 	GATE_TIM6,
171*e5e793a6SGabriel Fernandez 	GATE_TIM7,
172*e5e793a6SGabriel Fernandez 	GATE_LPTIM1,
173*e5e793a6SGabriel Fernandez 	GATE_SPI2,
174*e5e793a6SGabriel Fernandez 	GATE_SPI3,
175*e5e793a6SGabriel Fernandez 	GATE_USART3,
176*e5e793a6SGabriel Fernandez 	GATE_UART4,
177*e5e793a6SGabriel Fernandez 	GATE_UART5,
178*e5e793a6SGabriel Fernandez 	GATE_UART7,
179*e5e793a6SGabriel Fernandez 	GATE_UART8,
180*e5e793a6SGabriel Fernandez 	GATE_I2C1,
181*e5e793a6SGabriel Fernandez 	GATE_I2C2,
182*e5e793a6SGabriel Fernandez 	GATE_SPDIF,
183*e5e793a6SGabriel Fernandez 	GATE_TIM1,
184*e5e793a6SGabriel Fernandez 	GATE_TIM8,
185*e5e793a6SGabriel Fernandez 	GATE_SPI1,
186*e5e793a6SGabriel Fernandez 	GATE_USART6,
187*e5e793a6SGabriel Fernandez 	GATE_SAI1,
188*e5e793a6SGabriel Fernandez 	GATE_SAI2,
189*e5e793a6SGabriel Fernandez 	GATE_DFSDM,
190*e5e793a6SGabriel Fernandez 	GATE_ADFSDM,
191*e5e793a6SGabriel Fernandez 	GATE_FDCAN,
192*e5e793a6SGabriel Fernandez 	GATE_LPTIM2,
193*e5e793a6SGabriel Fernandez 	GATE_LPTIM3,
194*e5e793a6SGabriel Fernandez 	GATE_LPTIM4,
195*e5e793a6SGabriel Fernandez 	GATE_LPTIM5,
196*e5e793a6SGabriel Fernandez 	GATE_VREF,
197*e5e793a6SGabriel Fernandez 	GATE_DTS,
198*e5e793a6SGabriel Fernandez 	GATE_PMBCTRL,
199*e5e793a6SGabriel Fernandez 	GATE_HDP,
200*e5e793a6SGabriel Fernandez 	GATE_SYSCFG,
201*e5e793a6SGabriel Fernandez 	GATE_DCMIPP,
202*e5e793a6SGabriel Fernandez 	GATE_DDRPERFM,
203*e5e793a6SGabriel Fernandez 	GATE_IWDG2APB,
204*e5e793a6SGabriel Fernandez 	GATE_USBPHY,
205*e5e793a6SGabriel Fernandez 	GATE_STGENRO,
206*e5e793a6SGabriel Fernandez 	GATE_LTDC,
207*e5e793a6SGabriel Fernandez 	GATE_RTCAPB,
208*e5e793a6SGabriel Fernandez 	GATE_TZC,
209*e5e793a6SGabriel Fernandez 	GATE_ETZPC,
210*e5e793a6SGabriel Fernandez 	GATE_IWDG1APB,
211*e5e793a6SGabriel Fernandez 	GATE_BSEC,
212*e5e793a6SGabriel Fernandez 	GATE_STGENC,
213*e5e793a6SGabriel Fernandez 	GATE_USART1,
214*e5e793a6SGabriel Fernandez 	GATE_USART2,
215*e5e793a6SGabriel Fernandez 	GATE_SPI4,
216*e5e793a6SGabriel Fernandez 	GATE_SPI5,
217*e5e793a6SGabriel Fernandez 	GATE_I2C3,
218*e5e793a6SGabriel Fernandez 	GATE_I2C4,
219*e5e793a6SGabriel Fernandez 	GATE_I2C5,
220*e5e793a6SGabriel Fernandez 	GATE_TIM12,
221*e5e793a6SGabriel Fernandez 	GATE_TIM13,
222*e5e793a6SGabriel Fernandez 	GATE_TIM14,
223*e5e793a6SGabriel Fernandez 	GATE_TIM15,
224*e5e793a6SGabriel Fernandez 	GATE_TIM16,
225*e5e793a6SGabriel Fernandez 	GATE_TIM17,
226*e5e793a6SGabriel Fernandez 	GATE_DMA1,
227*e5e793a6SGabriel Fernandez 	GATE_DMA2,
228*e5e793a6SGabriel Fernandez 	GATE_DMAMUX1,
229*e5e793a6SGabriel Fernandez 	GATE_DMA3,
230*e5e793a6SGabriel Fernandez 	GATE_DMAMUX2,
231*e5e793a6SGabriel Fernandez 	GATE_ADC1,
232*e5e793a6SGabriel Fernandez 	GATE_ADC2,
233*e5e793a6SGabriel Fernandez 	GATE_USBO,
234*e5e793a6SGabriel Fernandez 	GATE_TSC,
235*e5e793a6SGabriel Fernandez 	GATE_GPIOA,
236*e5e793a6SGabriel Fernandez 	GATE_GPIOB,
237*e5e793a6SGabriel Fernandez 	GATE_GPIOC,
238*e5e793a6SGabriel Fernandez 	GATE_GPIOD,
239*e5e793a6SGabriel Fernandez 	GATE_GPIOE,
240*e5e793a6SGabriel Fernandez 	GATE_GPIOF,
241*e5e793a6SGabriel Fernandez 	GATE_GPIOG,
242*e5e793a6SGabriel Fernandez 	GATE_GPIOH,
243*e5e793a6SGabriel Fernandez 	GATE_GPIOI,
244*e5e793a6SGabriel Fernandez 	GATE_PKA,
245*e5e793a6SGabriel Fernandez 	GATE_SAES,
246*e5e793a6SGabriel Fernandez 	GATE_CRYP1,
247*e5e793a6SGabriel Fernandez 	GATE_HASH1,
248*e5e793a6SGabriel Fernandez 	GATE_RNG1,
249*e5e793a6SGabriel Fernandez 	GATE_BKPSRAM,
250*e5e793a6SGabriel Fernandez 	GATE_AXIMC,
251*e5e793a6SGabriel Fernandez 	GATE_MCE,
252*e5e793a6SGabriel Fernandez 	GATE_ETH1CK,
253*e5e793a6SGabriel Fernandez 	GATE_ETH1TX,
254*e5e793a6SGabriel Fernandez 	GATE_ETH1RX,
255*e5e793a6SGabriel Fernandez 	GATE_ETH1MAC,
256*e5e793a6SGabriel Fernandez 	GATE_FMC,
257*e5e793a6SGabriel Fernandez 	GATE_QSPI,
258*e5e793a6SGabriel Fernandez 	GATE_SDMMC1,
259*e5e793a6SGabriel Fernandez 	GATE_SDMMC2,
260*e5e793a6SGabriel Fernandez 	GATE_CRC1,
261*e5e793a6SGabriel Fernandez 	GATE_USBH,
262*e5e793a6SGabriel Fernandez 	GATE_ETH2CK,
263*e5e793a6SGabriel Fernandez 	GATE_ETH2TX,
264*e5e793a6SGabriel Fernandez 	GATE_ETH2RX,
265*e5e793a6SGabriel Fernandez 	GATE_ETH2MAC,
266*e5e793a6SGabriel Fernandez 	GATE_MDMA,
267*e5e793a6SGabriel Fernandez 	GATE_NB
268*e5e793a6SGabriel Fernandez };
269*e5e793a6SGabriel Fernandez 
270*e5e793a6SGabriel Fernandez #define GATE_CFG(_id, _offset, _bit_idx, _offset_clr)\
271*e5e793a6SGabriel Fernandez 	[(_id)] = {\
272*e5e793a6SGabriel Fernandez 		.offset		= (_offset),\
273*e5e793a6SGabriel Fernandez 		.bit_idx	= (_bit_idx),\
274*e5e793a6SGabriel Fernandez 		.set_clr	= (_offset_clr),\
275*e5e793a6SGabriel Fernandez 	}
276*e5e793a6SGabriel Fernandez 
277*e5e793a6SGabriel Fernandez static const struct gate_cfg gates_mp13[GATE_NB] = {
278*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LSE,		RCC_BDCR,		0,	0),
279*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LSE_RDY,		RCC_BDCR,		2,	0),
280*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_RTCCK,		RCC_BDCR,		20,	0),
281*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LSI,		RCC_RDLSICR,		0,	0),
282*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LSI_RDY,		RCC_RDLSICR,		1,	0),
283*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_HSI,		RCC_OCENSETR,		0,	1),
284*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_HSI_RDY,		RCC_OCRDYR,		0,	0),
285*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_CSI,		RCC_OCENSETR,		4,	1),
286*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_CSI_RDY,		RCC_OCRDYR,		4,	0),
287*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_HSE,		RCC_OCENSETR,		8,	1),
288*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_HSE_RDY,		RCC_OCRDYR,		8,	0),
289*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_HSIDIVRDY,	RCC_OCRDYR,		2,	0),
290*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_MPUSRCRDY,	RCC_MPCKSELR,		31,	0),
291*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_AXISSRCRDY,	RCC_ASSCKSELR,		31,	0),
292*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_MCUSSRCRDY,	RCC_MSSCKSELR,		31,	0),
293*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL12SRCRDY,	RCC_RCK12SELR,		31,	0),
294*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL3SRCRDY,	RCC_RCK3SELR,		31,	0),
295*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL4SRCRDY,	RCC_RCK4SELR,		31,	0),
296*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_MPUDIVRDY,	RCC_MPCKDIVR,		31,	0),
297*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_AXIDIVRDY,	RCC_AXIDIVR,		31,	0),
298*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_MLAHBDIVRDY,	RCC_MLAHBDIVR,		31,	0),
299*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_APB1DIVRDY,	RCC_APB1DIVR,		31,	0),
300*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_APB2DIVRDY,	RCC_APB2DIVR,		31,	0),
301*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_APB3DIVRDY,	RCC_APB3DIVR,		31,	0),
302*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_APB4DIVRDY,	RCC_APB4DIVR,		31,	0),
303*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_APB5DIVRDY,	RCC_APB5DIVR,		31,	0),
304*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_APB6DIVRDY,	RCC_APB6DIVR,		31,	0),
305*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_MCO1,		RCC_MCO1CFGR,		12,	0),
306*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_MCO2,		RCC_MCO2CFGR,		12,	0),
307*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DBGCK,		RCC_DBGCFGR,		8,	0),
308*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TRACECK,		RCC_DBGCFGR,		9,	0),
309*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL1,		RCC_PLL1CR,		0,	0),
310*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL1_RDY,		RCC_PLL1CR,		1,	0),
311*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL1_DIVP,	RCC_PLL1CR,		4,	0),
312*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL1_DIVQ,	RCC_PLL1CR,		5,	0),
313*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL1_DIVR,	RCC_PLL1CR,		6,	0),
314*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL2,		RCC_PLL2CR,		0,	0),
315*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL2_RDY,		RCC_PLL2CR,		1,	0),
316*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL2_DIVP,	RCC_PLL2CR,		4,	0),
317*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL2_DIVQ,	RCC_PLL2CR,		5,	0),
318*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL2_DIVR,	RCC_PLL2CR,		6,	0),
319*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL3,		RCC_PLL3CR,		0,	0),
320*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL3_RDY,		RCC_PLL3CR,		1,	0),
321*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL3_DIVP,	RCC_PLL3CR,		4,	0),
322*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL3_DIVQ,	RCC_PLL3CR,		5,	0),
323*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL3_DIVR,	RCC_PLL3CR,		6,	0),
324*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL4,		RCC_PLL4CR,		0,	0),
325*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL4_RDY,		RCC_PLL4CR,		1,	0),
326*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL4_DIVP,	RCC_PLL4CR,		4,	0),
327*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL4_DIVQ,	RCC_PLL4CR,		5,	0),
328*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PLL4_DIVR,	RCC_PLL4CR,		6,	0),
329*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRC1,		RCC_DDRITFCR,		0,	0),
330*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRC1LP,		RCC_DDRITFCR,		1,	0),
331*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRPHYC,		RCC_DDRITFCR,		4,	0),
332*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRPHYCLP,	RCC_DDRITFCR,		5,	0),
333*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRCAPB,		RCC_DDRITFCR,		6,	0),
334*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRCAPBLP,	RCC_DDRITFCR,		7,	0),
335*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_AXIDCG,		RCC_DDRITFCR,		8,	0),
336*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRPHYCAPB,	RCC_DDRITFCR,		9,	0),
337*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRPHYCAPBLP,	RCC_DDRITFCR,		10,	0),
338*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM2,		RCC_MP_APB1ENSETR,	0,	1),
339*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM3,		RCC_MP_APB1ENSETR,	1,	1),
340*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM4,		RCC_MP_APB1ENSETR,	2,	1),
341*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM5,		RCC_MP_APB1ENSETR,	3,	1),
342*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM6,		RCC_MP_APB1ENSETR,	4,	1),
343*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM7,		RCC_MP_APB1ENSETR,	5,	1),
344*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LPTIM1,		RCC_MP_APB1ENSETR,	9,	1),
345*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SPI2,		RCC_MP_APB1ENSETR,	11,	1),
346*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SPI3,		RCC_MP_APB1ENSETR,	12,	1),
347*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_USART3,		RCC_MP_APB1ENSETR,	15,	1),
348*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_UART4,		RCC_MP_APB1ENSETR,	16,	1),
349*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_UART5,		RCC_MP_APB1ENSETR,	17,	1),
350*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_UART7,		RCC_MP_APB1ENSETR,	18,	1),
351*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_UART8,		RCC_MP_APB1ENSETR,	19,	1),
352*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_I2C1,		RCC_MP_APB1ENSETR,	21,	1),
353*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_I2C2,		RCC_MP_APB1ENSETR,	22,	1),
354*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SPDIF,		RCC_MP_APB1ENSETR,	26,	1),
355*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM1,		RCC_MP_APB2ENSETR,	0,	1),
356*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM8,		RCC_MP_APB2ENSETR,	1,	1),
357*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SPI1,		RCC_MP_APB2ENSETR,	8,	1),
358*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_USART6,		RCC_MP_APB2ENSETR,	13,	1),
359*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SAI1,		RCC_MP_APB2ENSETR,	16,	1),
360*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SAI2,		RCC_MP_APB2ENSETR,	17,	1),
361*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DFSDM,		RCC_MP_APB2ENSETR,	20,	1),
362*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ADFSDM,		RCC_MP_APB2ENSETR,	21,	1),
363*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_FDCAN,		RCC_MP_APB2ENSETR,	24,	1),
364*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LPTIM2,		RCC_MP_APB3ENSETR,	0,	1),
365*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LPTIM3,		RCC_MP_APB3ENSETR,	1,	1),
366*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LPTIM4,		RCC_MP_APB3ENSETR,	2,	1),
367*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LPTIM5,		RCC_MP_APB3ENSETR,	3,	1),
368*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_VREF,		RCC_MP_APB3ENSETR,	13,	1),
369*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DTS,		RCC_MP_APB3ENSETR,	16,	1),
370*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PMBCTRL,		RCC_MP_APB3ENSETR,	17,	1),
371*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_HDP,		RCC_MP_APB3ENSETR,	20,	1),
372*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SYSCFG,		RCC_MP_S_APB3ENSETR,	0,	1),
373*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DCMIPP,		RCC_MP_APB4ENSETR,	1,	1),
374*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DDRPERFM,		RCC_MP_APB4ENSETR,	8,	1),
375*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_IWDG2APB,		RCC_MP_APB4ENSETR,	15,	1),
376*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_USBPHY,		RCC_MP_APB4ENSETR,	16,	1),
377*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_STGENRO,		RCC_MP_APB4ENSETR,	20,	1),
378*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_LTDC,		RCC_MP_S_APB4ENSETR,	0,	1),
379*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_RTCAPB,		RCC_MP_APB5ENSETR,	8,	1),
380*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TZC,		RCC_MP_APB5ENSETR,	11,	1),
381*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETZPC,		RCC_MP_APB5ENSETR,	13,	1),
382*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_IWDG1APB,		RCC_MP_APB5ENSETR,	15,	1),
383*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_BSEC,		RCC_MP_APB5ENSETR,	16,	1),
384*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_STGENC,		RCC_MP_APB5ENSETR,	20,	1),
385*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_USART1,		RCC_MP_APB6ENSETR,	0,	1),
386*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_USART2,		RCC_MP_APB6ENSETR,	1,	1),
387*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SPI4,		RCC_MP_APB6ENSETR,	2,	1),
388*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SPI5,		RCC_MP_APB6ENSETR,	3,	1),
389*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_I2C3,		RCC_MP_APB6ENSETR,	4,	1),
390*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_I2C4,		RCC_MP_APB6ENSETR,	5,	1),
391*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_I2C5,		RCC_MP_APB6ENSETR,	6,	1),
392*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM12,		RCC_MP_APB6ENSETR,	7,	1),
393*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM13,		RCC_MP_APB6ENSETR,	8,	1),
394*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM14,		RCC_MP_APB6ENSETR,	9,	1),
395*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM15,		RCC_MP_APB6ENSETR,	10,	1),
396*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM16,		RCC_MP_APB6ENSETR,	11,	1),
397*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TIM17,		RCC_MP_APB6ENSETR,	12,	1),
398*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DMA1,		RCC_MP_AHB2ENSETR,	0,	1),
399*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DMA2,		RCC_MP_AHB2ENSETR,	1,	1),
400*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DMAMUX1,		RCC_MP_AHB2ENSETR,	2,	1),
401*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DMA3,		RCC_MP_AHB2ENSETR,	3,	1),
402*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_DMAMUX2,		RCC_MP_AHB2ENSETR,	4,	1),
403*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ADC1,		RCC_MP_AHB2ENSETR,	5,	1),
404*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ADC2,		RCC_MP_AHB2ENSETR,	6,	1),
405*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_USBO,		RCC_MP_AHB2ENSETR,	8,	1),
406*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_TSC,		RCC_MP_AHB4ENSETR,	15,	1),
407*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOA,		RCC_MP_S_AHB4ENSETR,	0,	1),
408*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOB,		RCC_MP_S_AHB4ENSETR,	1,	1),
409*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOC,		RCC_MP_S_AHB4ENSETR,	2,	1),
410*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOD,		RCC_MP_S_AHB4ENSETR,	3,	1),
411*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOE,		RCC_MP_S_AHB4ENSETR,	4,	1),
412*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOF,		RCC_MP_S_AHB4ENSETR,	5,	1),
413*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOG,		RCC_MP_S_AHB4ENSETR,	6,	1),
414*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOH,		RCC_MP_S_AHB4ENSETR,	7,	1),
415*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_GPIOI,		RCC_MP_S_AHB4ENSETR,	8,	1),
416*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_PKA,		RCC_MP_AHB5ENSETR,	2,	1),
417*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SAES,		RCC_MP_AHB5ENSETR,	3,	1),
418*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_CRYP1,		RCC_MP_AHB5ENSETR,	4,	1),
419*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_HASH1,		RCC_MP_AHB5ENSETR,	5,	1),
420*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_RNG1,		RCC_MP_AHB5ENSETR,	6,	1),
421*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_BKPSRAM,		RCC_MP_AHB5ENSETR,	8,	1),
422*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_AXIMC,		RCC_MP_AHB5ENSETR,	16,	1),
423*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_MCE,		RCC_MP_AHB6ENSETR,	1,	1),
424*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETH1CK,		RCC_MP_AHB6ENSETR,	7,	1),
425*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETH1TX,		RCC_MP_AHB6ENSETR,	8,	1),
426*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETH1RX,		RCC_MP_AHB6ENSETR,	9,	1),
427*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETH1MAC,		RCC_MP_AHB6ENSETR,	10,	1),
428*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_FMC,		RCC_MP_AHB6ENSETR,	12,	1),
429*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_QSPI,		RCC_MP_AHB6ENSETR,	14,	1),
430*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SDMMC1,		RCC_MP_AHB6ENSETR,	16,	1),
431*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_SDMMC2,		RCC_MP_AHB6ENSETR,	17,	1),
432*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_CRC1,		RCC_MP_AHB6ENSETR,	20,	1),
433*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_USBH,		RCC_MP_AHB6ENSETR,	24,	1),
434*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETH2CK,		RCC_MP_AHB6ENSETR,	27,	1),
435*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETH2TX,		RCC_MP_AHB6ENSETR,	28,	1),
436*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETH2RX,		RCC_MP_AHB6ENSETR,	29,	1),
437*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_ETH2MAC,		RCC_MP_AHB6ENSETR,	30,	1),
438*e5e793a6SGabriel Fernandez 	GATE_CFG(GATE_MDMA,		RCC_MP_S_AHB6ENSETR,	0,	1),
439*e5e793a6SGabriel Fernandez };
440*e5e793a6SGabriel Fernandez 
441*e5e793a6SGabriel Fernandez /*
442*e5e793a6SGabriel Fernandez  * MUX CONFIG
443*e5e793a6SGabriel Fernandez  */
444*e5e793a6SGabriel Fernandez #define MUXRDY_CFG(_id, _offset, _shift, _witdh, _rdy)\
445*e5e793a6SGabriel Fernandez 	[(_id)] = {\
446*e5e793a6SGabriel Fernandez 			.offset	= (_offset),\
447*e5e793a6SGabriel Fernandez 			.shift	= (_shift),\
448*e5e793a6SGabriel Fernandez 			.width	= (_witdh),\
449*e5e793a6SGabriel Fernandez 			.ready	= (_rdy),\
450*e5e793a6SGabriel Fernandez 	}
451*e5e793a6SGabriel Fernandez 
452*e5e793a6SGabriel Fernandez #define MUX_CFG(_id, _offset, _shift, _witdh)\
453*e5e793a6SGabriel Fernandez 	MUXRDY_CFG(_id, _offset, _shift, _witdh, MUX_NO_RDY)
454*e5e793a6SGabriel Fernandez 
455*e5e793a6SGabriel Fernandez static const struct mux_cfg parent_mp13[MUX_NB] = {
456*e5e793a6SGabriel Fernandez 	MUXRDY_CFG(MUX_MPU,	RCC_MPCKSELR,		0, 2, GATE_MPUSRCRDY),
457*e5e793a6SGabriel Fernandez 	MUXRDY_CFG(MUX_AXI,	RCC_ASSCKSELR,		0, 3, GATE_AXISSRCRDY),
458*e5e793a6SGabriel Fernandez 	MUXRDY_CFG(MUX_MLAHB,	RCC_MSSCKSELR,		0, 2, GATE_MCUSSRCRDY),
459*e5e793a6SGabriel Fernandez 	MUXRDY_CFG(MUX_PLL12,	RCC_RCK12SELR,		0, 2, GATE_PLL12SRCRDY),
460*e5e793a6SGabriel Fernandez 	MUXRDY_CFG(MUX_PLL3,	RCC_RCK3SELR,		0, 2, GATE_PLL3SRCRDY),
461*e5e793a6SGabriel Fernandez 	MUXRDY_CFG(MUX_PLL4,	RCC_RCK4SELR,		0, 2, GATE_PLL4SRCRDY),
462*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_ADC1,	RCC_ADC12CKSELR,	0, 2),
463*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_ADC2,	RCC_ADC12CKSELR,	2, 2),
464*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_CKPER,	RCC_CPERCKSELR,		0, 2),
465*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_DCMIPP,	RCC_DCMIPPCKSELR,	0, 2),
466*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_ETH1,	RCC_ETH12CKSELR,	0, 2),
467*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_ETH2,	RCC_ETH12CKSELR,	8, 2),
468*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_FDCAN,	RCC_FDCANCKSELR,	0, 2),
469*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_FMC,	RCC_FMCCKSELR,		0, 2),
470*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_I2C12,	RCC_I2C12CKSELR,	0, 3),
471*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_I2C3,	RCC_I2C345CKSELR,	0, 3),
472*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_I2C4,	RCC_I2C345CKSELR,	3, 3),
473*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_I2C5,	RCC_I2C345CKSELR,	6, 3),
474*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_LPTIM1,	RCC_LPTIM1CKSELR,	0, 3),
475*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_LPTIM2,	RCC_LPTIM23CKSELR,	0, 3),
476*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_LPTIM3,	RCC_LPTIM23CKSELR,	3, 3),
477*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_LPTIM45,	RCC_LPTIM45CKSELR,	0, 3),
478*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_MCO1,	RCC_MCO1CFGR,		0, 3),
479*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_MCO2,	RCC_MCO2CFGR,		0, 3),
480*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_QSPI,	RCC_QSPICKSELR,		0, 2),
481*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_RNG1,	RCC_RNG1CKSELR,		0, 2),
482*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_RTC,	RCC_BDCR,		16, 2),
483*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SAES,	RCC_SAESCKSELR,		0, 2),
484*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SAI1,	RCC_SAI1CKSELR,		0, 3),
485*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SAI2,	RCC_SAI2CKSELR,		0, 3),
486*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SDMMC1,	RCC_SDMMC12CKSELR,	0, 3),
487*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SDMMC2,	RCC_SDMMC12CKSELR,	3, 3),
488*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SPDIF,	RCC_SPDIFCKSELR,	0, 2),
489*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SPI1,	RCC_SPI2S1CKSELR,	0, 3),
490*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SPI23,	RCC_SPI2S23CKSELR,	0, 3),
491*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SPI4,	RCC_SPI45CKSELR,	0, 3),
492*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_SPI5,	RCC_SPI45CKSELR,	3, 3),
493*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_STGEN,	RCC_STGENCKSELR,	0, 2),
494*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_UART1,	RCC_UART12CKSELR,	0, 3),
495*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_UART2,	RCC_UART12CKSELR,	3, 3),
496*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_UART35,	RCC_UART35CKSELR,	0, 3),
497*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_UART4,	RCC_UART4CKSELR,	0, 3),
498*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_UART6,	RCC_UART6CKSELR,	0, 3),
499*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_UART78,	RCC_UART78CKSELR,	0, 3),
500*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_USBO,	RCC_USBCKSELR,		4, 1),
501*e5e793a6SGabriel Fernandez 	MUX_CFG(MUX_USBPHY,	RCC_USBCKSELR,		0, 2),
502*e5e793a6SGabriel Fernandez };
503*e5e793a6SGabriel Fernandez 
504*e5e793a6SGabriel Fernandez /*
505*e5e793a6SGabriel Fernandez  * DIV CONFIG
506*e5e793a6SGabriel Fernandez  */
507*e5e793a6SGabriel Fernandez static const struct div_table_cfg axi_div_table[] = {
508*e5e793a6SGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
509*e5e793a6SGabriel Fernandez 	{ 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
510*e5e793a6SGabriel Fernandez 	{ 0 },
511*e5e793a6SGabriel Fernandez };
512*e5e793a6SGabriel Fernandez 
513*e5e793a6SGabriel Fernandez static const struct div_table_cfg mlahb_div_table[] = {
514*e5e793a6SGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
515*e5e793a6SGabriel Fernandez 	{ 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
516*e5e793a6SGabriel Fernandez 	{ 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 },
517*e5e793a6SGabriel Fernandez 	{ 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
518*e5e793a6SGabriel Fernandez 	{ 0 },
519*e5e793a6SGabriel Fernandez };
520*e5e793a6SGabriel Fernandez 
521*e5e793a6SGabriel Fernandez static const struct div_table_cfg apb_div_table[] = {
522*e5e793a6SGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
523*e5e793a6SGabriel Fernandez 	{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
524*e5e793a6SGabriel Fernandez 	{ 0 },
525*e5e793a6SGabriel Fernandez };
526*e5e793a6SGabriel Fernandez 
527*e5e793a6SGabriel Fernandez #define DIVRDY_CFG(_id, _offset, _shift, _width, _flags, _table, _ready)\
528*e5e793a6SGabriel Fernandez 	[(_id)] = {\
529*e5e793a6SGabriel Fernandez 		.offset	= (_offset),\
530*e5e793a6SGabriel Fernandez 		.shift	= (_shift),\
531*e5e793a6SGabriel Fernandez 		.width	= (_width),\
532*e5e793a6SGabriel Fernandez 		.flags	= (_flags),\
533*e5e793a6SGabriel Fernandez 		.table	= (_table),\
534*e5e793a6SGabriel Fernandez 		.ready	= (_ready),\
535*e5e793a6SGabriel Fernandez 	}
536*e5e793a6SGabriel Fernandez 
537*e5e793a6SGabriel Fernandez #define DIV_CFG(_id, _offset, _shift, _width, _flags, _table)\
538*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(_id, _offset, _shift, _width, _flags, _table, DIV_NO_RDY)
539*e5e793a6SGabriel Fernandez 
540*e5e793a6SGabriel Fernandez static const struct div_cfg dividers_mp13[] = {
541*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 0, NULL,
542*e5e793a6SGabriel Fernandez 		   GATE_MPUDIVRDY),
543*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 0, axi_div_table,
544*e5e793a6SGabriel Fernandez 		   GATE_AXIDIVRDY),
545*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_MLAHB, RCC_MLAHBDIVR, 0, 4, 0, mlahb_div_table,
546*e5e793a6SGabriel Fernandez 		   GATE_MLAHBDIVRDY),
547*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table,
548*e5e793a6SGabriel Fernandez 		   GATE_APB1DIVRDY),
549*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table,
550*e5e793a6SGabriel Fernandez 		   GATE_APB2DIVRDY),
551*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table,
552*e5e793a6SGabriel Fernandez 		   GATE_APB3DIVRDY),
553*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table,
554*e5e793a6SGabriel Fernandez 		   GATE_APB4DIVRDY),
555*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table,
556*e5e793a6SGabriel Fernandez 		   GATE_APB5DIVRDY),
557*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_APB6, RCC_APB6DIVR, 0, 3, 0, apb_div_table,
558*e5e793a6SGabriel Fernandez 		   GATE_APB6DIVRDY),
559*e5e793a6SGabriel Fernandez 	DIVRDY_CFG(DIV_HSI, RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL,
560*e5e793a6SGabriel Fernandez 		   GATE_HSIDIVRDY),
561*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL),
562*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL),
563*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL),
564*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL2DIVR, RCC_PLL2CFGR2, 16, 7, 0, NULL),
565*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL3DIVP, RCC_PLL3CFGR2, 0, 7, 0, NULL),
566*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL3DIVQ, RCC_PLL3CFGR2, 8, 7, 0, NULL),
567*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL3DIVR, RCC_PLL3CFGR2, 16, 7, 0, NULL),
568*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL4DIVP, RCC_PLL4CFGR2, 0, 7, 0, NULL),
569*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL4DIVQ, RCC_PLL4CFGR2, 8, 7, 0, NULL),
570*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_PLL4DIVR, RCC_PLL4CFGR2, 16, 7, 0, NULL),
571*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL),
572*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL),
573*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL),
574*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, CLK_DIVIDER_POWER_OF_TWO, NULL),
575*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL),
576*e5e793a6SGabriel Fernandez 	DIV_CFG(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL),
577*e5e793a6SGabriel Fernandez };
578*e5e793a6SGabriel Fernandez 
579*e5e793a6SGabriel Fernandez enum stm32_osc {
580*e5e793a6SGabriel Fernandez 	OSC_HSI,
581*e5e793a6SGabriel Fernandez 	OSC_HSE,
582*e5e793a6SGabriel Fernandez 	OSC_CSI,
583*e5e793a6SGabriel Fernandez 	OSC_LSI,
584*e5e793a6SGabriel Fernandez 	OSC_LSE,
585*e5e793a6SGabriel Fernandez 	NB_OSCILLATOR
586*e5e793a6SGabriel Fernandez };
587*e5e793a6SGabriel Fernandez 
588*e5e793a6SGabriel Fernandez struct stm32_osc_cfg {
589*e5e793a6SGabriel Fernandez 	int osc_id;
590*e5e793a6SGabriel Fernandez };
591*e5e793a6SGabriel Fernandez 
592*e5e793a6SGabriel Fernandez struct clk_stm32_bypass {
593*e5e793a6SGabriel Fernandez 	uint16_t offset;
594*e5e793a6SGabriel Fernandez 	uint8_t bit_byp;
595*e5e793a6SGabriel Fernandez 	uint8_t bit_digbyp;
596*e5e793a6SGabriel Fernandez };
597*e5e793a6SGabriel Fernandez 
598*e5e793a6SGabriel Fernandez struct clk_stm32_css {
599*e5e793a6SGabriel Fernandez 	uint16_t offset;
600*e5e793a6SGabriel Fernandez 	uint8_t bit_css;
601*e5e793a6SGabriel Fernandez };
602*e5e793a6SGabriel Fernandez 
603*e5e793a6SGabriel Fernandez struct clk_stm32_drive {
604*e5e793a6SGabriel Fernandez 	uint16_t offset;
605*e5e793a6SGabriel Fernandez 	uint8_t drv_shift;
606*e5e793a6SGabriel Fernandez 	uint8_t drv_width;
607*e5e793a6SGabriel Fernandez 	uint8_t drv_default;
608*e5e793a6SGabriel Fernandez };
609*e5e793a6SGabriel Fernandez 
610*e5e793a6SGabriel Fernandez struct clk_oscillator_data {
611*e5e793a6SGabriel Fernandez 	const char *name;
612*e5e793a6SGabriel Fernandez 	unsigned long frequency;
613*e5e793a6SGabriel Fernandez 	uint16_t gate_id;
614*e5e793a6SGabriel Fernandez 	struct clk_stm32_bypass *bypass;
615*e5e793a6SGabriel Fernandez 	struct clk_stm32_css *css;
616*e5e793a6SGabriel Fernandez 	struct clk_stm32_drive *drive;
617*e5e793a6SGabriel Fernandez };
618*e5e793a6SGabriel Fernandez 
619*e5e793a6SGabriel Fernandez #define BYPASS(_offset, _bit_byp, _bit_digbyp) (&(struct clk_stm32_bypass){\
620*e5e793a6SGabriel Fernandez 	.offset		= (_offset),\
621*e5e793a6SGabriel Fernandez 	.bit_byp	= (_bit_byp),\
622*e5e793a6SGabriel Fernandez 	.bit_digbyp	= (_bit_digbyp),\
623*e5e793a6SGabriel Fernandez })
624*e5e793a6SGabriel Fernandez 
625*e5e793a6SGabriel Fernandez #define CSS(_offset, _bit_css) (&(struct clk_stm32_css){\
626*e5e793a6SGabriel Fernandez 	.offset		= (_offset),\
627*e5e793a6SGabriel Fernandez 	.bit_css	= (_bit_css),\
628*e5e793a6SGabriel Fernandez })
629*e5e793a6SGabriel Fernandez 
630*e5e793a6SGabriel Fernandez #define DRIVE(_offset, _shift, _width, _default) (&(struct clk_stm32_drive){\
631*e5e793a6SGabriel Fernandez 	.offset		= (_offset),\
632*e5e793a6SGabriel Fernandez 	.drv_shift	= (_shift),\
633*e5e793a6SGabriel Fernandez 	.drv_width	= (_width),\
634*e5e793a6SGabriel Fernandez 	.drv_default	= (_default),\
635*e5e793a6SGabriel Fernandez })
636*e5e793a6SGabriel Fernandez 
637*e5e793a6SGabriel Fernandez #define OSCILLATOR(idx_osc, _name, _gate_id, _bypass, _css, _drive) \
638*e5e793a6SGabriel Fernandez 	[(idx_osc)] = (struct clk_oscillator_data){\
639*e5e793a6SGabriel Fernandez 		.name		= (_name),\
640*e5e793a6SGabriel Fernandez 		.gate_id	= (_gate_id),\
641*e5e793a6SGabriel Fernandez 		.bypass		= (_bypass),\
642*e5e793a6SGabriel Fernandez 		.css		= (_css),\
643*e5e793a6SGabriel Fernandez 		.drive		= (_drive),\
644*e5e793a6SGabriel Fernandez 	}
645*e5e793a6SGabriel Fernandez 
646*e5e793a6SGabriel Fernandez static struct clk_oscillator_data stm32mp13_osc_data[NB_OSCILLATOR] = {
647*e5e793a6SGabriel Fernandez 	OSCILLATOR(OSC_HSI, "clk-hsi", GATE_HSI,
648*e5e793a6SGabriel Fernandez 		   NULL, NULL, NULL),
649*e5e793a6SGabriel Fernandez 
650*e5e793a6SGabriel Fernandez 	OSCILLATOR(OSC_LSI, "clk-lsi", GATE_LSI,
651*e5e793a6SGabriel Fernandez 		   NULL, NULL, NULL),
652*e5e793a6SGabriel Fernandez 
653*e5e793a6SGabriel Fernandez 	OSCILLATOR(OSC_CSI, "clk-csi", GATE_CSI,
654*e5e793a6SGabriel Fernandez 		   NULL, NULL, NULL),
655*e5e793a6SGabriel Fernandez 
656*e5e793a6SGabriel Fernandez 	OSCILLATOR(OSC_LSE, "clk-lse", GATE_LSE,
657*e5e793a6SGabriel Fernandez 		   BYPASS(RCC_BDCR, 1, 3),
658*e5e793a6SGabriel Fernandez 		   CSS(RCC_BDCR, 8),
659*e5e793a6SGabriel Fernandez 		   DRIVE(RCC_BDCR, 4, 2, 2)),
660*e5e793a6SGabriel Fernandez 
661*e5e793a6SGabriel Fernandez 	OSCILLATOR(OSC_HSE, "clk-hse", GATE_HSE,
662*e5e793a6SGabriel Fernandez 		   BYPASS(RCC_OCENSETR, 10, 7),
663*e5e793a6SGabriel Fernandez 		   CSS(RCC_OCENSETR, 11),
664*e5e793a6SGabriel Fernandez 		   NULL),
665*e5e793a6SGabriel Fernandez };
666*e5e793a6SGabriel Fernandez 
667*e5e793a6SGabriel Fernandez static struct clk_oscillator_data *clk_oscillator_get_data(int osc_id)
668*e5e793a6SGabriel Fernandez {
669*e5e793a6SGabriel Fernandez 	assert(osc_id >= 0 && osc_id < (int)ARRAY_SIZE(stm32mp13_osc_data));
670*e5e793a6SGabriel Fernandez 
671*e5e793a6SGabriel Fernandez 	return &stm32mp13_osc_data[osc_id];
672*e5e793a6SGabriel Fernandez }
673*e5e793a6SGabriel Fernandez 
674*e5e793a6SGabriel Fernandez static unsigned long clk_stm32_get_rate_oscillateur(int osc_id)
675*e5e793a6SGabriel Fernandez {
676*e5e793a6SGabriel Fernandez 	struct clk_stm32_priv *priv = clk_stm32_get_priv();
677*e5e793a6SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
678*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[osc_id];
679*e5e793a6SGabriel Fernandez 
680*e5e793a6SGabriel Fernandez 	return osci->freq;
681*e5e793a6SGabriel Fernandez }
682*e5e793a6SGabriel Fernandez 
683*e5e793a6SGabriel Fernandez static void clk_oscillator_set_bypass(struct clk_stm32_priv *priv,
684*e5e793a6SGabriel Fernandez 				      struct clk_oscillator_data *osc_data,
685*e5e793a6SGabriel Fernandez 				      bool digbyp, bool bypass)
686*e5e793a6SGabriel Fernandez {
687*e5e793a6SGabriel Fernandez 	struct clk_stm32_bypass *bypass_data = osc_data->bypass;
688*e5e793a6SGabriel Fernandez 	uintptr_t address = 0;
689*e5e793a6SGabriel Fernandez 
690*e5e793a6SGabriel Fernandez 	if (!bypass_data)
691*e5e793a6SGabriel Fernandez 		return;
692*e5e793a6SGabriel Fernandez 
693*e5e793a6SGabriel Fernandez 	address = priv->base + bypass_data->offset;
694*e5e793a6SGabriel Fernandez 
695*e5e793a6SGabriel Fernandez 	if (digbyp)
696*e5e793a6SGabriel Fernandez 		io_setbits32(address, BIT(bypass_data->bit_digbyp));
697*e5e793a6SGabriel Fernandez 
698*e5e793a6SGabriel Fernandez 	if (bypass || digbyp)
699*e5e793a6SGabriel Fernandez 		io_setbits32(address, BIT(bypass_data->bit_byp));
700*e5e793a6SGabriel Fernandez }
701*e5e793a6SGabriel Fernandez 
702*e5e793a6SGabriel Fernandez static void clk_oscillator_set_css(struct clk_stm32_priv *priv,
703*e5e793a6SGabriel Fernandez 				   struct clk_oscillator_data *osc_data,
704*e5e793a6SGabriel Fernandez 				   bool css)
705*e5e793a6SGabriel Fernandez {
706*e5e793a6SGabriel Fernandez 	struct clk_stm32_css *css_data = osc_data->css;
707*e5e793a6SGabriel Fernandez 	uintptr_t address = 0;
708*e5e793a6SGabriel Fernandez 
709*e5e793a6SGabriel Fernandez 	if (!css_data)
710*e5e793a6SGabriel Fernandez 		return;
711*e5e793a6SGabriel Fernandez 
712*e5e793a6SGabriel Fernandez 	address = priv->base + css_data->offset;
713*e5e793a6SGabriel Fernandez 
714*e5e793a6SGabriel Fernandez 	if (css)
715*e5e793a6SGabriel Fernandez 		io_setbits32(address, BIT(css_data->bit_css));
716*e5e793a6SGabriel Fernandez }
717*e5e793a6SGabriel Fernandez 
718*e5e793a6SGabriel Fernandez static void clk_oscillator_set_drive(struct clk_stm32_priv *priv,
719*e5e793a6SGabriel Fernandez 				     struct clk_oscillator_data *osc_data,
720*e5e793a6SGabriel Fernandez 				     uint8_t lsedrv)
721*e5e793a6SGabriel Fernandez {
722*e5e793a6SGabriel Fernandez 	struct clk_stm32_drive *drive_data = osc_data->drive;
723*e5e793a6SGabriel Fernandez 	uintptr_t address = 0;
724*e5e793a6SGabriel Fernandez 	uint32_t mask = 0;
725*e5e793a6SGabriel Fernandez 	uint32_t value = 0;
726*e5e793a6SGabriel Fernandez 
727*e5e793a6SGabriel Fernandez 	if (!drive_data)
728*e5e793a6SGabriel Fernandez 		return;
729*e5e793a6SGabriel Fernandez 
730*e5e793a6SGabriel Fernandez 	address = priv->base + drive_data->offset;
731*e5e793a6SGabriel Fernandez 
732*e5e793a6SGabriel Fernandez 	mask = (BIT(drive_data->drv_width) - 1U) << drive_data->drv_shift;
733*e5e793a6SGabriel Fernandez 
734*e5e793a6SGabriel Fernandez 	/*
735*e5e793a6SGabriel Fernandez 	 * Warning: not recommended to switch directly from "high drive"
736*e5e793a6SGabriel Fernandez 	 * to "medium low drive", and vice-versa.
737*e5e793a6SGabriel Fernandez 	 */
738*e5e793a6SGabriel Fernandez 	value = (io_read32(address) & mask) >> drive_data->drv_shift;
739*e5e793a6SGabriel Fernandez 
740*e5e793a6SGabriel Fernandez 	while (value != lsedrv) {
741*e5e793a6SGabriel Fernandez 		if (value > lsedrv)
742*e5e793a6SGabriel Fernandez 			value--;
743*e5e793a6SGabriel Fernandez 		else
744*e5e793a6SGabriel Fernandez 			value++;
745*e5e793a6SGabriel Fernandez 
746*e5e793a6SGabriel Fernandez 		io_clrsetbits32(address, mask, value << drive_data->drv_shift);
747*e5e793a6SGabriel Fernandez 	}
748*e5e793a6SGabriel Fernandez }
749*e5e793a6SGabriel Fernandez 
750*e5e793a6SGabriel Fernandez static void stm32_enable_oscillator_hse(struct clk_stm32_priv *priv,
751*e5e793a6SGabriel Fernandez 					struct stm32_clk_platdata *pdata)
752*e5e793a6SGabriel Fernandez {
753*e5e793a6SGabriel Fernandez 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_HSE);
754*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE];
755*e5e793a6SGabriel Fernandez 
756*e5e793a6SGabriel Fernandez 	if (osci->freq == 0U)
757*e5e793a6SGabriel Fernandez 		return;
758*e5e793a6SGabriel Fernandez 
759*e5e793a6SGabriel Fernandez 	clk_oscillator_set_bypass(priv, osc_data,  osci->digbyp, osci->bypass);
760*e5e793a6SGabriel Fernandez 
761*e5e793a6SGabriel Fernandez 	/* Enable clock and wait ready bit */
762*e5e793a6SGabriel Fernandez 	if (stm32_gate_rdy_enable(osc_data->gate_id)) {
763*e5e793a6SGabriel Fernandez 		EMSG("timeout to enable hse clock");
764*e5e793a6SGabriel Fernandez 		panic();
765*e5e793a6SGabriel Fernandez 	}
766*e5e793a6SGabriel Fernandez 
767*e5e793a6SGabriel Fernandez 	clk_oscillator_set_css(priv, osc_data, osci->css);
768*e5e793a6SGabriel Fernandez }
769*e5e793a6SGabriel Fernandez 
770*e5e793a6SGabriel Fernandez static void stm32_enable_oscillator_lse(struct clk_stm32_priv *priv,
771*e5e793a6SGabriel Fernandez 					struct stm32_clk_platdata *pdata)
772*e5e793a6SGabriel Fernandez {
773*e5e793a6SGabriel Fernandez 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_LSE);
774*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
775*e5e793a6SGabriel Fernandez 
776*e5e793a6SGabriel Fernandez 	if (osci->freq == 0U)
777*e5e793a6SGabriel Fernandez 		return;
778*e5e793a6SGabriel Fernandez 
779*e5e793a6SGabriel Fernandez 	clk_oscillator_set_bypass(priv, osc_data, osci->digbyp, osci->bypass);
780*e5e793a6SGabriel Fernandez 
781*e5e793a6SGabriel Fernandez 	clk_oscillator_set_drive(priv, osc_data,  osci->drive);
782*e5e793a6SGabriel Fernandez 
783*e5e793a6SGabriel Fernandez 	/* Enable lse clock, but don't wait ready bit */
784*e5e793a6SGabriel Fernandez 	stm32_gate_enable(osc_data->gate_id);
785*e5e793a6SGabriel Fernandez }
786*e5e793a6SGabriel Fernandez 
787*e5e793a6SGabriel Fernandez static void
788*e5e793a6SGabriel Fernandez stm32_enable_oscillator_lsi(struct clk_stm32_priv *priv __maybe_unused,
789*e5e793a6SGabriel Fernandez 			    struct stm32_clk_platdata *pdata)
790*e5e793a6SGabriel Fernandez {
791*e5e793a6SGabriel Fernandez 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_LSI);
792*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSI];
793*e5e793a6SGabriel Fernandez 
794*e5e793a6SGabriel Fernandez 	if (osci->freq == 0U)
795*e5e793a6SGabriel Fernandez 		return;
796*e5e793a6SGabriel Fernandez 
797*e5e793a6SGabriel Fernandez 	/* Enable clock and wait ready bit */
798*e5e793a6SGabriel Fernandez 	if (stm32_gate_rdy_enable(osc_data->gate_id)) {
799*e5e793a6SGabriel Fernandez 		EMSG("timeout to enable lsi clock");
800*e5e793a6SGabriel Fernandez 		panic();
801*e5e793a6SGabriel Fernandez 	}
802*e5e793a6SGabriel Fernandez }
803*e5e793a6SGabriel Fernandez 
804*e5e793a6SGabriel Fernandez static void
805*e5e793a6SGabriel Fernandez stm32_enable_oscillator_csi(struct clk_stm32_priv *priv __maybe_unused,
806*e5e793a6SGabriel Fernandez 			    struct stm32_clk_platdata *pdata)
807*e5e793a6SGabriel Fernandez {
808*e5e793a6SGabriel Fernandez 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_CSI);
809*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_CSI];
810*e5e793a6SGabriel Fernandez 
811*e5e793a6SGabriel Fernandez 	if (osci->freq == 0U)
812*e5e793a6SGabriel Fernandez 		return;
813*e5e793a6SGabriel Fernandez 
814*e5e793a6SGabriel Fernandez 	/* Enable clock and wait ready bit */
815*e5e793a6SGabriel Fernandez 	if (stm32_gate_rdy_enable(osc_data->gate_id)) {
816*e5e793a6SGabriel Fernandez 		EMSG("timeout to enable csi clock");
817*e5e793a6SGabriel Fernandez 		panic();
818*e5e793a6SGabriel Fernandez 	}
819*e5e793a6SGabriel Fernandez }
820*e5e793a6SGabriel Fernandez 
821*e5e793a6SGabriel Fernandez static int stm32_clk_oscillators_lse_set_css(struct clk_stm32_priv *priv,
822*e5e793a6SGabriel Fernandez 					     struct stm32_clk_platdata *pdata)
823*e5e793a6SGabriel Fernandez 
824*e5e793a6SGabriel Fernandez {
825*e5e793a6SGabriel Fernandez 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_LSE);
826*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
827*e5e793a6SGabriel Fernandez 
828*e5e793a6SGabriel Fernandez 	clk_oscillator_set_css(priv, osc_data, osci->css);
829*e5e793a6SGabriel Fernandez 
830*e5e793a6SGabriel Fernandez 	return 0;
831*e5e793a6SGabriel Fernandez }
832*e5e793a6SGabriel Fernandez 
833*e5e793a6SGabriel Fernandez static int
834*e5e793a6SGabriel Fernandez stm32_clk_oscillators_wait_lse_ready(struct clk_stm32_priv *priv __maybe_unused,
835*e5e793a6SGabriel Fernandez 				     struct stm32_clk_platdata *pdata)
836*e5e793a6SGabriel Fernandez {
837*e5e793a6SGabriel Fernandez 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_LSE);
838*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
839*e5e793a6SGabriel Fernandez 
840*e5e793a6SGabriel Fernandez 	if (osci->freq == 0U)
841*e5e793a6SGabriel Fernandez 		return 0;
842*e5e793a6SGabriel Fernandez 
843*e5e793a6SGabriel Fernandez 	if (stm32_gate_wait_ready(osc_data->gate_id, true))
844*e5e793a6SGabriel Fernandez 		return -1;
845*e5e793a6SGabriel Fernandez 
846*e5e793a6SGabriel Fernandez 	return 0;
847*e5e793a6SGabriel Fernandez }
848*e5e793a6SGabriel Fernandez 
849*e5e793a6SGabriel Fernandez static void stm32_clk_oscillators_enable(struct clk_stm32_priv *priv,
850*e5e793a6SGabriel Fernandez 					 struct stm32_clk_platdata *pdata)
851*e5e793a6SGabriel Fernandez {
852*e5e793a6SGabriel Fernandez 	stm32_enable_oscillator_hse(priv, pdata);
853*e5e793a6SGabriel Fernandez 	stm32_enable_oscillator_lse(priv, pdata);
854*e5e793a6SGabriel Fernandez 	stm32_enable_oscillator_lsi(priv, pdata);
855*e5e793a6SGabriel Fernandez 	stm32_enable_oscillator_csi(priv, pdata);
856*e5e793a6SGabriel Fernandez }
857*e5e793a6SGabriel Fernandez 
858*e5e793a6SGabriel Fernandez enum stm32_pll_id {
859*e5e793a6SGabriel Fernandez 	PLL1_ID,
860*e5e793a6SGabriel Fernandez 	PLL2_ID,
861*e5e793a6SGabriel Fernandez 	PLL3_ID,
862*e5e793a6SGabriel Fernandez 	PLL4_ID,
863*e5e793a6SGabriel Fernandez 	PLL_NB
864*e5e793a6SGabriel Fernandez };
865*e5e793a6SGabriel Fernandez 
866*e5e793a6SGabriel Fernandez enum stm32mp1_plltype {
867*e5e793a6SGabriel Fernandez 	PLL_800,
868*e5e793a6SGabriel Fernandez 	PLL_1600,
869*e5e793a6SGabriel Fernandez 	PLL_2000,
870*e5e793a6SGabriel Fernandez 	PLL_TYPE_NB
871*e5e793a6SGabriel Fernandez };
872*e5e793a6SGabriel Fernandez 
873*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXCR		0
874*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXCFGR1		4
875*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXCFGR2		8
876*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXFRACR		12
877*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXCSGR		16
878*e5e793a6SGabriel Fernandez 
879*e5e793a6SGabriel Fernandez struct stm32_clk_pll {
880*e5e793a6SGabriel Fernandez 	enum stm32mp1_plltype plltype;
881*e5e793a6SGabriel Fernandez 	uint16_t gate_id;
882*e5e793a6SGabriel Fernandez 	uint16_t mux_id;
883*e5e793a6SGabriel Fernandez 	uint16_t reg_pllxcr;
884*e5e793a6SGabriel Fernandez };
885*e5e793a6SGabriel Fernandez 
886*e5e793a6SGabriel Fernandez struct stm32mp1_pll {
887*e5e793a6SGabriel Fernandez 	uint8_t refclk_min;
888*e5e793a6SGabriel Fernandez 	uint8_t refclk_max;
889*e5e793a6SGabriel Fernandez };
890*e5e793a6SGabriel Fernandez 
891*e5e793a6SGabriel Fernandez /* Define characteristic of PLL according type */
892*e5e793a6SGabriel Fernandez static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
893*e5e793a6SGabriel Fernandez 	[PLL_800] = {
894*e5e793a6SGabriel Fernandez 		.refclk_min = 4,
895*e5e793a6SGabriel Fernandez 		.refclk_max = 16,
896*e5e793a6SGabriel Fernandez 	},
897*e5e793a6SGabriel Fernandez 	[PLL_1600] = {
898*e5e793a6SGabriel Fernandez 		.refclk_min = 8,
899*e5e793a6SGabriel Fernandez 		.refclk_max = 16,
900*e5e793a6SGabriel Fernandez 	},
901*e5e793a6SGabriel Fernandez 	[PLL_2000] = {
902*e5e793a6SGabriel Fernandez 		.refclk_min = 8,
903*e5e793a6SGabriel Fernandez 		.refclk_max = 16,
904*e5e793a6SGabriel Fernandez 	}
905*e5e793a6SGabriel Fernandez };
906*e5e793a6SGabriel Fernandez 
907*e5e793a6SGabriel Fernandez #define CLK_PLL_CFG(_idx, _type, _gate_id, _mux_id, _reg)\
908*e5e793a6SGabriel Fernandez 	[(_idx)] = {\
909*e5e793a6SGabriel Fernandez 		.gate_id = (_gate_id),\
910*e5e793a6SGabriel Fernandez 		.mux_id = (_mux_id),\
911*e5e793a6SGabriel Fernandez 		.plltype = (_type),\
912*e5e793a6SGabriel Fernandez 		.reg_pllxcr = (_reg),\
913*e5e793a6SGabriel Fernandez 	}
914*e5e793a6SGabriel Fernandez 
915*e5e793a6SGabriel Fernandez static const struct stm32_clk_pll stm32_mp13_clk_pll[PLL_NB] = {
916*e5e793a6SGabriel Fernandez 	CLK_PLL_CFG(PLL1_ID, PLL_2000, GATE_PLL1, MUX_PLL12, RCC_PLL1CR),
917*e5e793a6SGabriel Fernandez 	CLK_PLL_CFG(PLL2_ID, PLL_1600, GATE_PLL2, MUX_PLL12, RCC_PLL2CR),
918*e5e793a6SGabriel Fernandez 	CLK_PLL_CFG(PLL3_ID, PLL_800, GATE_PLL3, MUX_PLL3, RCC_PLL3CR),
919*e5e793a6SGabriel Fernandez 	CLK_PLL_CFG(PLL4_ID, PLL_800, GATE_PLL4, MUX_PLL4, RCC_PLL4CR),
920*e5e793a6SGabriel Fernandez };
921*e5e793a6SGabriel Fernandez 
922*e5e793a6SGabriel Fernandez static const struct stm32_clk_pll *clk_stm32_pll_data(unsigned int idx)
923*e5e793a6SGabriel Fernandez {
924*e5e793a6SGabriel Fernandez 	return &stm32_mp13_clk_pll[idx];
925*e5e793a6SGabriel Fernandez }
926*e5e793a6SGabriel Fernandez 
927*e5e793a6SGabriel Fernandez /* Clock TREE configuration */
928*e5e793a6SGabriel Fernandez 
929*e5e793a6SGabriel Fernandez static unsigned int stm32_clk_configure_clk_get_binding_id(uint32_t data)
930*e5e793a6SGabriel Fernandez {
931*e5e793a6SGabriel Fernandez 	return (data & CLK_ID_MASK) >> CLK_ID_SHIFT;
932*e5e793a6SGabriel Fernandez }
933*e5e793a6SGabriel Fernandez 
934*e5e793a6SGabriel Fernandez static int stm32_clk_configure_clk(struct clk_stm32_priv *priv __maybe_unused,
935*e5e793a6SGabriel Fernandez 				   uint32_t data)
936*e5e793a6SGabriel Fernandez {
937*e5e793a6SGabriel Fernandez 	int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
938*e5e793a6SGabriel Fernandez 	int enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT;
939*e5e793a6SGabriel Fernandez 	int clk_id = 0;
940*e5e793a6SGabriel Fernandez 	int ret = 0;
941*e5e793a6SGabriel Fernandez 	int mux = -1;
942*e5e793a6SGabriel Fernandez 	int gate = -1;
943*e5e793a6SGabriel Fernandez 
944*e5e793a6SGabriel Fernandez 	clk_id = stm32_clk_configure_clk_get_binding_id(data);
945*e5e793a6SGabriel Fernandez 
946*e5e793a6SGabriel Fernandez 	switch (clk_id)	{
947*e5e793a6SGabriel Fernandez 	case CK_MCO1:
948*e5e793a6SGabriel Fernandez 		mux = MUX_MCO1;
949*e5e793a6SGabriel Fernandez 		gate = GATE_MCO1;
950*e5e793a6SGabriel Fernandez 		break;
951*e5e793a6SGabriel Fernandez 
952*e5e793a6SGabriel Fernandez 	case CK_MCO2:
953*e5e793a6SGabriel Fernandez 		mux = MUX_MCO2;
954*e5e793a6SGabriel Fernandez 		gate = GATE_MCO2;
955*e5e793a6SGabriel Fernandez 		break;
956*e5e793a6SGabriel Fernandez 	default:
957*e5e793a6SGabriel Fernandez 		ret = -1;
958*e5e793a6SGabriel Fernandez 		break;
959*e5e793a6SGabriel Fernandez 	}
960*e5e793a6SGabriel Fernandez 
961*e5e793a6SGabriel Fernandez 	if (ret != 0)
962*e5e793a6SGabriel Fernandez 		return ret;
963*e5e793a6SGabriel Fernandez 
964*e5e793a6SGabriel Fernandez 	if (stm32_mux_set_parent(mux, sel))
965*e5e793a6SGabriel Fernandez 		return -1;
966*e5e793a6SGabriel Fernandez 
967*e5e793a6SGabriel Fernandez 	if (enable)
968*e5e793a6SGabriel Fernandez 		stm32_gate_enable(gate);
969*e5e793a6SGabriel Fernandez 	else
970*e5e793a6SGabriel Fernandez 		stm32_gate_disable(gate);
971*e5e793a6SGabriel Fernandez 
972*e5e793a6SGabriel Fernandez 	return 0;
973*e5e793a6SGabriel Fernandez }
974*e5e793a6SGabriel Fernandez 
975*e5e793a6SGabriel Fernandez static int stm32_clk_configure_mux(__unused struct clk_stm32_priv *priv,
976*e5e793a6SGabriel Fernandez 				   uint32_t data)
977*e5e793a6SGabriel Fernandez {
978*e5e793a6SGabriel Fernandez 	int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
979*e5e793a6SGabriel Fernandez 	int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
980*e5e793a6SGabriel Fernandez 
981*e5e793a6SGabriel Fernandez 	if (mux == MUX_RTC) {
982*e5e793a6SGabriel Fernandez 		/* Mux RTC clock only is selector is valid and RTC not yet
983*e5e793a6SGabriel Fernandez 		 * enabled
984*e5e793a6SGabriel Fernandez 		 */
985*e5e793a6SGabriel Fernandez 		if (sel == 0)
986*e5e793a6SGabriel Fernandez 			return 0;
987*e5e793a6SGabriel Fernandez 
988*e5e793a6SGabriel Fernandez 		if (stm32_gate_is_enabled(GATE_RTCCK))
989*e5e793a6SGabriel Fernandez 			return 0;
990*e5e793a6SGabriel Fernandez 	}
991*e5e793a6SGabriel Fernandez 
992*e5e793a6SGabriel Fernandez 	if (stm32_mux_set_parent(mux, sel))
993*e5e793a6SGabriel Fernandez 		return -1;
994*e5e793a6SGabriel Fernandez 
995*e5e793a6SGabriel Fernandez 	return 0;
996*e5e793a6SGabriel Fernandez }
997*e5e793a6SGabriel Fernandez 
998*e5e793a6SGabriel Fernandez static TEE_Result
999*e5e793a6SGabriel Fernandez stm32_clk_configure_div(struct clk_stm32_priv *priv __maybe_unused,
1000*e5e793a6SGabriel Fernandez 			uint32_t data)
1001*e5e793a6SGabriel Fernandez {
1002*e5e793a6SGabriel Fernandez 	int div_id = (data & DIV_ID_MASK) >> DIV_ID_SHIFT;
1003*e5e793a6SGabriel Fernandez 	int div_n = (data & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
1004*e5e793a6SGabriel Fernandez 
1005*e5e793a6SGabriel Fernandez 	return stm32_div_set_value(div_id, div_n);
1006*e5e793a6SGabriel Fernandez }
1007*e5e793a6SGabriel Fernandez 
1008*e5e793a6SGabriel Fernandez static int stm32_clk_dividers_configure(struct clk_stm32_priv *priv)
1009*e5e793a6SGabriel Fernandez {
1010*e5e793a6SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1011*e5e793a6SGabriel Fernandez 	unsigned int i = 0;
1012*e5e793a6SGabriel Fernandez 
1013*e5e793a6SGabriel Fernandez 	for (i = 0; i < pdata->nclkdiv; i++) {
1014*e5e793a6SGabriel Fernandez 		if (stm32_clk_configure_div(priv, pdata->clkdiv[i]))
1015*e5e793a6SGabriel Fernandez 			return -1;
1016*e5e793a6SGabriel Fernandez 	}
1017*e5e793a6SGabriel Fernandez 
1018*e5e793a6SGabriel Fernandez 	return 0;
1019*e5e793a6SGabriel Fernandez }
1020*e5e793a6SGabriel Fernandez 
1021*e5e793a6SGabriel Fernandez static int stm32_clk_source_configure(struct clk_stm32_priv *priv)
1022*e5e793a6SGabriel Fernandez {
1023*e5e793a6SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1024*e5e793a6SGabriel Fernandez 	bool ckper_disabled = false;
1025*e5e793a6SGabriel Fernandez 	int ret = 0;
1026*e5e793a6SGabriel Fernandez 	size_t i = 0;
1027*e5e793a6SGabriel Fernandez 
1028*e5e793a6SGabriel Fernandez 	for (i = 0; i < pdata->nclksrc; i++) {
1029*e5e793a6SGabriel Fernandez 		uint32_t val = pdata->clksrc[i];
1030*e5e793a6SGabriel Fernandez 		uint32_t cmd = 0;
1031*e5e793a6SGabriel Fernandez 		uint32_t cmd_data = 0;
1032*e5e793a6SGabriel Fernandez 
1033*e5e793a6SGabriel Fernandez 		if (val == (uint32_t)CLK_CKPER_DISABLED) {
1034*e5e793a6SGabriel Fernandez 			ckper_disabled = true;
1035*e5e793a6SGabriel Fernandez 			continue;
1036*e5e793a6SGabriel Fernandez 		}
1037*e5e793a6SGabriel Fernandez 
1038*e5e793a6SGabriel Fernandez 		cmd = (val & CMD_MASK) >> CMD_SHIFT;
1039*e5e793a6SGabriel Fernandez 		cmd_data = val & ~CMD_MASK;
1040*e5e793a6SGabriel Fernandez 
1041*e5e793a6SGabriel Fernandez 		switch (cmd) {
1042*e5e793a6SGabriel Fernandez 		case CMD_MUX:
1043*e5e793a6SGabriel Fernandez 			ret = stm32_clk_configure_mux(priv, cmd_data);
1044*e5e793a6SGabriel Fernandez 			break;
1045*e5e793a6SGabriel Fernandez 
1046*e5e793a6SGabriel Fernandez 		case CMD_CLK:
1047*e5e793a6SGabriel Fernandez 			ret = stm32_clk_configure_clk(priv, cmd_data);
1048*e5e793a6SGabriel Fernandez 			break;
1049*e5e793a6SGabriel Fernandez 		default:
1050*e5e793a6SGabriel Fernandez 			ret = -1;
1051*e5e793a6SGabriel Fernandez 			break;
1052*e5e793a6SGabriel Fernandez 		}
1053*e5e793a6SGabriel Fernandez 
1054*e5e793a6SGabriel Fernandez 		if (ret != 0)
1055*e5e793a6SGabriel Fernandez 			return ret;
1056*e5e793a6SGabriel Fernandez 	}
1057*e5e793a6SGabriel Fernandez 
1058*e5e793a6SGabriel Fernandez 	/*
1059*e5e793a6SGabriel Fernandez 	 * CKPER is source for some peripheral clocks
1060*e5e793a6SGabriel Fernandez 	 * (FMC-NAND / QPSI-NOR) and switching source is allowed
1061*e5e793a6SGabriel Fernandez 	 * only if previous clock is still ON
1062*e5e793a6SGabriel Fernandez 	 * => deactivate CKPER only after switching clock
1063*e5e793a6SGabriel Fernandez 	 */
1064*e5e793a6SGabriel Fernandez 	if (ckper_disabled) {
1065*e5e793a6SGabriel Fernandez 		ret = stm32_clk_configure_mux(priv,
1066*e5e793a6SGabriel Fernandez 					      CLK_CKPER_DISABLED & CMD_MASK);
1067*e5e793a6SGabriel Fernandez 		if (ret != 0)
1068*e5e793a6SGabriel Fernandez 			return ret;
1069*e5e793a6SGabriel Fernandez 	}
1070*e5e793a6SGabriel Fernandez 
1071*e5e793a6SGabriel Fernandez 	return 0;
1072*e5e793a6SGabriel Fernandez }
1073*e5e793a6SGabriel Fernandez 
1074*e5e793a6SGabriel Fernandez static unsigned long clk_stm32_pll_get_oscillator_rate(int sel)
1075*e5e793a6SGabriel Fernandez {
1076*e5e793a6SGabriel Fernandez 	const int osc[] = { OSC_HSI, OSC_HSE, OSC_CSI };
1077*e5e793a6SGabriel Fernandez 
1078*e5e793a6SGabriel Fernandez 	assert(sel >= 0 && sel < (int)ARRAY_SIZE(osc));
1079*e5e793a6SGabriel Fernandez 
1080*e5e793a6SGabriel Fernandez 	return clk_stm32_get_rate_oscillateur(osc[sel]);
1081*e5e793a6SGabriel Fernandez }
1082*e5e793a6SGabriel Fernandez 
1083*e5e793a6SGabriel Fernandez static int clk_stm32_pll_compute_cfgr1(const struct stm32_clk_pll *pll,
1084*e5e793a6SGabriel Fernandez 				       struct stm32_pll_vco *vco,
1085*e5e793a6SGabriel Fernandez 				       uint32_t *value)
1086*e5e793a6SGabriel Fernandez {
1087*e5e793a6SGabriel Fernandez 	int sel = (vco->src & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
1088*e5e793a6SGabriel Fernandez 	uint32_t divm = vco->div_mn[PLL_CFG_M];
1089*e5e793a6SGabriel Fernandez 	uint32_t divn = vco->div_mn[PLL_CFG_N];
1090*e5e793a6SGabriel Fernandez 	unsigned long refclk = 0UL;
1091*e5e793a6SGabriel Fernandez 
1092*e5e793a6SGabriel Fernandez 	refclk = clk_stm32_pll_get_oscillator_rate(sel) / (divm + 1U);
1093*e5e793a6SGabriel Fernandez 
1094*e5e793a6SGabriel Fernandez 	if ((refclk < (stm32mp1_pll[pll->plltype].refclk_min * 1000000U)) ||
1095*e5e793a6SGabriel Fernandez 	    (refclk > (stm32mp1_pll[pll->plltype].refclk_max * 1000000U)))
1096*e5e793a6SGabriel Fernandez 		return -1;
1097*e5e793a6SGabriel Fernandez 
1098*e5e793a6SGabriel Fernandez 	*value = 0;
1099*e5e793a6SGabriel Fernandez 
1100*e5e793a6SGabriel Fernandez 	if (pll->plltype == PLL_800 && refclk >= 8000000U)
1101*e5e793a6SGabriel Fernandez 		*value = 1U << RCC_PLLNCFGR1_IFRGE_SHIFT;
1102*e5e793a6SGabriel Fernandez 
1103*e5e793a6SGabriel Fernandez 	*value |= (divn << RCC_PLLNCFGR1_DIVN_SHIFT) & RCC_PLLNCFGR1_DIVN_MASK;
1104*e5e793a6SGabriel Fernandez 	*value |= (divm << RCC_PLLNCFGR1_DIVM_SHIFT) & RCC_PLLNCFGR1_DIVM_MASK;
1105*e5e793a6SGabriel Fernandez 
1106*e5e793a6SGabriel Fernandez 	return 0;
1107*e5e793a6SGabriel Fernandez }
1108*e5e793a6SGabriel Fernandez 
1109*e5e793a6SGabriel Fernandez static uint32_t  clk_stm32_pll_compute_cfgr2(struct stm32_pll_output *out)
1110*e5e793a6SGabriel Fernandez {
1111*e5e793a6SGabriel Fernandez 	uint32_t value = 0;
1112*e5e793a6SGabriel Fernandez 
1113*e5e793a6SGabriel Fernandez 	value |= (out->output[PLL_CFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) &
1114*e5e793a6SGabriel Fernandez 		 RCC_PLLNCFGR2_DIVP_MASK;
1115*e5e793a6SGabriel Fernandez 	value |= (out->output[PLL_CFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) &
1116*e5e793a6SGabriel Fernandez 		 RCC_PLLNCFGR2_DIVQ_MASK;
1117*e5e793a6SGabriel Fernandez 	value |= (out->output[PLL_CFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) &
1118*e5e793a6SGabriel Fernandez 		 RCC_PLLNCFGR2_DIVR_MASK;
1119*e5e793a6SGabriel Fernandez 
1120*e5e793a6SGabriel Fernandez 	return value;
1121*e5e793a6SGabriel Fernandez }
1122*e5e793a6SGabriel Fernandez 
1123*e5e793a6SGabriel Fernandez /*
1124*e5e793a6SGabriel Fernandez  * Check if PLL1 can be configured on the fly.
1125*e5e793a6SGabriel Fernandez  * @result (-1) => config on the fly is not possible.
1126*e5e793a6SGabriel Fernandez  *         (0)  => config on the fly is possible.
1127*e5e793a6SGabriel Fernandez  *         (+1) => same parameters, no need to reconfigure.
1128*e5e793a6SGabriel Fernandez  * Return value is 0 if no error.
1129*e5e793a6SGabriel Fernandez  */
1130*e5e793a6SGabriel Fernandez static int clk_stm32_is_pll_config_on_the_fly(struct clk_stm32_priv *priv,
1131*e5e793a6SGabriel Fernandez 					      const struct stm32_clk_pll *pll,
1132*e5e793a6SGabriel Fernandez 					      struct stm32_pll_dt_cfg *pll_conf,
1133*e5e793a6SGabriel Fernandez 					      int *result)
1134*e5e793a6SGabriel Fernandez {
1135*e5e793a6SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1136*e5e793a6SGabriel Fernandez 	struct stm32_pll_vco *vco = &pll_conf->vco;
1137*e5e793a6SGabriel Fernandez 	struct stm32_pll_output *out = &pll_conf->output;
1138*e5e793a6SGabriel Fernandez 	uint32_t fracr = 0;
1139*e5e793a6SGabriel Fernandez 	uint32_t value = 0;
1140*e5e793a6SGabriel Fernandez 	int ret = 0;
1141*e5e793a6SGabriel Fernandez 	size_t sel = 0;
1142*e5e793a6SGabriel Fernandez 
1143*e5e793a6SGabriel Fernandez 	ret = clk_stm32_pll_compute_cfgr1(pll, vco, &value);
1144*e5e793a6SGabriel Fernandez 	if (ret != 0)
1145*e5e793a6SGabriel Fernandez 		return ret;
1146*e5e793a6SGabriel Fernandez 
1147*e5e793a6SGabriel Fernandez 	sel = (vco->src & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
1148*e5e793a6SGabriel Fernandez 	if (sel != stm32_mux_get_parent(pll->mux_id)) {
1149*e5e793a6SGabriel Fernandez 		/* Clock source of the PLL is different */
1150*e5e793a6SGabriel Fernandez 		*result = -1;
1151*e5e793a6SGabriel Fernandez 		return 0;
1152*e5e793a6SGabriel Fernandez 	}
1153*e5e793a6SGabriel Fernandez 
1154*e5e793a6SGabriel Fernandez 	if (io_read32(pll_base + RCC_OFFSET_PLLXCFGR1) != value) {
1155*e5e793a6SGabriel Fernandez 		/* Different DIVN/DIVM, can't config on the fly */
1156*e5e793a6SGabriel Fernandez 		*result = -1;
1157*e5e793a6SGabriel Fernandez 		return 0;
1158*e5e793a6SGabriel Fernandez 	}
1159*e5e793a6SGabriel Fernandez 
1160*e5e793a6SGabriel Fernandez 	*result = 1;
1161*e5e793a6SGabriel Fernandez 
1162*e5e793a6SGabriel Fernandez 	fracr = vco->frac << RCC_PLLNFRACR_FRACV_SHIFT;
1163*e5e793a6SGabriel Fernandez 	fracr |= RCC_PLLNCFGR1_DIVM_MASK;
1164*e5e793a6SGabriel Fernandez 	value = clk_stm32_pll_compute_cfgr2(out);
1165*e5e793a6SGabriel Fernandez 
1166*e5e793a6SGabriel Fernandez 	if ((io_read32(pll_base + RCC_OFFSET_PLLXFRACR) == fracr) &&
1167*e5e793a6SGabriel Fernandez 	    (io_read32(pll_base + RCC_OFFSET_PLLXCFGR2) == value)) {
1168*e5e793a6SGabriel Fernandez 		/* Same parameters, no need to config */
1169*e5e793a6SGabriel Fernandez 		*result = 1;
1170*e5e793a6SGabriel Fernandez 	} else {
1171*e5e793a6SGabriel Fernandez 		*result = 0;
1172*e5e793a6SGabriel Fernandez 	}
1173*e5e793a6SGabriel Fernandez 
1174*e5e793a6SGabriel Fernandez 	return 0;
1175*e5e793a6SGabriel Fernandez }
1176*e5e793a6SGabriel Fernandez 
1177*e5e793a6SGabriel Fernandez static int stm32_clk_hsidiv_configure(struct clk_stm32_priv *priv)
1178*e5e793a6SGabriel Fernandez {
1179*e5e793a6SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1180*e5e793a6SGabriel Fernandez 	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSI];
1181*e5e793a6SGabriel Fernandez 
1182*e5e793a6SGabriel Fernandez 	return stm32_div_set_rate(DIV_HSI, osci->freq, MAX_HSI_HZ);
1183*e5e793a6SGabriel Fernandez }
1184*e5e793a6SGabriel Fernandez 
1185*e5e793a6SGabriel Fernandez static void clk_stm32_pll_config_vco(struct clk_stm32_priv *priv,
1186*e5e793a6SGabriel Fernandez 				     const struct stm32_clk_pll *pll,
1187*e5e793a6SGabriel Fernandez 				     struct stm32_pll_vco *vco)
1188*e5e793a6SGabriel Fernandez {
1189*e5e793a6SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1190*e5e793a6SGabriel Fernandez 	uint32_t value = 0;
1191*e5e793a6SGabriel Fernandez 
1192*e5e793a6SGabriel Fernandez 	if (clk_stm32_pll_compute_cfgr1(pll, vco, &value) != 0) {
1193*e5e793a6SGabriel Fernandez 		EMSG("Invalid Vref clock");
1194*e5e793a6SGabriel Fernandez 		panic();
1195*e5e793a6SGabriel Fernandez 	}
1196*e5e793a6SGabriel Fernandez 
1197*e5e793a6SGabriel Fernandez 	/* Write N / M / IFREGE fields */
1198*e5e793a6SGabriel Fernandez 	io_write32(pll_base + RCC_OFFSET_PLLXCFGR1, value);
1199*e5e793a6SGabriel Fernandez 
1200*e5e793a6SGabriel Fernandez 	/* Fractional configuration */
1201*e5e793a6SGabriel Fernandez 	io_write32(pll_base + RCC_OFFSET_PLLXFRACR, 0);
1202*e5e793a6SGabriel Fernandez 
1203*e5e793a6SGabriel Fernandez 	/* Frac must be enabled only once its configuration is loaded */
1204*e5e793a6SGabriel Fernandez 	io_write32(pll_base + RCC_OFFSET_PLLXFRACR,
1205*e5e793a6SGabriel Fernandez 		   vco->frac << RCC_PLLNFRACR_FRACV_SHIFT);
1206*e5e793a6SGabriel Fernandez 
1207*e5e793a6SGabriel Fernandez 	io_setbits32(pll_base + RCC_OFFSET_PLLXFRACR, RCC_PLLNFRACR_FRACLE);
1208*e5e793a6SGabriel Fernandez }
1209*e5e793a6SGabriel Fernandez 
1210*e5e793a6SGabriel Fernandez static void clk_stm32_pll_config_csg(struct clk_stm32_priv *priv,
1211*e5e793a6SGabriel Fernandez 				     const struct stm32_clk_pll *pll,
1212*e5e793a6SGabriel Fernandez 				     struct stm32_pll_vco *vco)
1213*e5e793a6SGabriel Fernandez {
1214*e5e793a6SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1215*e5e793a6SGabriel Fernandez 	uint32_t mod_per = 0;
1216*e5e793a6SGabriel Fernandez 	uint32_t inc_step = 0;
1217*e5e793a6SGabriel Fernandez 	uint32_t sscg_mode = 0;
1218*e5e793a6SGabriel Fernandez 	uint32_t value = 0;
1219*e5e793a6SGabriel Fernandez 
1220*e5e793a6SGabriel Fernandez 	if (!vco->csg_enabled)
1221*e5e793a6SGabriel Fernandez 		return;
1222*e5e793a6SGabriel Fernandez 
1223*e5e793a6SGabriel Fernandez 	mod_per = vco->csg[PLL_CSG_MOD_PER];
1224*e5e793a6SGabriel Fernandez 	inc_step = vco->csg[PLL_CSG_INC_STEP];
1225*e5e793a6SGabriel Fernandez 	sscg_mode = vco->csg[PLL_CSG_SSCG_MODE];
1226*e5e793a6SGabriel Fernandez 
1227*e5e793a6SGabriel Fernandez 	value |= (mod_per << RCC_PLLNCSGR_MOD_PER_SHIFT) &
1228*e5e793a6SGabriel Fernandez 		 RCC_PLLNCSGR_MOD_PER_MASK;
1229*e5e793a6SGabriel Fernandez 	value |= (inc_step << RCC_PLLNCSGR_INC_STEP_SHIFT) &
1230*e5e793a6SGabriel Fernandez 		 RCC_PLLNCSGR_INC_STEP_MASK;
1231*e5e793a6SGabriel Fernandez 	value |= (sscg_mode << RCC_PLLNCSGR_SSCG_MODE_SHIFT) &
1232*e5e793a6SGabriel Fernandez 		 RCC_PLLNCSGR_SSCG_MODE_MASK;
1233*e5e793a6SGabriel Fernandez 
1234*e5e793a6SGabriel Fernandez 	io_write32(pll_base + RCC_OFFSET_PLLXCSGR, value);
1235*e5e793a6SGabriel Fernandez 	io_setbits32(pll_base + RCC_OFFSET_PLLXCR, RCC_PLLNCR_SSCG_CTRL);
1236*e5e793a6SGabriel Fernandez }
1237*e5e793a6SGabriel Fernandez 
1238*e5e793a6SGabriel Fernandez static void clk_stm32_pll_config_out(struct clk_stm32_priv *priv,
1239*e5e793a6SGabriel Fernandez 				     const struct stm32_clk_pll *pll,
1240*e5e793a6SGabriel Fernandez 				     struct stm32_pll_output *out)
1241*e5e793a6SGabriel Fernandez {
1242*e5e793a6SGabriel Fernandez 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
1243*e5e793a6SGabriel Fernandez 	uint32_t value = 0;
1244*e5e793a6SGabriel Fernandez 
1245*e5e793a6SGabriel Fernandez 	value = clk_stm32_pll_compute_cfgr2(out);
1246*e5e793a6SGabriel Fernandez 
1247*e5e793a6SGabriel Fernandez 	io_write32(pll_base + RCC_OFFSET_PLLXCFGR2, value);
1248*e5e793a6SGabriel Fernandez }
1249*e5e793a6SGabriel Fernandez 
1250*e5e793a6SGabriel Fernandez static struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx)
1251*e5e793a6SGabriel Fernandez {
1252*e5e793a6SGabriel Fernandez 	struct clk_stm32_priv *priv = clk_stm32_get_priv();
1253*e5e793a6SGabriel Fernandez 	struct stm32_clk_platdata *pdata = priv->pdata;
1254*e5e793a6SGabriel Fernandez 
1255*e5e793a6SGabriel Fernandez 	return &pdata->pll[pll_idx];
1256*e5e793a6SGabriel Fernandez }
1257*e5e793a6SGabriel Fernandez 
1258*e5e793a6SGabriel Fernandez static int clk_stm32_pll_init_switch_to_hsi_clk_system(int mux_sys)
1259*e5e793a6SGabriel Fernandez {
1260*e5e793a6SGabriel Fernandez 	int sel = 0;
1261*e5e793a6SGabriel Fernandez 
1262*e5e793a6SGabriel Fernandez 	if (mux_sys == -1)
1263*e5e793a6SGabriel Fernandez 		return -1;
1264*e5e793a6SGabriel Fernandez 
1265*e5e793a6SGabriel Fernandez 	/* Make a backup to the current parent */
1266*e5e793a6SGabriel Fernandez 	sel = stm32_mux_get_parent(mux_sys);
1267*e5e793a6SGabriel Fernandez 
1268*e5e793a6SGabriel Fernandez 	/* Switch to HSI */
1269*e5e793a6SGabriel Fernandez 	if (stm32_mux_set_parent(mux_sys, 0))
1270*e5e793a6SGabriel Fernandez 		return -1;
1271*e5e793a6SGabriel Fernandez 
1272*e5e793a6SGabriel Fernandez 	return sel;
1273*e5e793a6SGabriel Fernandez }
1274*e5e793a6SGabriel Fernandez 
1275*e5e793a6SGabriel Fernandez static uint32_t
1276*e5e793a6SGabriel Fernandez clk_stm32_pll_backup_output_diven(const struct stm32_clk_pll *pll)
1277*e5e793a6SGabriel Fernandez {
1278*e5e793a6SGabriel Fernandez 	struct clk_stm32_priv *priv = clk_stm32_get_priv();
1279*e5e793a6SGabriel Fernandez 	uintptr_t addr = priv->base + pll->reg_pllxcr;
1280*e5e793a6SGabriel Fernandez 
1281*e5e793a6SGabriel Fernandez 	return io_read32(addr + RCC_OFFSET_PLLXCR) &
1282*e5e793a6SGabriel Fernandez 			 (RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN |
1283*e5e793a6SGabriel Fernandez 			  RCC_PLLNCR_DIVREN);
1284*e5e793a6SGabriel Fernandez }
1285*e5e793a6SGabriel Fernandez 
1286*e5e793a6SGabriel Fernandez static void clk_stm32_pll_restore_output_diven(const struct stm32_clk_pll *pll,
1287*e5e793a6SGabriel Fernandez 					       uint32_t value)
1288*e5e793a6SGabriel Fernandez {
1289*e5e793a6SGabriel Fernandez 	struct clk_stm32_priv *priv = clk_stm32_get_priv();
1290*e5e793a6SGabriel Fernandez 	uintptr_t addr = priv->base + pll->reg_pllxcr;
1291*e5e793a6SGabriel Fernandez 	const uint32_t mask = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN |
1292*e5e793a6SGabriel Fernandez 			      RCC_PLLNCR_DIVREN;
1293*e5e793a6SGabriel Fernandez 
1294*e5e793a6SGabriel Fernandez 	io_clrsetbits32(addr, mask, value & mask);
1295*e5e793a6SGabriel Fernandez }
1296*e5e793a6SGabriel Fernandez 
1297*e5e793a6SGabriel Fernandez static int clk_stm32_pll_init(struct clk_stm32_priv *priv, int pll_idx,
1298*e5e793a6SGabriel Fernandez 			      struct stm32_pll_dt_cfg *pll_conf)
1299*e5e793a6SGabriel Fernandez {
1300*e5e793a6SGabriel Fernandez 	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx);
1301*e5e793a6SGabriel Fernandez 	int config_on_the_fly = -1;
1302*e5e793a6SGabriel Fernandez 	int ret = 0;
1303*e5e793a6SGabriel Fernandez 	uint8_t sel = 0;
1304*e5e793a6SGabriel Fernandez 	uint32_t save_div_pqr_en = 0;
1305*e5e793a6SGabriel Fernandez 	int mux_system[] = { MUX_MPU, MUX_AXI, MUX_MLAHB, -1 };
1306*e5e793a6SGabriel Fernandez 	int mux_sys  = mux_system[pll_idx];
1307*e5e793a6SGabriel Fernandez 
1308*e5e793a6SGabriel Fernandez 	ret = clk_stm32_is_pll_config_on_the_fly(priv, pll, pll_conf,
1309*e5e793a6SGabriel Fernandez 						 &config_on_the_fly);
1310*e5e793a6SGabriel Fernandez 	if (ret != 0)
1311*e5e793a6SGabriel Fernandez 		return ret;
1312*e5e793a6SGabriel Fernandez 
1313*e5e793a6SGabriel Fernandez 	/* Backup status of DIV DIVPEN / DIVQEN / DIVREN */
1314*e5e793a6SGabriel Fernandez 	save_div_pqr_en = clk_stm32_pll_backup_output_diven(pll);
1315*e5e793a6SGabriel Fernandez 
1316*e5e793a6SGabriel Fernandez 	if (config_on_the_fly == -1) {
1317*e5e793a6SGabriel Fernandez 		/* Make a backup to the current parent and switch to HSI */
1318*e5e793a6SGabriel Fernandez 		sel = clk_stm32_pll_init_switch_to_hsi_clk_system(mux_sys);
1319*e5e793a6SGabriel Fernandez 
1320*e5e793a6SGabriel Fernandez 		/* Stop the PLL before */
1321*e5e793a6SGabriel Fernandez 		if (stm32_gate_is_enabled(pll->gate_id))  {
1322*e5e793a6SGabriel Fernandez 			io_clrbits32(priv->base + pll->reg_pllxcr,
1323*e5e793a6SGabriel Fernandez 				     RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN |
1324*e5e793a6SGabriel Fernandez 				     RCC_PLLNCR_DIVREN);
1325*e5e793a6SGabriel Fernandez 
1326*e5e793a6SGabriel Fernandez 			if (stm32_gate_rdy_disable(pll->gate_id))
1327*e5e793a6SGabriel Fernandez 				return -1;
1328*e5e793a6SGabriel Fernandez 		}
1329*e5e793a6SGabriel Fernandez 
1330*e5e793a6SGabriel Fernandez 		/* Configure PLLs source */
1331*e5e793a6SGabriel Fernandez 		ret = stm32_clk_configure_mux(priv, pll_conf->vco.src);
1332*e5e793a6SGabriel Fernandez 		if (ret)
1333*e5e793a6SGabriel Fernandez 			return ret;
1334*e5e793a6SGabriel Fernandez 
1335*e5e793a6SGabriel Fernandez 		clk_stm32_pll_config_vco(priv, pll, &pll_conf->vco);
1336*e5e793a6SGabriel Fernandez 	}
1337*e5e793a6SGabriel Fernandez 
1338*e5e793a6SGabriel Fernandez 	if (config_on_the_fly != 1) {
1339*e5e793a6SGabriel Fernandez 		clk_stm32_pll_config_out(priv, pll, &pll_conf->output);
1340*e5e793a6SGabriel Fernandez 		clk_stm32_pll_config_csg(priv, pll, &pll_conf->vco);
1341*e5e793a6SGabriel Fernandez 	}
1342*e5e793a6SGabriel Fernandez 
1343*e5e793a6SGabriel Fernandez 	if (!stm32_gate_is_enabled(pll->gate_id)) {
1344*e5e793a6SGabriel Fernandez 		if (stm32_gate_rdy_enable(pll->gate_id))
1345*e5e793a6SGabriel Fernandez 			return -1;
1346*e5e793a6SGabriel Fernandez 
1347*e5e793a6SGabriel Fernandez 		clk_stm32_pll_restore_output_diven(pll, save_div_pqr_en);
1348*e5e793a6SGabriel Fernandez 	}
1349*e5e793a6SGabriel Fernandez 
1350*e5e793a6SGabriel Fernandez 	if ((config_on_the_fly == -1) && (mux_sys != -1)) {
1351*e5e793a6SGabriel Fernandez 		/* Restore to backup parent */
1352*e5e793a6SGabriel Fernandez 		if (stm32_mux_set_parent(mux_sys, sel))
1353*e5e793a6SGabriel Fernandez 			return -1;
1354*e5e793a6SGabriel Fernandez 	}
1355*e5e793a6SGabriel Fernandez 
1356*e5e793a6SGabriel Fernandez 	return 0;
1357*e5e793a6SGabriel Fernandez }
1358*e5e793a6SGabriel Fernandez 
1359*e5e793a6SGabriel Fernandez static int stm32_clk_pll_configure(struct clk_stm32_priv *priv)
1360*e5e793a6SGabriel Fernandez {
1361*e5e793a6SGabriel Fernandez 	struct stm32_pll_dt_cfg *pll_conf = NULL;
1362*e5e793a6SGabriel Fernandez 	size_t i = 0;
1363*e5e793a6SGabriel Fernandez 	const int plls[] = { PLL1_ID, PLL3_ID, PLL4_ID };
1364*e5e793a6SGabriel Fernandez 
1365*e5e793a6SGabriel Fernandez 	for (i = 0; i < ARRAY_SIZE(plls); i++) {
1366*e5e793a6SGabriel Fernandez 		pll_conf = clk_stm32_pll_get_pdata(plls[i]);
1367*e5e793a6SGabriel Fernandez 
1368*e5e793a6SGabriel Fernandez 		if (pll_conf->vco.status) {
1369*e5e793a6SGabriel Fernandez 			int err = 0;
1370*e5e793a6SGabriel Fernandez 
1371*e5e793a6SGabriel Fernandez 			err = clk_stm32_pll_init(priv, plls[i], pll_conf);
1372*e5e793a6SGabriel Fernandez 			if (err)
1373*e5e793a6SGabriel Fernandez 				return err;
1374*e5e793a6SGabriel Fernandez 		}
1375*e5e793a6SGabriel Fernandez 	}
1376*e5e793a6SGabriel Fernandez 
1377*e5e793a6SGabriel Fernandez 	return 0;
1378*e5e793a6SGabriel Fernandez }
1379*e5e793a6SGabriel Fernandez 
1380*e5e793a6SGabriel Fernandez static int stm32mp1_init_clock_tree(struct clk_stm32_priv *priv,
1381*e5e793a6SGabriel Fernandez 				    struct stm32_clk_platdata *pdata)
1382*e5e793a6SGabriel Fernandez {
1383*e5e793a6SGabriel Fernandez 	int ret = 0;
1384*e5e793a6SGabriel Fernandez 
1385*e5e793a6SGabriel Fernandez 	/*
1386*e5e793a6SGabriel Fernandez 	 * Switch ON oscillators found in device-tree.
1387*e5e793a6SGabriel Fernandez 	 * Note: HSI already ON after BootROM stage.
1388*e5e793a6SGabriel Fernandez 	 */
1389*e5e793a6SGabriel Fernandez 	stm32_clk_oscillators_enable(priv, pdata);
1390*e5e793a6SGabriel Fernandez 
1391*e5e793a6SGabriel Fernandez 	ret = stm32_clk_hsidiv_configure(priv);
1392*e5e793a6SGabriel Fernandez 	if (ret != 0)
1393*e5e793a6SGabriel Fernandez 		return ret;
1394*e5e793a6SGabriel Fernandez 
1395*e5e793a6SGabriel Fernandez 	ret = stm32_clk_dividers_configure(priv);
1396*e5e793a6SGabriel Fernandez 	if (ret != 0)
1397*e5e793a6SGabriel Fernandez 		panic();
1398*e5e793a6SGabriel Fernandez 
1399*e5e793a6SGabriel Fernandez 	ret = stm32_clk_pll_configure(priv);
1400*e5e793a6SGabriel Fernandez 	if (ret != 0)
1401*e5e793a6SGabriel Fernandez 		panic();
1402*e5e793a6SGabriel Fernandez 
1403*e5e793a6SGabriel Fernandez 	/* Wait LSE ready before to use it */
1404*e5e793a6SGabriel Fernandez 	ret = stm32_clk_oscillators_wait_lse_ready(priv, pdata);
1405*e5e793a6SGabriel Fernandez 	if (ret != 0)
1406*e5e793a6SGabriel Fernandez 		panic();
1407*e5e793a6SGabriel Fernandez 
1408*e5e793a6SGabriel Fernandez 	/* Configure with expected clock source */
1409*e5e793a6SGabriel Fernandez 	ret = stm32_clk_source_configure(priv);
1410*e5e793a6SGabriel Fernandez 	if (ret != 0)
1411*e5e793a6SGabriel Fernandez 		panic();
1412*e5e793a6SGabriel Fernandez 
1413*e5e793a6SGabriel Fernandez 	/* Configure LSE CSS after RTC source configuration */
1414*e5e793a6SGabriel Fernandez 	ret = stm32_clk_oscillators_lse_set_css(priv, pdata);
1415*e5e793a6SGabriel Fernandez 	if (ret != 0)
1416*e5e793a6SGabriel Fernandez 		panic();
1417*e5e793a6SGabriel Fernandez 
1418*e5e793a6SGabriel Fernandez 	/* Software Self-Refresh mode (SSR) during DDR initilialization */
1419*e5e793a6SGabriel Fernandez 	io_clrsetbits32(priv->base + RCC_DDRITFCR, RCC_DDRITFCR_DDRCKMOD_MASK,
1420*e5e793a6SGabriel Fernandez 			RCC_DDRITFCR_DDRCKMOD_SSR <<
1421*e5e793a6SGabriel Fernandez 			RCC_DDRITFCR_DDRCKMOD_SHIFT);
1422*e5e793a6SGabriel Fernandez 
1423*e5e793a6SGabriel Fernandez 	return 0;
1424*e5e793a6SGabriel Fernandez }
1425*e5e793a6SGabriel Fernandez 
1426*e5e793a6SGabriel Fernandez static int clk_stm32_parse_oscillator_fdt(const void *fdt, int node,
1427*e5e793a6SGabriel Fernandez 					  const char *name,
1428*e5e793a6SGabriel Fernandez 					  struct stm32_osci_dt_cfg *osci)
1429*e5e793a6SGabriel Fernandez {
1430*e5e793a6SGabriel Fernandez 	int subnode = 0;
1431*e5e793a6SGabriel Fernandez 
1432*e5e793a6SGabriel Fernandez 	fdt_for_each_subnode(subnode, fdt, node) {
1433*e5e793a6SGabriel Fernandez 		const char *cchar = NULL;
1434*e5e793a6SGabriel Fernandez 		const fdt32_t *cuint = NULL;
1435*e5e793a6SGabriel Fernandez 		int ret = 0;
1436*e5e793a6SGabriel Fernandez 
1437*e5e793a6SGabriel Fernandez 		cchar = fdt_get_name(fdt, subnode, &ret);
1438*e5e793a6SGabriel Fernandez 		if (!cchar)
1439*e5e793a6SGabriel Fernandez 			return ret;
1440*e5e793a6SGabriel Fernandez 
1441*e5e793a6SGabriel Fernandez 		if (strncmp(cchar, name, (size_t)ret) ||
1442*e5e793a6SGabriel Fernandez 		    _fdt_get_status(fdt, subnode) == DT_STATUS_DISABLED)
1443*e5e793a6SGabriel Fernandez 			continue;
1444*e5e793a6SGabriel Fernandez 
1445*e5e793a6SGabriel Fernandez 		cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret);
1446*e5e793a6SGabriel Fernandez 		if (!cuint)
1447*e5e793a6SGabriel Fernandez 			panic();
1448*e5e793a6SGabriel Fernandez 
1449*e5e793a6SGabriel Fernandez 		osci->freq = fdt32_to_cpu(*cuint);
1450*e5e793a6SGabriel Fernandez 
1451*e5e793a6SGabriel Fernandez 		if (fdt_getprop(fdt, subnode, "st,bypass", NULL))
1452*e5e793a6SGabriel Fernandez 			osci->bypass = true;
1453*e5e793a6SGabriel Fernandez 
1454*e5e793a6SGabriel Fernandez 		if (fdt_getprop(fdt, subnode, "st,digbypass", NULL))
1455*e5e793a6SGabriel Fernandez 			osci->digbyp = true;
1456*e5e793a6SGabriel Fernandez 
1457*e5e793a6SGabriel Fernandez 		if (fdt_getprop(fdt, subnode, "st,css", NULL))
1458*e5e793a6SGabriel Fernandez 			osci->css = true;
1459*e5e793a6SGabriel Fernandez 
1460*e5e793a6SGabriel Fernandez 		osci->drive = _fdt_read_uint32_default(fdt, subnode, "st,drive",
1461*e5e793a6SGabriel Fernandez 						       LSEDRV_MEDIUM_HIGH);
1462*e5e793a6SGabriel Fernandez 
1463*e5e793a6SGabriel Fernandez 		return 0;
1464*e5e793a6SGabriel Fernandez 	}
1465*e5e793a6SGabriel Fernandez 
1466*e5e793a6SGabriel Fernandez 	return -FDT_ERR_NOTFOUND;
1467*e5e793a6SGabriel Fernandez }
1468*e5e793a6SGabriel Fernandez 
1469*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt_all_oscillator(const void *fdt,
1470*e5e793a6SGabriel Fernandez 					      int node __maybe_unused,
1471*e5e793a6SGabriel Fernandez 					      struct stm32_clk_platdata *pdata)
1472*e5e793a6SGabriel Fernandez {
1473*e5e793a6SGabriel Fernandez 	int fdt_err = 0;
1474*e5e793a6SGabriel Fernandez 	size_t i = 0;
1475*e5e793a6SGabriel Fernandez 	int osc_node = 0;
1476*e5e793a6SGabriel Fernandez 
1477*e5e793a6SGabriel Fernandez 	osc_node = fdt_path_offset(fdt, "/clocks");
1478*e5e793a6SGabriel Fernandez 	if (osc_node < 0)
1479*e5e793a6SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
1480*e5e793a6SGabriel Fernandez 
1481*e5e793a6SGabriel Fernandez 	for (i = 0; i < NB_OSCILLATOR; i++) {
1482*e5e793a6SGabriel Fernandez 		struct stm32_osci_dt_cfg *osci = &pdata->osci[i];
1483*e5e793a6SGabriel Fernandez 		struct clk_oscillator_data *osc_data = NULL;
1484*e5e793a6SGabriel Fernandez 
1485*e5e793a6SGabriel Fernandez 		osc_data = clk_oscillator_get_data(i);
1486*e5e793a6SGabriel Fernandez 
1487*e5e793a6SGabriel Fernandez 		fdt_err = clk_stm32_parse_oscillator_fdt(fdt, osc_node,
1488*e5e793a6SGabriel Fernandez 							 osc_data->name, osci);
1489*e5e793a6SGabriel Fernandez 		if (fdt_err < 0)
1490*e5e793a6SGabriel Fernandez 			panic();
1491*e5e793a6SGabriel Fernandez 	}
1492*e5e793a6SGabriel Fernandez 
1493*e5e793a6SGabriel Fernandez 	return 0;
1494*e5e793a6SGabriel Fernandez }
1495*e5e793a6SGabriel Fernandez 
1496*e5e793a6SGabriel Fernandez static int clk_stm32_load_vco_config_fdt(const void *fdt, int subnode,
1497*e5e793a6SGabriel Fernandez 					 struct stm32_pll_vco *vco)
1498*e5e793a6SGabriel Fernandez {
1499*e5e793a6SGabriel Fernandez 	int ret = 0;
1500*e5e793a6SGabriel Fernandez 
1501*e5e793a6SGabriel Fernandez 	ret = _fdt_read_uint32_array(fdt, subnode, "divmn", vco->div_mn,
1502*e5e793a6SGabriel Fernandez 				     PLL_DIV_MN_NB);
1503*e5e793a6SGabriel Fernandez 	if (ret != 0)
1504*e5e793a6SGabriel Fernandez 		return ret;
1505*e5e793a6SGabriel Fernandez 
1506*e5e793a6SGabriel Fernandez 	ret = _fdt_read_uint32_array(fdt, subnode, "csg", vco->csg,
1507*e5e793a6SGabriel Fernandez 				     PLL_CSG_NB);
1508*e5e793a6SGabriel Fernandez 
1509*e5e793a6SGabriel Fernandez 	vco->csg_enabled = (ret == 0);
1510*e5e793a6SGabriel Fernandez 
1511*e5e793a6SGabriel Fernandez 	if (ret == -FDT_ERR_NOTFOUND)
1512*e5e793a6SGabriel Fernandez 		ret = 0;
1513*e5e793a6SGabriel Fernandez 
1514*e5e793a6SGabriel Fernandez 	if (ret != 0)
1515*e5e793a6SGabriel Fernandez 		return ret;
1516*e5e793a6SGabriel Fernandez 
1517*e5e793a6SGabriel Fernandez 	vco->status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN |
1518*e5e793a6SGabriel Fernandez 		      RCC_PLLNCR_DIVREN | RCC_PLLNCR_PLLON;
1519*e5e793a6SGabriel Fernandez 
1520*e5e793a6SGabriel Fernandez 	vco->frac = _fdt_read_uint32_default(fdt, subnode, "frac", 0);
1521*e5e793a6SGabriel Fernandez 
1522*e5e793a6SGabriel Fernandez 	vco->src = _fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX);
1523*e5e793a6SGabriel Fernandez 
1524*e5e793a6SGabriel Fernandez 	return 0;
1525*e5e793a6SGabriel Fernandez }
1526*e5e793a6SGabriel Fernandez 
1527*e5e793a6SGabriel Fernandez static int clk_stm32_load_output_config_fdt(const void *fdt, int subnode,
1528*e5e793a6SGabriel Fernandez 					    struct stm32_pll_output *output)
1529*e5e793a6SGabriel Fernandez {
1530*e5e793a6SGabriel Fernandez 	return _fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr",
1531*e5e793a6SGabriel Fernandez 				      output->output, (int)PLL_DIV_PQR_NB);
1532*e5e793a6SGabriel Fernandez }
1533*e5e793a6SGabriel Fernandez 
1534*e5e793a6SGabriel Fernandez static int clk_stm32_parse_pll_fdt(const void *fdt, int subnode,
1535*e5e793a6SGabriel Fernandez 				   struct stm32_pll_dt_cfg *pll)
1536*e5e793a6SGabriel Fernandez {
1537*e5e793a6SGabriel Fernandez 	const fdt32_t *cuint = NULL;
1538*e5e793a6SGabriel Fernandez 	int subnode_pll = 0;
1539*e5e793a6SGabriel Fernandez 	int subnode_vco = 0;
1540*e5e793a6SGabriel Fernandez 	int err = 0;
1541*e5e793a6SGabriel Fernandez 
1542*e5e793a6SGabriel Fernandez 	cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
1543*e5e793a6SGabriel Fernandez 	if (!cuint)
1544*e5e793a6SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
1545*e5e793a6SGabriel Fernandez 
1546*e5e793a6SGabriel Fernandez 	subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
1547*e5e793a6SGabriel Fernandez 	if (subnode_pll < 0)
1548*e5e793a6SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
1549*e5e793a6SGabriel Fernandez 
1550*e5e793a6SGabriel Fernandez 	cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL);
1551*e5e793a6SGabriel Fernandez 	if (!cuint)
1552*e5e793a6SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
1553*e5e793a6SGabriel Fernandez 
1554*e5e793a6SGabriel Fernandez 	subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
1555*e5e793a6SGabriel Fernandez 	if (subnode_vco < 0)
1556*e5e793a6SGabriel Fernandez 		return -FDT_ERR_NOTFOUND;
1557*e5e793a6SGabriel Fernandez 
1558*e5e793a6SGabriel Fernandez 	err = clk_stm32_load_vco_config_fdt(fdt, subnode_vco, &pll->vco);
1559*e5e793a6SGabriel Fernandez 	if (err != 0)
1560*e5e793a6SGabriel Fernandez 		return err;
1561*e5e793a6SGabriel Fernandez 
1562*e5e793a6SGabriel Fernandez 	err = clk_stm32_load_output_config_fdt(fdt, subnode_pll, &pll->output);
1563*e5e793a6SGabriel Fernandez 	if (err != 0)
1564*e5e793a6SGabriel Fernandez 		return err;
1565*e5e793a6SGabriel Fernandez 
1566*e5e793a6SGabriel Fernandez 	return 0;
1567*e5e793a6SGabriel Fernandez }
1568*e5e793a6SGabriel Fernandez 
1569*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt_all_pll(const void *fdt, int node,
1570*e5e793a6SGabriel Fernandez 				       struct stm32_clk_platdata *pdata)
1571*e5e793a6SGabriel Fernandez {
1572*e5e793a6SGabriel Fernandez 	size_t i = 0;
1573*e5e793a6SGabriel Fernandez 
1574*e5e793a6SGabriel Fernandez 	for (i = PLL1_ID; i < pdata->npll; i++) {
1575*e5e793a6SGabriel Fernandez 		struct stm32_pll_dt_cfg *pll = pdata->pll + i;
1576*e5e793a6SGabriel Fernandez 		char name[RCC_PLL_NAME_SIZE] = { 0 };
1577*e5e793a6SGabriel Fernandez 		int subnode = 0;
1578*e5e793a6SGabriel Fernandez 		int err = 0;
1579*e5e793a6SGabriel Fernandez 
1580*e5e793a6SGabriel Fernandez 		snprintf(name, sizeof(name), "st,pll@%d", i);
1581*e5e793a6SGabriel Fernandez 
1582*e5e793a6SGabriel Fernandez 		subnode = fdt_subnode_offset(fdt, node, name);
1583*e5e793a6SGabriel Fernandez 		if (subnode < 0)
1584*e5e793a6SGabriel Fernandez 			continue;
1585*e5e793a6SGabriel Fernandez 
1586*e5e793a6SGabriel Fernandez 		err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
1587*e5e793a6SGabriel Fernandez 		if (err != 0)
1588*e5e793a6SGabriel Fernandez 			panic();
1589*e5e793a6SGabriel Fernandez 	}
1590*e5e793a6SGabriel Fernandez 
1591*e5e793a6SGabriel Fernandez 	return 0;
1592*e5e793a6SGabriel Fernandez }
1593*e5e793a6SGabriel Fernandez 
1594*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt_opp(const void *fdt, int node,
1595*e5e793a6SGabriel Fernandez 				   const char *opp_name,
1596*e5e793a6SGabriel Fernandez 				   struct stm32_clk_opp_cfg *opp_cfg)
1597*e5e793a6SGabriel Fernandez {
1598*e5e793a6SGabriel Fernandez 	int subnode = 0;
1599*e5e793a6SGabriel Fernandez 	int nb_opp = 0;
1600*e5e793a6SGabriel Fernandez 	int ret = 0;
1601*e5e793a6SGabriel Fernandez 
1602*e5e793a6SGabriel Fernandez 	node = fdt_subnode_offset(fdt, node, opp_name);
1603*e5e793a6SGabriel Fernandez 	if (node == -FDT_ERR_NOTFOUND)
1604*e5e793a6SGabriel Fernandez 		return 0;
1605*e5e793a6SGabriel Fernandez 	if (node < 0)
1606*e5e793a6SGabriel Fernandez 		return node;
1607*e5e793a6SGabriel Fernandez 
1608*e5e793a6SGabriel Fernandez 	fdt_for_each_subnode(subnode, fdt, node) {
1609*e5e793a6SGabriel Fernandez 		if (nb_opp >= MAX_OPP) {
1610*e5e793a6SGabriel Fernandez 			EMSG("%d MAX opp in %s", MAX_OPP, opp_name);
1611*e5e793a6SGabriel Fernandez 			panic();
1612*e5e793a6SGabriel Fernandez 		}
1613*e5e793a6SGabriel Fernandez 
1614*e5e793a6SGabriel Fernandez 		opp_cfg->frq = _fdt_read_uint32_default(fdt, subnode,
1615*e5e793a6SGabriel Fernandez 							"hz",
1616*e5e793a6SGabriel Fernandez 							UINT32_MAX);
1617*e5e793a6SGabriel Fernandez 
1618*e5e793a6SGabriel Fernandez 		opp_cfg->src = _fdt_read_uint32_default(fdt, subnode,
1619*e5e793a6SGabriel Fernandez 							"st,clksrc",
1620*e5e793a6SGabriel Fernandez 							UINT32_MAX);
1621*e5e793a6SGabriel Fernandez 
1622*e5e793a6SGabriel Fernandez 		opp_cfg->div = _fdt_read_uint32_default(fdt, subnode,
1623*e5e793a6SGabriel Fernandez 							"st,clkdiv",
1624*e5e793a6SGabriel Fernandez 							UINT32_MAX);
1625*e5e793a6SGabriel Fernandez 
1626*e5e793a6SGabriel Fernandez 		ret = clk_stm32_parse_pll_fdt(fdt, subnode, &opp_cfg->pll_cfg);
1627*e5e793a6SGabriel Fernandez 		if (ret)
1628*e5e793a6SGabriel Fernandez 			return ret;
1629*e5e793a6SGabriel Fernandez 
1630*e5e793a6SGabriel Fernandez 		opp_cfg++;
1631*e5e793a6SGabriel Fernandez 		nb_opp++;
1632*e5e793a6SGabriel Fernandez 	}
1633*e5e793a6SGabriel Fernandez 
1634*e5e793a6SGabriel Fernandez 	return 0;
1635*e5e793a6SGabriel Fernandez }
1636*e5e793a6SGabriel Fernandez 
1637*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt_all_opp(const void *fdt, int node,
1638*e5e793a6SGabriel Fernandez 				       struct stm32_clk_platdata *pdata)
1639*e5e793a6SGabriel Fernandez {
1640*e5e793a6SGabriel Fernandez 	struct stm32_clk_opp_dt_cfg *opp = pdata->opp;
1641*e5e793a6SGabriel Fernandez 	int ret = 0;
1642*e5e793a6SGabriel Fernandez 
1643*e5e793a6SGabriel Fernandez 	node = fdt_subnode_offset(fdt, node, "st,clk_opp");
1644*e5e793a6SGabriel Fernandez 	/* No opp are defined */
1645*e5e793a6SGabriel Fernandez 	if (node == -FDT_ERR_NOTFOUND)
1646*e5e793a6SGabriel Fernandez 		return 0;
1647*e5e793a6SGabriel Fernandez 	if (node < 0)
1648*e5e793a6SGabriel Fernandez 		return node;
1649*e5e793a6SGabriel Fernandez 
1650*e5e793a6SGabriel Fernandez 	ret = stm32_clk_parse_fdt_opp(fdt, node, "st,ck_mpu", opp->mpu_opp);
1651*e5e793a6SGabriel Fernandez 	if (ret)
1652*e5e793a6SGabriel Fernandez 		return ret;
1653*e5e793a6SGabriel Fernandez 
1654*e5e793a6SGabriel Fernandez 	ret = stm32_clk_parse_fdt_opp(fdt, node, "st,ck_axi", opp->axi_opp);
1655*e5e793a6SGabriel Fernandez 	if (ret)
1656*e5e793a6SGabriel Fernandez 		return ret;
1657*e5e793a6SGabriel Fernandez 
1658*e5e793a6SGabriel Fernandez 	ret = stm32_clk_parse_fdt_opp(fdt, node, "st,ck_mlahbs",
1659*e5e793a6SGabriel Fernandez 				      opp->mlahbs_opp);
1660*e5e793a6SGabriel Fernandez 	if (ret)
1661*e5e793a6SGabriel Fernandez 		return ret;
1662*e5e793a6SGabriel Fernandez 
1663*e5e793a6SGabriel Fernandez 	return 0;
1664*e5e793a6SGabriel Fernandez }
1665*e5e793a6SGabriel Fernandez 
1666*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt(const void *fdt, int node,
1667*e5e793a6SGabriel Fernandez 			       struct stm32_clk_platdata *pdata)
1668*e5e793a6SGabriel Fernandez {
1669*e5e793a6SGabriel Fernandez 	int err = 0;
1670*e5e793a6SGabriel Fernandez 
1671*e5e793a6SGabriel Fernandez 	err = stm32_clk_parse_fdt_all_oscillator(fdt, node, pdata);
1672*e5e793a6SGabriel Fernandez 	if (err != 0)
1673*e5e793a6SGabriel Fernandez 		return err;
1674*e5e793a6SGabriel Fernandez 
1675*e5e793a6SGabriel Fernandez 	err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
1676*e5e793a6SGabriel Fernandez 	if (err != 0)
1677*e5e793a6SGabriel Fernandez 		return err;
1678*e5e793a6SGabriel Fernandez 
1679*e5e793a6SGabriel Fernandez 	err = stm32_clk_parse_fdt_all_opp(fdt, node, pdata);
1680*e5e793a6SGabriel Fernandez 	if (err != 0)
1681*e5e793a6SGabriel Fernandez 		return err;
1682*e5e793a6SGabriel Fernandez 
1683*e5e793a6SGabriel Fernandez 	err = clk_stm32_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv,
1684*e5e793a6SGabriel Fernandez 					  &pdata->nclkdiv);
1685*e5e793a6SGabriel Fernandez 	if (err != 0)
1686*e5e793a6SGabriel Fernandez 		return err;
1687*e5e793a6SGabriel Fernandez 
1688*e5e793a6SGabriel Fernandez 	err = clk_stm32_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc,
1689*e5e793a6SGabriel Fernandez 					  &pdata->nclksrc);
1690*e5e793a6SGabriel Fernandez 	if (err != 0)
1691*e5e793a6SGabriel Fernandez 		return err;
1692*e5e793a6SGabriel Fernandez 
1693*e5e793a6SGabriel Fernandez 	return 0;
1694*e5e793a6SGabriel Fernandez }
1695*e5e793a6SGabriel Fernandez 
1696*e5e793a6SGabriel Fernandez static struct stm32_pll_dt_cfg mp13_pll[PLL_NB];
1697*e5e793a6SGabriel Fernandez static struct stm32_clk_opp_dt_cfg mp13_clk_opp;
1698*e5e793a6SGabriel Fernandez static struct stm32_osci_dt_cfg mp13_osci[NB_OSCILLATOR];
1699*e5e793a6SGabriel Fernandez static uint32_t mp13_clksrc[MUX_NB];
1700*e5e793a6SGabriel Fernandez static uint32_t mp13_clkdiv[DIV_NB];
1701*e5e793a6SGabriel Fernandez 
1702*e5e793a6SGabriel Fernandez static struct stm32_clk_platdata stm32mp13_clock_pdata = {
1703*e5e793a6SGabriel Fernandez 	.osci		= mp13_osci,
1704*e5e793a6SGabriel Fernandez 	.nosci		= NB_OSCILLATOR,
1705*e5e793a6SGabriel Fernandez 	.pll		= mp13_pll,
1706*e5e793a6SGabriel Fernandez 	.opp		= &mp13_clk_opp,
1707*e5e793a6SGabriel Fernandez 	.npll		= PLL_NB,
1708*e5e793a6SGabriel Fernandez 	.clksrc		= mp13_clksrc,
1709*e5e793a6SGabriel Fernandez 	.nclksrc	= MUX_NB,
1710*e5e793a6SGabriel Fernandez 	.clkdiv		= mp13_clkdiv,
1711*e5e793a6SGabriel Fernandez 	.nclkdiv	= DIV_NB,
1712*e5e793a6SGabriel Fernandez };
1713*e5e793a6SGabriel Fernandez 
1714*e5e793a6SGabriel Fernandez static struct clk_stm32_priv stm32mp13_clock_data = {
1715*e5e793a6SGabriel Fernandez 	.muxes			= parent_mp13,
1716*e5e793a6SGabriel Fernandez 	.nb_muxes		= ARRAY_SIZE(parent_mp13),
1717*e5e793a6SGabriel Fernandez 	.gates			= gates_mp13,
1718*e5e793a6SGabriel Fernandez 	.nb_gates		= ARRAY_SIZE(gates_mp13),
1719*e5e793a6SGabriel Fernandez 	.div			= dividers_mp13,
1720*e5e793a6SGabriel Fernandez 	.nb_div			= ARRAY_SIZE(dividers_mp13),
1721*e5e793a6SGabriel Fernandez 	.pdata			= &stm32mp13_clock_pdata,
1722*e5e793a6SGabriel Fernandez };
1723*e5e793a6SGabriel Fernandez 
1724*e5e793a6SGabriel Fernandez static TEE_Result stm32mp13_clk_probe(const void *fdt, int node,
1725*e5e793a6SGabriel Fernandez 				      const void *compat_data __unused)
1726*e5e793a6SGabriel Fernandez {
1727*e5e793a6SGabriel Fernandez 	TEE_Result res = TEE_ERROR_GENERIC;
1728*e5e793a6SGabriel Fernandez 	int fdt_rc = 0;
1729*e5e793a6SGabriel Fernandez 	int rc = 0;
1730*e5e793a6SGabriel Fernandez 	struct clk_stm32_priv *priv = &stm32mp13_clock_data;
1731*e5e793a6SGabriel Fernandez 	struct stm32_clk_platdata *pdata = &stm32mp13_clock_pdata;
1732*e5e793a6SGabriel Fernandez 
1733*e5e793a6SGabriel Fernandez 	fdt_rc = stm32_clk_parse_fdt(fdt, node, pdata);
1734*e5e793a6SGabriel Fernandez 	if (fdt_rc) {
1735*e5e793a6SGabriel Fernandez 		EMSG("Failed to parse clock node: %d", fdt_rc);
1736*e5e793a6SGabriel Fernandez 		return TEE_ERROR_GENERIC;
1737*e5e793a6SGabriel Fernandez 	}
1738*e5e793a6SGabriel Fernandez 
1739*e5e793a6SGabriel Fernandez 	res = clk_stm32_init(priv, stm32_rcc_base());
1740*e5e793a6SGabriel Fernandez 	if (res)
1741*e5e793a6SGabriel Fernandez 		return res;
1742*e5e793a6SGabriel Fernandez 
1743*e5e793a6SGabriel Fernandez 	rc = stm32mp1_init_clock_tree(priv, pdata);
1744*e5e793a6SGabriel Fernandez 	if (rc)
1745*e5e793a6SGabriel Fernandez 		return TEE_ERROR_GENERIC;
1746*e5e793a6SGabriel Fernandez 
1747*e5e793a6SGabriel Fernandez 	return TEE_SUCCESS;
1748*e5e793a6SGabriel Fernandez }
1749*e5e793a6SGabriel Fernandez 
1750*e5e793a6SGabriel Fernandez CLK_DT_DECLARE(stm32mp13_clk, "st,stm32mp13-rcc", stm32mp13_clk_probe);
1751