xref: /openbmc/u-boot/drivers/clk/clk_stm32f.c (revision 5c8fd32b)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
4  * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
5  */
6 
7 #include <common.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <stm32_rcc.h>
11 
12 #include <asm/io.h>
13 #include <asm/arch/stm32.h>
14 #include <asm/arch/stm32_pwr.h>
15 
16 #include <dt-bindings/mfd/stm32f7-rcc.h>
17 
18 #define RCC_CR_HSION			BIT(0)
19 #define RCC_CR_HSEON			BIT(16)
20 #define RCC_CR_HSERDY			BIT(17)
21 #define RCC_CR_HSEBYP			BIT(18)
22 #define RCC_CR_CSSON			BIT(19)
23 #define RCC_CR_PLLON			BIT(24)
24 #define RCC_CR_PLLRDY			BIT(25)
25 #define RCC_CR_PLLSAION			BIT(28)
26 #define RCC_CR_PLLSAIRDY		BIT(29)
27 
28 #define RCC_PLLCFGR_PLLM_MASK		GENMASK(5, 0)
29 #define RCC_PLLCFGR_PLLN_MASK		GENMASK(14, 6)
30 #define RCC_PLLCFGR_PLLP_MASK		GENMASK(17, 16)
31 #define RCC_PLLCFGR_PLLQ_MASK		GENMASK(27, 24)
32 #define RCC_PLLCFGR_PLLSRC		BIT(22)
33 #define RCC_PLLCFGR_PLLM_SHIFT		0
34 #define RCC_PLLCFGR_PLLN_SHIFT		6
35 #define RCC_PLLCFGR_PLLP_SHIFT		16
36 #define RCC_PLLCFGR_PLLQ_SHIFT		24
37 
38 #define RCC_CFGR_AHB_PSC_MASK		GENMASK(7, 4)
39 #define RCC_CFGR_APB1_PSC_MASK		GENMASK(12, 10)
40 #define RCC_CFGR_APB2_PSC_MASK		GENMASK(15, 13)
41 #define RCC_CFGR_SW0			BIT(0)
42 #define RCC_CFGR_SW1			BIT(1)
43 #define RCC_CFGR_SW_MASK		GENMASK(1, 0)
44 #define RCC_CFGR_SW_HSI			0
45 #define RCC_CFGR_SW_HSE			RCC_CFGR_SW0
46 #define RCC_CFGR_SW_PLL			RCC_CFGR_SW1
47 #define RCC_CFGR_SWS0			BIT(2)
48 #define RCC_CFGR_SWS1			BIT(3)
49 #define RCC_CFGR_SWS_MASK		GENMASK(3, 2)
50 #define RCC_CFGR_SWS_HSI		0
51 #define RCC_CFGR_SWS_HSE		RCC_CFGR_SWS0
52 #define RCC_CFGR_SWS_PLL		RCC_CFGR_SWS1
53 #define RCC_CFGR_HPRE_SHIFT		4
54 #define RCC_CFGR_PPRE1_SHIFT		10
55 #define RCC_CFGR_PPRE2_SHIFT		13
56 
57 #define RCC_PLLSAICFGR_PLLSAIN_MASK	GENMASK(14, 6)
58 #define RCC_PLLSAICFGR_PLLSAIP_MASK	GENMASK(17, 16)
59 #define RCC_PLLSAICFGR_PLLSAIQ_MASK	GENMASK(27, 24)
60 #define RCC_PLLSAICFGR_PLLSAIR_MASK	GENMASK(30, 28)
61 #define RCC_PLLSAICFGR_PLLSAIN_SHIFT	6
62 #define RCC_PLLSAICFGR_PLLSAIP_SHIFT	16
63 #define RCC_PLLSAICFGR_PLLSAIQ_SHIFT	24
64 #define RCC_PLLSAICFGR_PLLSAIR_SHIFT	28
65 #define RCC_PLLSAICFGR_PLLSAIP_4	BIT(16)
66 #define RCC_PLLSAICFGR_PLLSAIQ_4	BIT(26)
67 #define RCC_PLLSAICFGR_PLLSAIR_3	BIT(29) | BIT(28)
68 
69 #define RCC_DCKCFGRX_TIMPRE		BIT(24)
70 #define RCC_DCKCFGRX_CK48MSEL		BIT(27)
71 #define RCC_DCKCFGRX_SDMMC1SEL		BIT(28)
72 #define RCC_DCKCFGR2_SDMMC2SEL		BIT(29)
73 
74 #define RCC_DCKCFGR_PLLSAIDIVR_SHIFT    16
75 #define RCC_DCKCFGR_PLLSAIDIVR_MASK	GENMASK(17, 16)
76 #define RCC_DCKCFGR_PLLSAIDIVR_2	0
77 
78 /*
79  * RCC AHB1ENR specific definitions
80  */
81 #define RCC_AHB1ENR_ETHMAC_EN		BIT(25)
82 #define RCC_AHB1ENR_ETHMAC_TX_EN	BIT(26)
83 #define RCC_AHB1ENR_ETHMAC_RX_EN	BIT(27)
84 
85 /*
86  * RCC APB1ENR specific definitions
87  */
88 #define RCC_APB1ENR_TIM2EN		BIT(0)
89 #define RCC_APB1ENR_PWREN		BIT(28)
90 
91 /*
92  * RCC APB2ENR specific definitions
93  */
94 #define RCC_APB2ENR_SYSCFGEN		BIT(14)
95 #define RCC_APB2ENR_SAI1EN		BIT(22)
96 
97 enum pllsai_div {
98 	PLLSAIP,
99 	PLLSAIQ,
100 	PLLSAIR,
101 };
102 
103 static const struct stm32_clk_info stm32f4_clk_info = {
104 	/* 180 MHz */
105 	.sys_pll_psc = {
106 		.pll_n = 360,
107 		.pll_p = 2,
108 		.pll_q = 8,
109 		.ahb_psc = AHB_PSC_1,
110 		.apb1_psc = APB_PSC_4,
111 		.apb2_psc = APB_PSC_2,
112 	},
113 	.has_overdrive = false,
114 	.v2 = false,
115 };
116 
117 static const struct stm32_clk_info stm32f7_clk_info = {
118 	/* 200 MHz */
119 	.sys_pll_psc = {
120 		.pll_n = 400,
121 		.pll_p = 2,
122 		.pll_q = 8,
123 		.ahb_psc = AHB_PSC_1,
124 		.apb1_psc = APB_PSC_4,
125 		.apb2_psc = APB_PSC_2,
126 	},
127 	.has_overdrive = true,
128 	.v2 = true,
129 };
130 
131 struct stm32_clk {
132 	struct stm32_rcc_regs *base;
133 	struct stm32_pwr_regs *pwr_regs;
134 	struct stm32_clk_info info;
135 	unsigned long hse_rate;
136 	bool pllsaip;
137 };
138 
139 #ifdef CONFIG_VIDEO_STM32
140 static const u8 plldivr_table[] = { 0, 0, 2, 3, 4, 5, 6, 7 };
141 #endif
142 static const u8 pllsaidivr_table[] = { 2, 4, 8, 16 };
143 
144 static int configure_clocks(struct udevice *dev)
145 {
146 	struct stm32_clk *priv = dev_get_priv(dev);
147 	struct stm32_rcc_regs *regs = priv->base;
148 	struct stm32_pwr_regs *pwr = priv->pwr_regs;
149 	struct pll_psc *sys_pll_psc = &priv->info.sys_pll_psc;
150 
151 	/* Reset RCC configuration */
152 	setbits_le32(&regs->cr, RCC_CR_HSION);
153 	writel(0, &regs->cfgr); /* Reset CFGR */
154 	clrbits_le32(&regs->cr, (RCC_CR_HSEON | RCC_CR_CSSON
155 		| RCC_CR_PLLON | RCC_CR_PLLSAION));
156 	writel(0x24003010, &regs->pllcfgr); /* Reset value from RM */
157 	clrbits_le32(&regs->cr, RCC_CR_HSEBYP);
158 	writel(0, &regs->cir); /* Disable all interrupts */
159 
160 	/* Configure for HSE+PLL operation */
161 	setbits_le32(&regs->cr, RCC_CR_HSEON);
162 	while (!(readl(&regs->cr) & RCC_CR_HSERDY))
163 		;
164 
165 	setbits_le32(&regs->cfgr, ((
166 		sys_pll_psc->ahb_psc << RCC_CFGR_HPRE_SHIFT)
167 		| (sys_pll_psc->apb1_psc << RCC_CFGR_PPRE1_SHIFT)
168 		| (sys_pll_psc->apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
169 
170 	/* Configure the main PLL */
171 	setbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLSRC); /* pll source HSE */
172 	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLM_MASK,
173 			sys_pll_psc->pll_m << RCC_PLLCFGR_PLLM_SHIFT);
174 	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLN_MASK,
175 			sys_pll_psc->pll_n << RCC_PLLCFGR_PLLN_SHIFT);
176 	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLP_MASK,
177 			((sys_pll_psc->pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT);
178 	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLQ_MASK,
179 			sys_pll_psc->pll_q << RCC_PLLCFGR_PLLQ_SHIFT);
180 
181 	/* configure SDMMC clock */
182 	if (priv->info.v2) { /*stm32f7 case */
183 		if (priv->pllsaip)
184 			/* select PLLSAIP as 48MHz clock source */
185 			setbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
186 		else
187 			/* select PLLQ as 48MHz clock source */
188 			clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
189 
190 		/* select 48MHz as SDMMC1 clock source */
191 		clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_SDMMC1SEL);
192 
193 		/* select 48MHz as SDMMC2 clock source */
194 		clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGR2_SDMMC2SEL);
195 	} else  { /* stm32f4 case */
196 		if (priv->pllsaip)
197 			/* select PLLSAIP as 48MHz clock source */
198 			setbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
199 		else
200 			/* select PLLQ as 48MHz clock source */
201 			clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
202 
203 		/* select 48MHz as SDMMC1 clock source */
204 		clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_SDMMC1SEL);
205 	}
206 
207 	/*
208 	 * Configure the SAI PLL to generate LTDC pixel clock and
209 	 * 48 Mhz for SDMMC and USB
210 	 */
211 	clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIP_MASK,
212 			RCC_PLLSAICFGR_PLLSAIP_4);
213 	clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIR_MASK,
214 			RCC_PLLSAICFGR_PLLSAIR_3);
215 	clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIN_MASK,
216 			195 << RCC_PLLSAICFGR_PLLSAIN_SHIFT);
217 
218 	clrsetbits_le32(&regs->dckcfgr, RCC_DCKCFGR_PLLSAIDIVR_MASK,
219 			RCC_DCKCFGR_PLLSAIDIVR_2 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT);
220 
221 	/* Enable the main PLL */
222 	setbits_le32(&regs->cr, RCC_CR_PLLON);
223 	while (!(readl(&regs->cr) & RCC_CR_PLLRDY))
224 		;
225 
226 	/* Enable the SAI PLL */
227 	setbits_le32(&regs->cr, RCC_CR_PLLSAION);
228 	while (!(readl(&regs->cr) & RCC_CR_PLLSAIRDY))
229 		;
230 	setbits_le32(&regs->apb1enr, RCC_APB1ENR_PWREN);
231 
232 	if (priv->info.has_overdrive) {
233 		/*
234 		 * Enable high performance mode
235 		 * System frequency up to 200 MHz
236 		 */
237 		setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
238 		/* Infinite wait! */
239 		while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY))
240 			;
241 		/* Enable the Over-drive switch */
242 		setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN);
243 		/* Infinite wait! */
244 		while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY))
245 			;
246 	}
247 
248 	stm32_flash_latency_cfg(5);
249 	clrbits_le32(&regs->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
250 	setbits_le32(&regs->cfgr, RCC_CFGR_SW_PLL);
251 
252 	while ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) !=
253 			RCC_CFGR_SWS_PLL)
254 		;
255 
256 #ifdef CONFIG_ETH_DESIGNWARE
257 	/* gate the SYSCFG clock, needed to set RMII ethernet interface */
258 	setbits_le32(&regs->apb2enr, RCC_APB2ENR_SYSCFGEN);
259 #endif
260 
261 	return 0;
262 }
263 
264 static bool stm32_clk_get_ck48msel(struct stm32_clk *priv)
265 {
266 	struct stm32_rcc_regs *regs = priv->base;
267 
268 	if (priv->info.v2) /*stm32f7 case */
269 		return readl(&regs->dckcfgr2) & RCC_DCKCFGRX_CK48MSEL;
270 	else
271 
272 		return readl(&regs->dckcfgr) & RCC_DCKCFGRX_CK48MSEL;
273 }
274 
275 static unsigned long stm32_clk_get_pllsai_vco_rate(struct stm32_clk *priv)
276 {
277 	struct stm32_rcc_regs *regs = priv->base;
278 	u16 pllm, pllsain;
279 
280 	pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
281 	pllsain = ((readl(&regs->pllsaicfgr) & RCC_PLLSAICFGR_PLLSAIN_MASK)
282 		  >> RCC_PLLSAICFGR_PLLSAIN_SHIFT);
283 
284 	return ((priv->hse_rate / pllm) * pllsain);
285 }
286 
287 static unsigned long stm32_clk_get_pllsai_rate(struct stm32_clk *priv,
288 					       enum pllsai_div output)
289 {
290 	struct stm32_rcc_regs *regs = priv->base;
291 	u16 pll_div_output;
292 
293 	switch (output) {
294 	case PLLSAIP:
295 		pll_div_output = ((((readl(&regs->pllsaicfgr)
296 				  & RCC_PLLSAICFGR_PLLSAIP_MASK)
297 				  >> RCC_PLLSAICFGR_PLLSAIP_SHIFT) + 1) << 1);
298 		break;
299 	case PLLSAIQ:
300 		pll_div_output = (readl(&regs->pllsaicfgr)
301 				  & RCC_PLLSAICFGR_PLLSAIQ_MASK)
302 				  >> RCC_PLLSAICFGR_PLLSAIQ_SHIFT;
303 		break;
304 	case PLLSAIR:
305 		pll_div_output = (readl(&regs->pllsaicfgr)
306 				  & RCC_PLLSAICFGR_PLLSAIR_MASK)
307 				  >> RCC_PLLSAICFGR_PLLSAIR_SHIFT;
308 		break;
309 	default:
310 		pr_err("incorrect PLLSAI output %d\n", output);
311 		return -EINVAL;
312 	}
313 
314 	return (stm32_clk_get_pllsai_vco_rate(priv) / pll_div_output);
315 }
316 
317 static bool stm32_get_timpre(struct stm32_clk *priv)
318 {
319 	struct stm32_rcc_regs *regs = priv->base;
320 	u32 val;
321 
322 	if (priv->info.v2) /*stm32f7 case */
323 		val = readl(&regs->dckcfgr2);
324 	else
325 		val = readl(&regs->dckcfgr);
326 	/* get timer prescaler */
327 	return !!(val & RCC_DCKCFGRX_TIMPRE);
328 }
329 
330 static u32 stm32_get_hclk_rate(struct stm32_rcc_regs *regs, u32 sysclk)
331 {
332 	u8 shift;
333 	/* Prescaler table lookups for clock computation */
334 	u8 ahb_psc_table[16] = {
335 		0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
336 	};
337 
338 	shift = ahb_psc_table[(
339 		(readl(&regs->cfgr) & RCC_CFGR_AHB_PSC_MASK)
340 		>> RCC_CFGR_HPRE_SHIFT)];
341 
342 	return sysclk >> shift;
343 };
344 
345 static u8 stm32_get_apb_shift(struct stm32_rcc_regs *regs, enum apb apb)
346 {
347 	/* Prescaler table lookups for clock computation */
348 	u8 apb_psc_table[8] = {
349 		0, 0, 0, 0, 1, 2, 3, 4
350 	};
351 
352 	if (apb == APB1)
353 		return apb_psc_table[(
354 		       (readl(&regs->cfgr) & RCC_CFGR_APB1_PSC_MASK)
355 		       >> RCC_CFGR_PPRE1_SHIFT)];
356 	else /* APB2 */
357 		return apb_psc_table[(
358 		       (readl(&regs->cfgr) & RCC_CFGR_APB2_PSC_MASK)
359 		       >> RCC_CFGR_PPRE2_SHIFT)];
360 };
361 
362 static u32 stm32_get_timer_rate(struct stm32_clk *priv, u32 sysclk,
363 				enum apb apb)
364 {
365 	struct stm32_rcc_regs *regs = priv->base;
366 	u8 shift = stm32_get_apb_shift(regs, apb);
367 
368 	if (stm32_get_timpre(priv))
369 		/*
370 		 * if APB prescaler is configured to a
371 		 * division factor of 1, 2 or 4
372 		 */
373 		switch (shift) {
374 		case 0:
375 		case 1:
376 		case 2:
377 			return stm32_get_hclk_rate(regs, sysclk);
378 		default:
379 			return (sysclk >> shift) * 4;
380 		}
381 	else
382 		/*
383 		 * if APB prescaler is configured to a
384 		 * division factor of 1
385 		 */
386 		if (shift == 0)
387 			return sysclk;
388 		else
389 			return (sysclk >> shift) * 2;
390 };
391 
392 static ulong stm32_clk_get_rate(struct clk *clk)
393 {
394 	struct stm32_clk *priv = dev_get_priv(clk->dev);
395 	struct stm32_rcc_regs *regs = priv->base;
396 	u32 sysclk = 0;
397 	u32 vco;
398 	u32 sdmmcxsel_bit;
399 	u32 saidivr;
400 	u32 pllsai_rate;
401 	u16 pllm, plln, pllp, pllq;
402 
403 	if ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) ==
404 			RCC_CFGR_SWS_PLL) {
405 		pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
406 		plln = ((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
407 			>> RCC_PLLCFGR_PLLN_SHIFT);
408 		pllp = ((((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
409 			>> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
410 		pllq = ((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLQ_MASK)
411 			>> RCC_PLLCFGR_PLLQ_SHIFT);
412 		vco = (priv->hse_rate / pllm) * plln;
413 		sysclk = vco / pllp;
414 	} else {
415 		return -EINVAL;
416 	}
417 
418 	switch (clk->id) {
419 	/*
420 	 * AHB CLOCK: 3 x 32 bits consecutive registers are used :
421 	 * AHB1, AHB2 and AHB3
422 	 */
423 	case STM32F7_AHB1_CLOCK(GPIOA) ... STM32F7_AHB3_CLOCK(QSPI):
424 		return stm32_get_hclk_rate(regs, sysclk);
425 	/* APB1 CLOCK */
426 	case STM32F7_APB1_CLOCK(TIM2) ... STM32F7_APB1_CLOCK(UART8):
427 		/* For timer clock, an additionnal prescaler is used*/
428 		switch (clk->id) {
429 		case STM32F7_APB1_CLOCK(TIM2):
430 		case STM32F7_APB1_CLOCK(TIM3):
431 		case STM32F7_APB1_CLOCK(TIM4):
432 		case STM32F7_APB1_CLOCK(TIM5):
433 		case STM32F7_APB1_CLOCK(TIM6):
434 		case STM32F7_APB1_CLOCK(TIM7):
435 		case STM32F7_APB1_CLOCK(TIM12):
436 		case STM32F7_APB1_CLOCK(TIM13):
437 		case STM32F7_APB1_CLOCK(TIM14):
438 			return stm32_get_timer_rate(priv, sysclk, APB1);
439 		}
440 		return (sysclk >> stm32_get_apb_shift(regs, APB1));
441 
442 	/* APB2 CLOCK */
443 	case STM32F7_APB2_CLOCK(TIM1) ... STM32F7_APB2_CLOCK(DSI):
444 		switch (clk->id) {
445 		/*
446 		 * particular case for SDMMC1 and SDMMC2 :
447 		 * 48Mhz source clock can be from main PLL or from
448 		 * PLLSAIP
449 		 */
450 		case STM32F7_APB2_CLOCK(SDMMC1):
451 		case STM32F7_APB2_CLOCK(SDMMC2):
452 			if (clk->id == STM32F7_APB2_CLOCK(SDMMC1))
453 				sdmmcxsel_bit = RCC_DCKCFGRX_SDMMC1SEL;
454 			else
455 				sdmmcxsel_bit = RCC_DCKCFGR2_SDMMC2SEL;
456 
457 			if (readl(&regs->dckcfgr2) & sdmmcxsel_bit)
458 				/* System clock is selected as SDMMC1 clock */
459 				return sysclk;
460 			/*
461 			 * 48 MHz can be generated by either PLLSAIP
462 			 * or by PLLQ depending of CK48MSEL bit of RCC_DCKCFGR
463 			 */
464 			if (stm32_clk_get_ck48msel(priv))
465 				return stm32_clk_get_pllsai_rate(priv, PLLSAIP);
466 			else
467 				return (vco / pllq);
468 			break;
469 
470 		/* For timer clock, an additionnal prescaler is used*/
471 		case STM32F7_APB2_CLOCK(TIM1):
472 		case STM32F7_APB2_CLOCK(TIM8):
473 		case STM32F7_APB2_CLOCK(TIM9):
474 		case STM32F7_APB2_CLOCK(TIM10):
475 		case STM32F7_APB2_CLOCK(TIM11):
476 			return stm32_get_timer_rate(priv, sysclk, APB2);
477 		break;
478 
479 		/* particular case for LTDC clock */
480 		case STM32F7_APB2_CLOCK(LTDC):
481 			saidivr = readl(&regs->dckcfgr);
482 			saidivr = (saidivr & RCC_DCKCFGR_PLLSAIDIVR_MASK)
483 				  >> RCC_DCKCFGR_PLLSAIDIVR_SHIFT;
484 			pllsai_rate = stm32_clk_get_pllsai_rate(priv, PLLSAIR);
485 
486 			return pllsai_rate / pllsaidivr_table[saidivr];
487 		}
488 		return (sysclk >> stm32_get_apb_shift(regs, APB2));
489 
490 	default:
491 		pr_err("clock index %ld out of range\n", clk->id);
492 		return -EINVAL;
493 	}
494 }
495 
496 static ulong stm32_set_rate(struct clk *clk, ulong rate)
497 {
498 #ifdef CONFIG_VIDEO_STM32
499 	struct stm32_clk *priv = dev_get_priv(clk->dev);
500 	struct stm32_rcc_regs *regs = priv->base;
501 	u32 pllsair_rate, pllsai_vco_rate, current_rate;
502 	u32 best_div, best_diff, diff;
503 	u16 div;
504 	u8 best_plldivr, best_pllsaidivr;
505 	u8 i, j;
506 	bool found = false;
507 
508 	/* Only set_rate for LTDC clock is implemented */
509 	if (clk->id != STM32F7_APB2_CLOCK(LTDC)) {
510 		pr_err("set_rate not implemented for clock index %ld\n",
511 		       clk->id);
512 		return 0;
513 	}
514 
515 	if (rate == stm32_clk_get_rate(clk))
516 		/* already set to requested rate */
517 		return rate;
518 
519 	/* get the current PLLSAIR output freq */
520 	pllsair_rate = stm32_clk_get_pllsai_rate(priv, PLLSAIR);
521 	best_div = pllsair_rate / rate;
522 
523 	/* look into pllsaidivr_table if this divider is available*/
524 	for (i = 0 ; i < sizeof(pllsaidivr_table); i++)
525 		if (best_div == pllsaidivr_table[i]) {
526 			/* set pll_saidivr with found value */
527 			clrsetbits_le32(&regs->dckcfgr,
528 					RCC_DCKCFGR_PLLSAIDIVR_MASK,
529 					pllsaidivr_table[i]);
530 			return rate;
531 		}
532 
533 	/*
534 	 * As no pllsaidivr value is suitable to obtain requested freq,
535 	 * test all combination of pllsaidivr * pllsair and find the one
536 	 * which give freq closest to requested rate.
537 	 */
538 
539 	pllsai_vco_rate = stm32_clk_get_pllsai_vco_rate(priv);
540 	best_diff = ULONG_MAX;
541 	best_pllsaidivr = 0;
542 	best_plldivr = 0;
543 	/*
544 	 * start at index 2 of plldivr_table as divider value at index 0
545 	 * and 1 are 0)
546 	 */
547 	for (i = 2; i < sizeof(plldivr_table); i++) {
548 		for (j = 0; j < sizeof(pllsaidivr_table); j++) {
549 			div = plldivr_table[i] * pllsaidivr_table[j];
550 			current_rate = pllsai_vco_rate / div;
551 			/* perfect combination is found ? */
552 			if (current_rate == rate) {
553 				best_pllsaidivr = j;
554 				best_plldivr = i;
555 				found = true;
556 				break;
557 			}
558 
559 			diff = (current_rate > rate) ?
560 			       current_rate - rate : rate - current_rate;
561 
562 			/* found a better combination ? */
563 			if (diff < best_diff) {
564 				best_diff = diff;
565 				best_pllsaidivr = j;
566 				best_plldivr = i;
567 			}
568 		}
569 
570 		if (found)
571 			break;
572 	}
573 
574 	/* Disable the SAI PLL */
575 	clrbits_le32(&regs->cr, RCC_CR_PLLSAION);
576 
577 	/* set pll_saidivr with found value */
578 	clrsetbits_le32(&regs->dckcfgr, RCC_DCKCFGR_PLLSAIDIVR_MASK,
579 			best_pllsaidivr << RCC_DCKCFGR_PLLSAIDIVR_SHIFT);
580 
581 	/* set pllsair with found value */
582 	clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIR_MASK,
583 			plldivr_table[best_plldivr]
584 			<< RCC_PLLSAICFGR_PLLSAIR_SHIFT);
585 
586 	/* Enable the SAI PLL */
587 	setbits_le32(&regs->cr, RCC_CR_PLLSAION);
588 	while (!(readl(&regs->cr) & RCC_CR_PLLSAIRDY))
589 		;
590 
591 	div = plldivr_table[best_plldivr] * pllsaidivr_table[best_pllsaidivr];
592 	return pllsai_vco_rate / div;
593 #else
594 	return 0;
595 #endif
596 }
597 
598 static int stm32_clk_enable(struct clk *clk)
599 {
600 	struct stm32_clk *priv = dev_get_priv(clk->dev);
601 	struct stm32_rcc_regs *regs = priv->base;
602 	u32 offset = clk->id / 32;
603 	u32 bit_index = clk->id % 32;
604 
605 	debug("%s: clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n",
606 	      __func__, clk->id, offset, bit_index);
607 	setbits_le32(&regs->ahb1enr + offset, BIT(bit_index));
608 
609 	return 0;
610 }
611 
612 static int stm32_clk_probe(struct udevice *dev)
613 {
614 	struct ofnode_phandle_args args;
615 	struct udevice *fixed_clock_dev = NULL;
616 	struct clk clk;
617 	int err;
618 
619 	debug("%s\n", __func__);
620 
621 	struct stm32_clk *priv = dev_get_priv(dev);
622 	fdt_addr_t addr;
623 
624 	addr = dev_read_addr(dev);
625 	if (addr == FDT_ADDR_T_NONE)
626 		return -EINVAL;
627 
628 	priv->base = (struct stm32_rcc_regs *)addr;
629 	priv->pllsaip = true;
630 
631 	switch (dev_get_driver_data(dev)) {
632 	case STM32F42X:
633 		priv->pllsaip = false;
634 		/* fallback into STM32F469 case */
635 	case STM32F469:
636 		memcpy(&priv->info, &stm32f4_clk_info,
637 		       sizeof(struct stm32_clk_info));
638 		break;
639 
640 	case STM32F7:
641 		memcpy(&priv->info, &stm32f7_clk_info,
642 		       sizeof(struct stm32_clk_info));
643 		break;
644 	default:
645 		return -EINVAL;
646 	}
647 
648 	/* retrieve HSE frequency (external oscillator) */
649 	err = uclass_get_device_by_name(UCLASS_CLK, "clk-hse",
650 					&fixed_clock_dev);
651 
652 	if (err) {
653 		pr_err("Can't find fixed clock (%d)", err);
654 		return err;
655 	}
656 
657 	err = clk_request(fixed_clock_dev, &clk);
658 	if (err) {
659 		pr_err("Can't request %s clk (%d)", fixed_clock_dev->name,
660 		       err);
661 		return err;
662 	}
663 
664 	/*
665 	 * set pllm factor accordingly to the external oscillator
666 	 * frequency (HSE). For STM32F4 and STM32F7, we want VCO
667 	 * freq at 1MHz
668 	 * if input PLL frequency is 25Mhz, divide it by 25
669 	 */
670 	clk.id = 0;
671 	priv->hse_rate = clk_get_rate(&clk);
672 
673 	if (priv->hse_rate < 1000000) {
674 		pr_err("%s: unexpected HSE clock rate = %ld \"n", __func__,
675 		       priv->hse_rate);
676 		return -EINVAL;
677 	}
678 
679 	priv->info.sys_pll_psc.pll_m = priv->hse_rate / 1000000;
680 
681 	if (priv->info.has_overdrive) {
682 		err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
683 						 &args);
684 		if (err) {
685 			debug("%s: can't find syscon device (%d)\n", __func__,
686 			      err);
687 			return err;
688 		}
689 
690 		priv->pwr_regs = (struct stm32_pwr_regs *)ofnode_get_addr(args.node);
691 	}
692 
693 	configure_clocks(dev);
694 
695 	return 0;
696 }
697 
698 static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
699 {
700 	debug("%s(clk=%p)\n", __func__, clk);
701 
702 	if (args->args_count != 2) {
703 		debug("Invaild args_count: %d\n", args->args_count);
704 		return -EINVAL;
705 	}
706 
707 	if (args->args_count)
708 		clk->id = args->args[1];
709 	else
710 		clk->id = 0;
711 
712 	return 0;
713 }
714 
715 static struct clk_ops stm32_clk_ops = {
716 	.of_xlate	= stm32_clk_of_xlate,
717 	.enable		= stm32_clk_enable,
718 	.get_rate	= stm32_clk_get_rate,
719 	.set_rate	= stm32_set_rate,
720 };
721 
722 U_BOOT_DRIVER(stm32fx_clk) = {
723 	.name			= "stm32fx_rcc_clock",
724 	.id			= UCLASS_CLK,
725 	.ops			= &stm32_clk_ops,
726 	.probe			= stm32_clk_probe,
727 	.priv_auto_alloc_size	= sizeof(struct stm32_clk),
728 	.flags			= DM_FLAG_PRE_RELOC,
729 };
730