xref: /openbmc/u-boot/drivers/clk/clk_stm32f.c (revision aa5e3e22)
1 /*
2  * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
3  * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <stm32_rcc.h>
12 
13 #include <asm/io.h>
14 #include <asm/arch/stm32.h>
15 #include <asm/arch/stm32_pwr.h>
16 
17 #include <dt-bindings/mfd/stm32f7-rcc.h>
18 
19 #define RCC_CR_HSION			BIT(0)
20 #define RCC_CR_HSEON			BIT(16)
21 #define RCC_CR_HSERDY			BIT(17)
22 #define RCC_CR_HSEBYP			BIT(18)
23 #define RCC_CR_CSSON			BIT(19)
24 #define RCC_CR_PLLON			BIT(24)
25 #define RCC_CR_PLLRDY			BIT(25)
26 #define RCC_CR_PLLSAION			BIT(28)
27 #define RCC_CR_PLLSAIRDY		BIT(29)
28 
29 #define RCC_PLLCFGR_PLLM_MASK		GENMASK(5, 0)
30 #define RCC_PLLCFGR_PLLN_MASK		GENMASK(14, 6)
31 #define RCC_PLLCFGR_PLLP_MASK		GENMASK(17, 16)
32 #define RCC_PLLCFGR_PLLQ_MASK		GENMASK(27, 24)
33 #define RCC_PLLCFGR_PLLSRC		BIT(22)
34 #define RCC_PLLCFGR_PLLM_SHIFT		0
35 #define RCC_PLLCFGR_PLLN_SHIFT		6
36 #define RCC_PLLCFGR_PLLP_SHIFT		16
37 #define RCC_PLLCFGR_PLLQ_SHIFT		24
38 
39 #define RCC_CFGR_AHB_PSC_MASK		GENMASK(7, 4)
40 #define RCC_CFGR_APB1_PSC_MASK		GENMASK(12, 10)
41 #define RCC_CFGR_APB2_PSC_MASK		GENMASK(15, 13)
42 #define RCC_CFGR_SW0			BIT(0)
43 #define RCC_CFGR_SW1			BIT(1)
44 #define RCC_CFGR_SW_MASK		GENMASK(1, 0)
45 #define RCC_CFGR_SW_HSI			0
46 #define RCC_CFGR_SW_HSE			RCC_CFGR_SW0
47 #define RCC_CFGR_SW_PLL			RCC_CFGR_SW1
48 #define RCC_CFGR_SWS0			BIT(2)
49 #define RCC_CFGR_SWS1			BIT(3)
50 #define RCC_CFGR_SWS_MASK		GENMASK(3, 2)
51 #define RCC_CFGR_SWS_HSI		0
52 #define RCC_CFGR_SWS_HSE		RCC_CFGR_SWS0
53 #define RCC_CFGR_SWS_PLL		RCC_CFGR_SWS1
54 #define RCC_CFGR_HPRE_SHIFT		4
55 #define RCC_CFGR_PPRE1_SHIFT		10
56 #define RCC_CFGR_PPRE2_SHIFT		13
57 
58 #define RCC_PLLCFGR_PLLSAIN_MASK	GENMASK(14, 6)
59 #define RCC_PLLCFGR_PLLSAIP_MASK	GENMASK(17, 16)
60 #define RCC_PLLSAICFGR_PLLSAIN_SHIFT	6
61 #define RCC_PLLSAICFGR_PLLSAIP_SHIFT	16
62 #define RCC_PLLSAICFGR_PLLSAIP_4	BIT(16)
63 #define RCC_PLLSAICFGR_PLLSAIQ_4	BIT(26)
64 #define RCC_PLLSAICFGR_PLLSAIR_2	BIT(29)
65 
66 #define RCC_DCKCFGRX_TIMPRE		BIT(24)
67 #define RCC_DCKCFGRX_CK48MSEL		BIT(27)
68 #define RCC_DCKCFGRX_SDMMC1SEL		BIT(28)
69 #define RCC_DCKCFGR2_SDMMC2SEL		BIT(29)
70 
71 /*
72  * RCC AHB1ENR specific definitions
73  */
74 #define RCC_AHB1ENR_ETHMAC_EN		BIT(25)
75 #define RCC_AHB1ENR_ETHMAC_TX_EN	BIT(26)
76 #define RCC_AHB1ENR_ETHMAC_RX_EN	BIT(27)
77 
78 /*
79  * RCC APB1ENR specific definitions
80  */
81 #define RCC_APB1ENR_TIM2EN		BIT(0)
82 #define RCC_APB1ENR_PWREN		BIT(28)
83 
84 /*
85  * RCC APB2ENR specific definitions
86  */
87 #define RCC_APB2ENR_SYSCFGEN		BIT(14)
88 #define RCC_APB2ENR_SAI1EN		BIT(22)
89 
90 static const struct stm32_clk_info stm32f4_clk_info = {
91 	/* 180 MHz */
92 	.sys_pll_psc = {
93 		.pll_n = 360,
94 		.pll_p = 2,
95 		.pll_q = 8,
96 		.ahb_psc = AHB_PSC_1,
97 		.apb1_psc = APB_PSC_4,
98 		.apb2_psc = APB_PSC_2,
99 	},
100 	.has_overdrive = false,
101 	.v2 = false,
102 };
103 
104 static const struct stm32_clk_info stm32f7_clk_info = {
105 	/* 200 MHz */
106 	.sys_pll_psc = {
107 		.pll_n = 400,
108 		.pll_p = 2,
109 		.pll_q = 8,
110 		.ahb_psc = AHB_PSC_1,
111 		.apb1_psc = APB_PSC_4,
112 		.apb2_psc = APB_PSC_2,
113 	},
114 	.has_overdrive = true,
115 	.v2 = true,
116 };
117 
118 struct stm32_clk {
119 	struct stm32_rcc_regs *base;
120 	struct stm32_pwr_regs *pwr_regs;
121 	struct stm32_clk_info info;
122 	unsigned long hse_rate;
123 };
124 
125 static int configure_clocks(struct udevice *dev)
126 {
127 	struct stm32_clk *priv = dev_get_priv(dev);
128 	struct stm32_rcc_regs *regs = priv->base;
129 	struct stm32_pwr_regs *pwr = priv->pwr_regs;
130 	struct pll_psc *sys_pll_psc = &priv->info.sys_pll_psc;
131 	u32 pllsaicfgr = 0;
132 
133 	/* Reset RCC configuration */
134 	setbits_le32(&regs->cr, RCC_CR_HSION);
135 	writel(0, &regs->cfgr); /* Reset CFGR */
136 	clrbits_le32(&regs->cr, (RCC_CR_HSEON | RCC_CR_CSSON
137 		| RCC_CR_PLLON | RCC_CR_PLLSAION));
138 	writel(0x24003010, &regs->pllcfgr); /* Reset value from RM */
139 	clrbits_le32(&regs->cr, RCC_CR_HSEBYP);
140 	writel(0, &regs->cir); /* Disable all interrupts */
141 
142 	/* Configure for HSE+PLL operation */
143 	setbits_le32(&regs->cr, RCC_CR_HSEON);
144 	while (!(readl(&regs->cr) & RCC_CR_HSERDY))
145 		;
146 
147 	setbits_le32(&regs->cfgr, ((
148 		sys_pll_psc->ahb_psc << RCC_CFGR_HPRE_SHIFT)
149 		| (sys_pll_psc->apb1_psc << RCC_CFGR_PPRE1_SHIFT)
150 		| (sys_pll_psc->apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
151 
152 	/* Configure the main PLL */
153 	setbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLSRC); /* pll source HSE */
154 	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLM_MASK,
155 			sys_pll_psc->pll_m << RCC_PLLCFGR_PLLM_SHIFT);
156 	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLN_MASK,
157 			sys_pll_psc->pll_n << RCC_PLLCFGR_PLLN_SHIFT);
158 	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLP_MASK,
159 			((sys_pll_psc->pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT);
160 	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLQ_MASK,
161 			sys_pll_psc->pll_q << RCC_PLLCFGR_PLLQ_SHIFT);
162 
163 	/* Configure the SAI PLL to get a 48 MHz source */
164 	pllsaicfgr = RCC_PLLSAICFGR_PLLSAIR_2 | RCC_PLLSAICFGR_PLLSAIQ_4 |
165 		     RCC_PLLSAICFGR_PLLSAIP_4;
166 	pllsaicfgr |= 192 << RCC_PLLSAICFGR_PLLSAIN_SHIFT;
167 	writel(pllsaicfgr, &regs->pllsaicfgr);
168 
169 	/* Enable the main PLL */
170 	setbits_le32(&regs->cr, RCC_CR_PLLON);
171 	while (!(readl(&regs->cr) & RCC_CR_PLLRDY))
172 		;
173 
174 	if (priv->info.v2) { /*stm32f7 case */
175 		/* select PLLSAI as 48MHz clock source */
176 		setbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
177 
178 		/* select 48MHz as SDMMC1 clock source */
179 		clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_SDMMC1SEL);
180 
181 		/* select 48MHz as SDMMC2 clock source */
182 		clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGR2_SDMMC2SEL);
183 	} else  { /* stm32f4 case */
184 		/* select PLLSAI as 48MHz clock source */
185 		setbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
186 
187 		/* select 48MHz as SDMMC1 clock source */
188 		clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_SDMMC1SEL);
189 	}
190 
191 	/* Enable the SAI PLL */
192 	setbits_le32(&regs->cr, RCC_CR_PLLSAION);
193 	while (!(readl(&regs->cr) & RCC_CR_PLLSAIRDY))
194 		;
195 
196 	setbits_le32(&regs->apb1enr, RCC_APB1ENR_PWREN);
197 
198 	if (priv->info.has_overdrive) {
199 		/*
200 		 * Enable high performance mode
201 		 * System frequency up to 200 MHz
202 		 */
203 		setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
204 		/* Infinite wait! */
205 		while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY))
206 			;
207 		/* Enable the Over-drive switch */
208 		setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN);
209 		/* Infinite wait! */
210 		while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY))
211 			;
212 	}
213 
214 	stm32_flash_latency_cfg(5);
215 	clrbits_le32(&regs->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
216 	setbits_le32(&regs->cfgr, RCC_CFGR_SW_PLL);
217 
218 	while ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) !=
219 			RCC_CFGR_SWS_PLL)
220 		;
221 	/* gate the SAI clock, needed for MMC 1&2 clocks */
222 	setbits_le32(&regs->apb2enr, RCC_APB2ENR_SAI1EN);
223 
224 #ifdef CONFIG_ETH_DESIGNWARE
225 	/* gate the SYSCFG clock, needed to set RMII ethernet interface */
226 	setbits_le32(&regs->apb2enr, RCC_APB2ENR_SYSCFGEN);
227 #endif
228 
229 	return 0;
230 }
231 
232 static unsigned long stm32_clk_pll48clk_rate(struct stm32_clk *priv,
233 					     u32 sysclk)
234 {
235 	struct stm32_rcc_regs *regs = priv->base;
236 	u16 pllq, pllm, pllsain, pllsaip;
237 	bool pllsai;
238 
239 	pllq = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLQ_MASK)
240 	       >> RCC_PLLCFGR_PLLQ_SHIFT;
241 
242 	if (priv->info.v2) /*stm32f7 case */
243 		pllsai = readl(&regs->dckcfgr2) & RCC_DCKCFGRX_CK48MSEL;
244 	else
245 		pllsai = readl(&regs->dckcfgr) & RCC_DCKCFGRX_CK48MSEL;
246 
247 	if (pllsai) {
248 		/* PLL48CLK is selected from PLLSAI, get PLLSAI value */
249 		pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
250 		pllsain = ((readl(&regs->pllsaicfgr) & RCC_PLLCFGR_PLLSAIN_MASK)
251 			>> RCC_PLLSAICFGR_PLLSAIN_SHIFT);
252 		pllsaip = ((((readl(&regs->pllsaicfgr) & RCC_PLLCFGR_PLLSAIP_MASK)
253 			>> RCC_PLLSAICFGR_PLLSAIP_SHIFT) + 1) << 1);
254 		return ((priv->hse_rate / pllm) * pllsain) / pllsaip;
255 	}
256 	/* PLL48CLK is selected from PLLQ */
257 	return sysclk / pllq;
258 }
259 
260 static bool stm32_get_timpre(struct stm32_clk *priv)
261 {
262 	struct stm32_rcc_regs *regs = priv->base;
263 	u32 val;
264 
265 	if (priv->info.v2) /*stm32f7 case */
266 		val = readl(&regs->dckcfgr2);
267 	else
268 		val = readl(&regs->dckcfgr);
269 	/* get timer prescaler */
270 	return !!(val & RCC_DCKCFGRX_TIMPRE);
271 }
272 
273 static u32 stm32_get_hclk_rate(struct stm32_rcc_regs *regs, u32 sysclk)
274 {
275 	u8 shift;
276 	/* Prescaler table lookups for clock computation */
277 	u8 ahb_psc_table[16] = {
278 		0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
279 	};
280 
281 	shift = ahb_psc_table[(
282 		(readl(&regs->cfgr) & RCC_CFGR_AHB_PSC_MASK)
283 		>> RCC_CFGR_HPRE_SHIFT)];
284 
285 	return sysclk >> shift;
286 };
287 
288 static u8 stm32_get_apb_shift(struct stm32_rcc_regs *regs, enum apb apb)
289 {
290 	/* Prescaler table lookups for clock computation */
291 	u8 apb_psc_table[8] = {
292 		0, 0, 0, 0, 1, 2, 3, 4
293 	};
294 
295 	if (apb == APB1)
296 		return apb_psc_table[(
297 		       (readl(&regs->cfgr) & RCC_CFGR_APB1_PSC_MASK)
298 		       >> RCC_CFGR_PPRE1_SHIFT)];
299 	else /* APB2 */
300 		return apb_psc_table[(
301 		       (readl(&regs->cfgr) & RCC_CFGR_APB2_PSC_MASK)
302 		       >> RCC_CFGR_PPRE2_SHIFT)];
303 };
304 
305 static u32 stm32_get_timer_rate(struct stm32_clk *priv, u32 sysclk,
306 				enum apb apb)
307 {
308 	struct stm32_rcc_regs *regs = priv->base;
309 	u8 shift = stm32_get_apb_shift(regs, apb);
310 
311 	if (stm32_get_timpre(priv))
312 		/*
313 		 * if APB prescaler is configured to a
314 		 * division factor of 1, 2 or 4
315 		 */
316 		switch (shift) {
317 		case 0:
318 		case 1:
319 		case 2:
320 			return stm32_get_hclk_rate(regs, sysclk);
321 		default:
322 			return (sysclk >> shift) * 4;
323 		}
324 	else
325 		/*
326 		 * if APB prescaler is configured to a
327 		 * division factor of 1
328 		 */
329 		if (shift == 0)
330 			return sysclk;
331 		else
332 			return (sysclk >> shift) * 2;
333 };
334 
335 static ulong stm32_clk_get_rate(struct clk *clk)
336 {
337 	struct stm32_clk *priv = dev_get_priv(clk->dev);
338 	struct stm32_rcc_regs *regs = priv->base;
339 	u32 sysclk = 0;
340 	u16 pllm, plln, pllp;
341 
342 	if ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) ==
343 			RCC_CFGR_SWS_PLL) {
344 		pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
345 		plln = ((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
346 			>> RCC_PLLCFGR_PLLN_SHIFT);
347 		pllp = ((((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
348 			>> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
349 		sysclk = ((priv->hse_rate / pllm) * plln) / pllp;
350 	} else {
351 		return -EINVAL;
352 	}
353 
354 	switch (clk->id) {
355 	/*
356 	 * AHB CLOCK: 3 x 32 bits consecutive registers are used :
357 	 * AHB1, AHB2 and AHB3
358 	 */
359 	case STM32F7_AHB1_CLOCK(GPIOA) ... STM32F7_AHB3_CLOCK(QSPI):
360 		return stm32_get_hclk_rate(regs, sysclk);
361 	/* APB1 CLOCK */
362 	case STM32F7_APB1_CLOCK(TIM2) ... STM32F7_APB1_CLOCK(UART8):
363 		/* For timer clock, an additionnal prescaler is used*/
364 		switch (clk->id) {
365 		case STM32F7_APB1_CLOCK(TIM2):
366 		case STM32F7_APB1_CLOCK(TIM3):
367 		case STM32F7_APB1_CLOCK(TIM4):
368 		case STM32F7_APB1_CLOCK(TIM5):
369 		case STM32F7_APB1_CLOCK(TIM6):
370 		case STM32F7_APB1_CLOCK(TIM7):
371 		case STM32F7_APB1_CLOCK(TIM12):
372 		case STM32F7_APB1_CLOCK(TIM13):
373 		case STM32F7_APB1_CLOCK(TIM14):
374 			return stm32_get_timer_rate(priv, sysclk, APB1);
375 		}
376 		return (sysclk >> stm32_get_apb_shift(regs, APB1));
377 
378 	/* APB2 CLOCK */
379 	case STM32F7_APB2_CLOCK(TIM1) ... STM32F7_APB2_CLOCK(LTDC):
380 		/*
381 		 * particular case for SDMMC1 and SDMMC2 :
382 		 * 48Mhz source clock can be from main PLL or from
383 		 * SAI PLL
384 		 */
385 		switch (clk->id) {
386 		case STM32F7_APB2_CLOCK(SDMMC1):
387 			if (readl(&regs->dckcfgr2) & RCC_DCKCFGRX_SDMMC1SEL)
388 				/* System clock is selected as SDMMC1 clock */
389 				return sysclk;
390 			else
391 				return stm32_clk_pll48clk_rate(priv, sysclk);
392 			break;
393 		case STM32F7_APB2_CLOCK(SDMMC2):
394 			if (readl(&regs->dckcfgr2) & RCC_DCKCFGR2_SDMMC2SEL)
395 				/* System clock is selected as SDMMC2 clock */
396 				return sysclk;
397 			else
398 				return stm32_clk_pll48clk_rate(priv, sysclk);
399 			break;
400 
401 		/* For timer clock, an additionnal prescaler is used*/
402 		case STM32F7_APB2_CLOCK(TIM1):
403 		case STM32F7_APB2_CLOCK(TIM8):
404 		case STM32F7_APB2_CLOCK(TIM9):
405 		case STM32F7_APB2_CLOCK(TIM10):
406 		case STM32F7_APB2_CLOCK(TIM11):
407 			return stm32_get_timer_rate(priv, sysclk, APB2);
408 		break;
409 		}
410 		return (sysclk >> stm32_get_apb_shift(regs, APB2));
411 
412 	default:
413 		pr_err("clock index %ld out of range\n", clk->id);
414 		return -EINVAL;
415 	}
416 }
417 
418 static ulong stm32_set_rate(struct clk *clk, ulong rate)
419 {
420 	return 0;
421 }
422 
423 static int stm32_clk_enable(struct clk *clk)
424 {
425 	struct stm32_clk *priv = dev_get_priv(clk->dev);
426 	struct stm32_rcc_regs *regs = priv->base;
427 	u32 offset = clk->id / 32;
428 	u32 bit_index = clk->id % 32;
429 
430 	debug("%s: clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n",
431 	      __func__, clk->id, offset, bit_index);
432 	setbits_le32(&regs->ahb1enr + offset, BIT(bit_index));
433 
434 	return 0;
435 }
436 
437 static int stm32_clk_probe(struct udevice *dev)
438 {
439 	struct ofnode_phandle_args args;
440 	struct udevice *fixed_clock_dev = NULL;
441 	struct clk clk;
442 	int err;
443 
444 	debug("%s\n", __func__);
445 
446 	struct stm32_clk *priv = dev_get_priv(dev);
447 	fdt_addr_t addr;
448 
449 	addr = dev_read_addr(dev);
450 	if (addr == FDT_ADDR_T_NONE)
451 		return -EINVAL;
452 
453 	priv->base = (struct stm32_rcc_regs *)addr;
454 
455 	switch (dev_get_driver_data(dev)) {
456 	case STM32F4:
457 		memcpy(&priv->info, &stm32f4_clk_info,
458 		       sizeof(struct stm32_clk_info));
459 		break;
460 	case STM32F7:
461 		memcpy(&priv->info, &stm32f7_clk_info,
462 		       sizeof(struct stm32_clk_info));
463 		break;
464 	default:
465 		return -EINVAL;
466 	}
467 
468 	/* retrieve HSE frequency (external oscillator) */
469 	err = uclass_get_device_by_name(UCLASS_CLK, "clk-hse",
470 					&fixed_clock_dev);
471 
472 	if (err) {
473 		pr_err("Can't find fixed clock (%d)", err);
474 		return err;
475 	}
476 
477 	err = clk_request(fixed_clock_dev, &clk);
478 	if (err) {
479 		pr_err("Can't request %s clk (%d)", fixed_clock_dev->name,
480 		       err);
481 		return err;
482 	}
483 
484 	/*
485 	 * set pllm factor accordingly to the external oscillator
486 	 * frequency (HSE). For STM32F4 and STM32F7, we want VCO
487 	 * freq at 1MHz
488 	 * if input PLL frequency is 25Mhz, divide it by 25
489 	 */
490 	clk.id = 0;
491 	priv->hse_rate = clk_get_rate(&clk);
492 
493 	if (priv->hse_rate < 1000000) {
494 		pr_err("%s: unexpected HSE clock rate = %ld \"n", __func__,
495 		       priv->hse_rate);
496 		return -EINVAL;
497 	}
498 
499 	priv->info.sys_pll_psc.pll_m = priv->hse_rate / 1000000;
500 
501 	if (priv->info.has_overdrive) {
502 		err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
503 						 &args);
504 		if (err) {
505 			debug("%s: can't find syscon device (%d)\n", __func__,
506 			      err);
507 			return err;
508 		}
509 
510 		priv->pwr_regs = (struct stm32_pwr_regs *)ofnode_get_addr(args.node);
511 	}
512 
513 	configure_clocks(dev);
514 
515 	return 0;
516 }
517 
518 static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
519 {
520 	debug("%s(clk=%p)\n", __func__, clk);
521 
522 	if (args->args_count != 2) {
523 		debug("Invaild args_count: %d\n", args->args_count);
524 		return -EINVAL;
525 	}
526 
527 	if (args->args_count)
528 		clk->id = args->args[1];
529 	else
530 		clk->id = 0;
531 
532 	return 0;
533 }
534 
535 static struct clk_ops stm32_clk_ops = {
536 	.of_xlate	= stm32_clk_of_xlate,
537 	.enable		= stm32_clk_enable,
538 	.get_rate	= stm32_clk_get_rate,
539 	.set_rate	= stm32_set_rate,
540 };
541 
542 U_BOOT_DRIVER(stm32fx_clk) = {
543 	.name			= "stm32fx_rcc_clock",
544 	.id			= UCLASS_CLK,
545 	.ops			= &stm32_clk_ops,
546 	.probe			= stm32_clk_probe,
547 	.priv_auto_alloc_size	= sizeof(struct stm32_clk),
548 	.flags			= DM_FLAG_PRE_RELOC,
549 };
550