2 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
3 * Author(s): Patrice Chotard, <patrice.chotard@st.com> for STMicroelectronics.
5 * SPDX-License-Identifier: GPL-2.0+
9 #include <clk-uclass.h>
16 #include <dt-bindings/clock/stm32h7-clks.h>
18 DECLARE_GLOBAL_DATA_PTR
;
20 /* RCC CR specific definitions */
21 #define RCC_CR_HSION BIT(0)
22 #define RCC_CR_HSIRDY BIT(2)
24 #define RCC_CR_HSEON BIT(16)
25 #define RCC_CR_HSERDY BIT(17)
26 #define RCC_CR_HSEBYP BIT(18)
27 #define RCC_CR_PLL1ON BIT(24)
28 #define RCC_CR_PLL1RDY BIT(25)
30 #define RCC_CR_HSIDIV_MASK GENMASK(4, 3)
31 #define RCC_CR_HSIDIV_SHIFT 3
33 #define RCC_CFGR_SW_MASK GENMASK(2, 0)
34 #define RCC_CFGR_SW_HSI 0
35 #define RCC_CFGR_SW_CSI 1
36 #define RCC_CFGR_SW_HSE 2
37 #define RCC_CFGR_SW_PLL1 3
39 #define RCC_PLLCKSELR_PLLSRC_HSI 0
40 #define RCC_PLLCKSELR_PLLSRC_CSI 1
41 #define RCC_PLLCKSELR_PLLSRC_HSE 2
42 #define RCC_PLLCKSELR_PLLSRC_NO_CLK 3
44 #define RCC_PLLCKSELR_PLLSRC_MASK GENMASK(1, 0)
46 #define RCC_PLLCKSELR_DIVM1_SHIFT 4
47 #define RCC_PLLCKSELR_DIVM1_MASK GENMASK(9, 4)
49 #define RCC_PLL1DIVR_DIVN1_MASK GENMASK(8, 0)
51 #define RCC_PLL1DIVR_DIVP1_SHIFT 9
52 #define RCC_PLL1DIVR_DIVP1_MASK GENMASK(15, 9)
54 #define RCC_PLL1DIVR_DIVQ1_SHIFT 16
55 #define RCC_PLL1DIVR_DIVQ1_MASK GENMASK(22, 16)
57 #define RCC_PLL1DIVR_DIVR1_SHIFT 24
58 #define RCC_PLL1DIVR_DIVR1_MASK GENMASK(30, 24)
60 #define RCC_PLL1FRACR_FRACN1_SHIFT 3
61 #define RCC_PLL1FRACR_FRACN1_MASK GENMASK(15, 3)
63 #define RCC_PLLCFGR_PLL1RGE_SHIFT 2
64 #define PLL1RGE_1_2_MHZ 0
65 #define PLL1RGE_2_4_MHZ 1
66 #define PLL1RGE_4_8_MHZ 2
67 #define PLL1RGE_8_16_MHZ 3
68 #define RCC_PLLCFGR_DIVP1EN BIT(16)
69 #define RCC_PLLCFGR_DIVQ1EN BIT(17)
70 #define RCC_PLLCFGR_DIVR1EN BIT(18)
72 #define RCC_D1CFGR_HPRE_MASK GENMASK(3, 0)
73 #define RCC_D1CFGR_HPRE_DIVIDED BIT(3)
74 #define RCC_D1CFGR_HPRE_DIVIDER GENMASK(2, 0)
76 #define RCC_D1CFGR_HPRE_DIV2 8
78 #define RCC_D1CFGR_D1PPRE_SHIFT 4
79 #define RCC_D1CFGR_D1PPRE_DIVIDED BIT(6)
80 #define RCC_D1CFGR_D1PPRE_DIVIDER GENMASK(5, 4)
82 #define RCC_D1CFGR_D1CPRE_SHIFT 8
83 #define RCC_D1CFGR_D1CPRE_DIVIDER GENMASK(10, 8)
84 #define RCC_D1CFGR_D1CPRE_DIVIDED BIT(11)
86 #define RCC_D2CFGR_D2PPRE1_SHIFT 4
87 #define RCC_D2CFGR_D2PPRE1_DIVIDED BIT(6)
88 #define RCC_D2CFGR_D2PPRE1_DIVIDER GENMASK(5, 4)
90 #define RCC_D2CFGR_D2PPRE2_SHIFT 8
91 #define RCC_D2CFGR_D2PPRE2_DIVIDED BIT(10)
92 #define RCC_D2CFGR_D2PPRE2_DIVIDER GENMASK(9, 8)
94 #define RCC_D3CFGR_D3PPRE_SHIFT 4
95 #define RCC_D3CFGR_D3PPRE_DIVIDED BIT(6)
96 #define RCC_D3CFGR_D3PPRE_DIVIDER GENMASK(5, 4)
98 #define RCC_D1CCIPR_FMCSRC_MASK GENMASK(1, 0)
99 #define FMCSRC_HCLKD1 0
100 #define FMCSRC_PLL1_Q_CK 1
101 #define FMCSRC_PLL2_R_CK 2
102 #define FMCSRC_PER_CK 3
104 #define RCC_D1CCIPR_QSPISRC_MASK GENMASK(5, 4)
105 #define RCC_D1CCIPR_QSPISRC_SHIFT 4
106 #define QSPISRC_HCLKD1 0
107 #define QSPISRC_PLL1_Q_CK 1
108 #define QSPISRC_PLL2_R_CK 2
109 #define QSPISRC_PER_CK 3
112 #define PWR_CR3_SCUEN BIT(2)
113 #define PWR_D3CR 0x18
114 #define PWR_D3CR_VOS_MASK GENMASK(15, 14)
115 #define PWR_D3CR_VOS_SHIFT 14
116 #define VOS_SCALE_3 1
117 #define VOS_SCALE_2 2
118 #define VOS_SCALE_1 3
119 #define PWR_D3CR_VOSREADY BIT(13)
121 struct stm32_rcc_regs
{
122 u32 cr
; /* 0x00 Source Control Register */
123 u32 icscr
; /* 0x04 Internal Clock Source Calibration Register */
124 u32 crrcr
; /* 0x08 Clock Recovery RC Register */
125 u32 reserved1
; /* 0x0c reserved */
126 u32 cfgr
; /* 0x10 Clock Configuration Register */
127 u32 reserved2
; /* 0x14 reserved */
128 u32 d1cfgr
; /* 0x18 Domain 1 Clock Configuration Register */
129 u32 d2cfgr
; /* 0x1c Domain 2 Clock Configuration Register */
130 u32 d3cfgr
; /* 0x20 Domain 3 Clock Configuration Register */
131 u32 reserved3
; /* 0x24 reserved */
132 u32 pllckselr
; /* 0x28 PLLs Clock Source Selection Register */
133 u32 pllcfgr
; /* 0x2c PLLs Configuration Register */
134 u32 pll1divr
; /* 0x30 PLL1 Dividers Configuration Register */
135 u32 pll1fracr
; /* 0x34 PLL1 Fractional Divider Register */
136 u32 pll2divr
; /* 0x38 PLL2 Dividers Configuration Register */
137 u32 pll2fracr
; /* 0x3c PLL2 Fractional Divider Register */
138 u32 pll3divr
; /* 0x40 PLL3 Dividers Configuration Register */
139 u32 pll3fracr
; /* 0x44 PLL3 Fractional Divider Register */
140 u32 reserved4
; /* 0x48 reserved */
141 u32 d1ccipr
; /* 0x4c Domain 1 Kernel Clock Configuration Register */
142 u32 d2ccip1r
; /* 0x50 Domain 2 Kernel Clock Configuration Register */
143 u32 d2ccip2r
; /* 0x54 Domain 2 Kernel Clock Configuration Register */
144 u32 d3ccipr
; /* 0x58 Domain 3 Kernel Clock Configuration Register */
145 u32 reserved5
; /* 0x5c reserved */
146 u32 cier
; /* 0x60 Clock Source Interrupt Enable Register */
147 u32 cifr
; /* 0x64 Clock Source Interrupt Flag Register */
148 u32 cicr
; /* 0x68 Clock Source Interrupt Clear Register */
149 u32 reserved6
; /* 0x6c reserved */
150 u32 bdcr
; /* 0x70 Backup Domain Control Register */
151 u32 csr
; /* 0x74 Clock Control and Status Register */
152 u32 reserved7
; /* 0x78 reserved */
154 u32 ahb3rstr
; /* 0x7c AHB3 Peripheral Reset Register */
155 u32 ahb1rstr
; /* 0x80 AHB1 Peripheral Reset Register */
156 u32 ahb2rstr
; /* 0x84 AHB2 Peripheral Reset Register */
157 u32 ahb4rstr
; /* 0x88 AHB4 Peripheral Reset Register */
159 u32 apb3rstr
; /* 0x8c APB3 Peripheral Reset Register */
160 u32 apb1lrstr
; /* 0x90 APB1 low Peripheral Reset Register */
161 u32 apb1hrstr
; /* 0x94 APB1 high Peripheral Reset Register */
162 u32 apb2rstr
; /* 0x98 APB2 Clock Register */
163 u32 apb4rstr
; /* 0x9c APB4 Clock Register */
165 u32 gcr
; /* 0xa0 Global Control Register */
166 u32 reserved8
; /* 0xa4 reserved */
167 u32 d3amr
; /* 0xa8 D3 Autonomous mode Register */
168 u32 reserved9
[9];/* 0xac to 0xcc reserved */
169 u32 rsr
; /* 0xd0 Reset Status Register */
170 u32 ahb3enr
; /* 0xd4 AHB3 Clock Register */
171 u32 ahb1enr
; /* 0xd8 AHB1 Clock Register */
172 u32 ahb2enr
; /* 0xdc AHB2 Clock Register */
173 u32 ahb4enr
; /* 0xe0 AHB4 Clock Register */
175 u32 apb3enr
; /* 0xe4 APB3 Clock Register */
176 u32 apb1lenr
; /* 0xe8 APB1 low Clock Register */
177 u32 apb1henr
; /* 0xec APB1 high Clock Register */
178 u32 apb2enr
; /* 0xf0 APB2 Clock Register */
179 u32 apb4enr
; /* 0xf4 APB4 Clock Register */
182 #define RCC_AHB3ENR offsetof(struct stm32_rcc_regs, ahb3enr)
183 #define RCC_AHB1ENR offsetof(struct stm32_rcc_regs, ahb1enr)
184 #define RCC_AHB2ENR offsetof(struct stm32_rcc_regs, ahb2enr)
185 #define RCC_AHB4ENR offsetof(struct stm32_rcc_regs, ahb4enr)
186 #define RCC_APB3ENR offsetof(struct stm32_rcc_regs, apb3enr)
187 #define RCC_APB1LENR offsetof(struct stm32_rcc_regs, apb1lenr)
188 #define RCC_APB1HENR offsetof(struct stm32_rcc_regs, apb1henr)
189 #define RCC_APB2ENR offsetof(struct stm32_rcc_regs, apb2enr)
190 #define RCC_APB4ENR offsetof(struct stm32_rcc_regs, apb4enr)
199 * the way all these entries are sorted in this array could seem
200 * unlogical, but we are dependant of kernel DT_bindings,
201 * where clocks are separate in 2 banks, peripheral clocks and
205 static const struct clk_cfg clk_map
[] = {
206 {RCC_AHB3ENR
, 31, "d1sram1"}, /* peripheral clocks */
207 {RCC_AHB3ENR
, 30, "itcm"},
208 {RCC_AHB3ENR
, 29, "dtcm2"},
209 {RCC_AHB3ENR
, 28, "dtcm1"},
210 {RCC_AHB3ENR
, 8, "flitf"},
211 {RCC_AHB3ENR
, 5, "jpgdec"},
212 {RCC_AHB3ENR
, 4, "dma2d"},
213 {RCC_AHB3ENR
, 0, "mdma"},
214 {RCC_AHB1ENR
, 28, "usb2ulpi"},
215 {RCC_AHB1ENR
, 17, "eth1rx"},
216 {RCC_AHB1ENR
, 16, "eth1tx"},
217 {RCC_AHB1ENR
, 15, "eth1mac"},
218 {RCC_AHB1ENR
, 14, "art"},
219 {RCC_AHB1ENR
, 26, "usb1ulpi"},
220 {RCC_AHB1ENR
, 1, "dma2"},
221 {RCC_AHB1ENR
, 0, "dma1"},
222 {RCC_AHB2ENR
, 31, "d2sram3"},
223 {RCC_AHB2ENR
, 30, "d2sram2"},
224 {RCC_AHB2ENR
, 29, "d2sram1"},
225 {RCC_AHB2ENR
, 5, "hash"},
226 {RCC_AHB2ENR
, 4, "crypt"},
227 {RCC_AHB2ENR
, 0, "camitf"},
228 {RCC_AHB4ENR
, 28, "bkpram"},
229 {RCC_AHB4ENR
, 25, "hsem"},
230 {RCC_AHB4ENR
, 21, "bdma"},
231 {RCC_AHB4ENR
, 19, "crc"},
232 {RCC_AHB4ENR
, 10, "gpiok"},
233 {RCC_AHB4ENR
, 9, "gpioj"},
234 {RCC_AHB4ENR
, 8, "gpioi"},
235 {RCC_AHB4ENR
, 7, "gpioh"},
236 {RCC_AHB4ENR
, 6, "gpiog"},
237 {RCC_AHB4ENR
, 5, "gpiof"},
238 {RCC_AHB4ENR
, 4, "gpioe"},
239 {RCC_AHB4ENR
, 3, "gpiod"},
240 {RCC_AHB4ENR
, 2, "gpioc"},
241 {RCC_AHB4ENR
, 1, "gpiob"},
242 {RCC_AHB4ENR
, 0, "gpioa"},
243 {RCC_APB3ENR
, 6, "wwdg1"},
244 {RCC_APB1LENR
, 29, "dac12"},
245 {RCC_APB1LENR
, 11, "wwdg2"},
246 {RCC_APB1LENR
, 8, "tim14"},
247 {RCC_APB1LENR
, 7, "tim13"},
248 {RCC_APB1LENR
, 6, "tim12"},
249 {RCC_APB1LENR
, 5, "tim7"},
250 {RCC_APB1LENR
, 4, "tim6"},
251 {RCC_APB1LENR
, 3, "tim5"},
252 {RCC_APB1LENR
, 2, "tim4"},
253 {RCC_APB1LENR
, 1, "tim3"},
254 {RCC_APB1LENR
, 0, "tim2"},
255 {RCC_APB1HENR
, 5, "mdios"},
256 {RCC_APB1HENR
, 4, "opamp"},
257 {RCC_APB1HENR
, 1, "crs"},
258 {RCC_APB2ENR
, 18, "tim17"},
259 {RCC_APB2ENR
, 17, "tim16"},
260 {RCC_APB2ENR
, 16, "tim15"},
261 {RCC_APB2ENR
, 1, "tim8"},
262 {RCC_APB2ENR
, 0, "tim1"},
263 {RCC_APB4ENR
, 26, "tmpsens"},
264 {RCC_APB4ENR
, 16, "rtcapb"},
265 {RCC_APB4ENR
, 15, "vref"},
266 {RCC_APB4ENR
, 14, "comp12"},
267 {RCC_APB4ENR
, 1, "syscfg"},
268 {RCC_AHB3ENR
, 16, "sdmmc1"}, /* kernel clocks */
269 {RCC_AHB3ENR
, 14, "quadspi"},
270 {RCC_AHB3ENR
, 12, "fmc"},
271 {RCC_AHB1ENR
, 27, "usb2otg"},
272 {RCC_AHB1ENR
, 25, "usb1otg"},
273 {RCC_AHB1ENR
, 5, "adc12"},
274 {RCC_AHB2ENR
, 9, "sdmmc2"},
275 {RCC_AHB2ENR
, 6, "rng"},
276 {RCC_AHB4ENR
, 24, "adc3"},
277 {RCC_APB3ENR
, 4, "dsi"},
278 {RCC_APB3ENR
, 3, "ltdc"},
279 {RCC_APB1LENR
, 31, "usart8"},
280 {RCC_APB1LENR
, 30, "usart7"},
281 {RCC_APB1LENR
, 27, "hdmicec"},
282 {RCC_APB1LENR
, 23, "i2c3"},
283 {RCC_APB1LENR
, 22, "i2c2"},
284 {RCC_APB1LENR
, 21, "i2c1"},
285 {RCC_APB1LENR
, 20, "uart5"},
286 {RCC_APB1LENR
, 19, "uart4"},
287 {RCC_APB1LENR
, 18, "usart3"},
288 {RCC_APB1LENR
, 17, "usart2"},
289 {RCC_APB1LENR
, 16, "spdifrx"},
290 {RCC_APB1LENR
, 15, "spi3"},
291 {RCC_APB1LENR
, 14, "spi2"},
292 {RCC_APB1LENR
, 9, "lptim1"},
293 {RCC_APB1HENR
, 8, "fdcan"},
294 {RCC_APB1HENR
, 2, "swp"},
295 {RCC_APB2ENR
, 29, "hrtim"},
296 {RCC_APB2ENR
, 28, "dfsdm1"},
297 {RCC_APB2ENR
, 24, "sai3"},
298 {RCC_APB2ENR
, 23, "sai2"},
299 {RCC_APB2ENR
, 22, "sai1"},
300 {RCC_APB2ENR
, 20, "spi5"},
301 {RCC_APB2ENR
, 13, "spi4"},
302 {RCC_APB2ENR
, 12, "spi1"},
303 {RCC_APB2ENR
, 5, "usart6"},
304 {RCC_APB2ENR
, 4, "usart1"},
305 {RCC_APB4ENR
, 21, "sai4a"},
306 {RCC_APB4ENR
, 21, "sai4b"},
307 {RCC_APB4ENR
, 12, "lptim5"},
308 {RCC_APB4ENR
, 11, "lptim4"},
309 {RCC_APB4ENR
, 10, "lptim3"},
310 {RCC_APB4ENR
, 9, "lptim2"},
311 {RCC_APB4ENR
, 7, "i2c4"},
312 {RCC_APB4ENR
, 5, "spi6"},
313 {RCC_APB4ENR
, 3, "lpuart1"},
317 struct stm32_rcc_regs
*rcc_base
;
318 struct regmap
*pwr_regmap
;
332 * pll1_p = 250MHz / pll1_q = 250MHz pll1_r = 250Mhz
334 struct pll_psc sys_pll_psc
= {
342 int configure_clocks(struct udevice
*dev
)
344 struct stm32_clk
*priv
= dev_get_priv(dev
);
345 struct stm32_rcc_regs
*regs
= priv
->rcc_base
;
346 uint8_t *pwr_base
= (uint8_t *)regmap_get_range(priv
->pwr_regmap
, 0);
347 uint32_t pllckselr
= 0;
348 uint32_t pll1divr
= 0;
349 uint32_t pllcfgr
= 0;
352 setbits_le32(®s
->cr
, RCC_CR_HSION
);
353 while (!(readl(®s
->cr
) & RCC_CR_HSIRDY
))
356 /* Reset CFGR, now HSI is the default system clock */
357 writel(0, ®s
->cfgr
);
359 /* Set all kernel domain clock registers to reset value*/
360 writel(0x0, ®s
->d1ccipr
);
361 writel(0x0, ®s
->d2ccip1r
);
362 writel(0x0, ®s
->d2ccip2r
);
364 /* Set voltage scaling at scale 1 (1,15 - 1,26 Volts) */
365 clrsetbits_le32(pwr_base
+ PWR_D3CR
, PWR_D3CR_VOS_MASK
,
366 VOS_SCALE_1
<< PWR_D3CR_VOS_SHIFT
);
367 /* Lock supply configuration update */
368 clrbits_le32(pwr_base
+ PWR_CR3
, PWR_CR3_SCUEN
);
369 while (!(readl(pwr_base
+ PWR_D3CR
) & PWR_D3CR_VOSREADY
))
372 /* disable HSE to configure it */
373 clrbits_le32(®s
->cr
, RCC_CR_HSEON
);
374 while ((readl(®s
->cr
) & RCC_CR_HSERDY
))
377 /* clear HSE bypass and set it ON */
378 clrbits_le32(®s
->cr
, RCC_CR_HSEBYP
);
380 setbits_le32(®s
->cr
, RCC_CR_HSEON
);
381 while (!(readl(®s
->cr
) & RCC_CR_HSERDY
))
384 /* pll setup, disable it */
385 clrbits_le32(®s
->cr
, RCC_CR_PLL1ON
);
386 while ((readl(®s
->cr
) & RCC_CR_PLL1RDY
))
389 /* Select HSE as PLL clock source */
390 pllckselr
|= RCC_PLLCKSELR_PLLSRC_HSE
;
391 pllckselr
|= sys_pll_psc
.divm
<< RCC_PLLCKSELR_DIVM1_SHIFT
;
392 writel(pllckselr
, ®s
->pllckselr
);
394 pll1divr
|= (sys_pll_psc
.divr
- 1) << RCC_PLL1DIVR_DIVR1_SHIFT
;
395 pll1divr
|= (sys_pll_psc
.divq
- 1) << RCC_PLL1DIVR_DIVQ1_SHIFT
;
396 pll1divr
|= (sys_pll_psc
.divp
- 1) << RCC_PLL1DIVR_DIVP1_SHIFT
;
397 pll1divr
|= (sys_pll_psc
.divn
- 1);
398 writel(pll1divr
, ®s
->pll1divr
);
400 pllcfgr
|= PLL1RGE_4_8_MHZ
<< RCC_PLLCFGR_PLL1RGE_SHIFT
;
401 pllcfgr
|= RCC_PLLCFGR_DIVP1EN
;
402 pllcfgr
|= RCC_PLLCFGR_DIVQ1EN
;
403 pllcfgr
|= RCC_PLLCFGR_DIVR1EN
;
404 writel(pllcfgr
, ®s
->pllcfgr
);
406 /* pll setup, enable it */
407 setbits_le32(®s
->cr
, RCC_CR_PLL1ON
);
409 /* set HPRE (/2) DI clk --> 125MHz */
410 clrsetbits_le32(®s
->d1cfgr
, RCC_D1CFGR_HPRE_MASK
,
411 RCC_D1CFGR_HPRE_DIV2
);
413 /* select PLL1 as system clock source (sys_ck)*/
414 clrsetbits_le32(®s
->cfgr
, RCC_CFGR_SW_MASK
, RCC_CFGR_SW_PLL1
);
415 while ((readl(®s
->cfgr
) & RCC_CFGR_SW_MASK
) != RCC_CFGR_SW_PLL1
)
418 /* sdram: use pll1_q as fmc_k clk */
419 clrsetbits_le32(®s
->d1ccipr
, RCC_D1CCIPR_FMCSRC_MASK
,
425 static u32
stm32_get_HSI_divider(struct stm32_rcc_regs
*regs
)
429 /* get HSI divider value */
430 divider
= readl(®s
->cr
) & RCC_CR_HSIDIV_MASK
;
431 divider
= divider
>> RCC_CR_HSIDIV_SHIFT
;
446 static const char * const pllsrc_name
[PLLSRC_NB
] = {
452 [TIMER
] = "timer-clk"
455 static ulong
stm32_get_rate(struct stm32_rcc_regs
*regs
, enum pllsrc pllsrc
)
458 struct udevice
*fixed_clock_dev
= NULL
;
461 const char *name
= pllsrc_name
[pllsrc
];
463 debug("%s name %s\n", __func__
, name
);
466 ret
= uclass_get_device_by_name(UCLASS_CLK
, name
, &fixed_clock_dev
);
468 pr_err("Can't find clk %s (%d)", name
, ret
);
472 ret
= clk_request(fixed_clock_dev
, &clk
);
474 pr_err("Can't request %s clk (%d)", name
, ret
);
480 divider
= stm32_get_HSI_divider(regs
);
482 debug("%s divider %d rate %ld\n", __func__
,
483 divider
, clk_get_rate(&clk
));
485 return clk_get_rate(&clk
) >> divider
;
494 static u32
stm32_get_PLL1_rate(struct stm32_rcc_regs
*regs
,
495 enum pll1_output output
)
498 u32 divm1
, divn1
, divp1
, divq1
, divr1
, fracn1
;
502 switch (readl(®s
->pllckselr
) & RCC_PLLCKSELR_PLLSRC_MASK
) {
503 case RCC_PLLCKSELR_PLLSRC_HSI
:
504 pllsrc
= stm32_get_rate(regs
, HSI
);
506 case RCC_PLLCKSELR_PLLSRC_CSI
:
507 pllsrc
= stm32_get_rate(regs
, CSI
);
509 case RCC_PLLCKSELR_PLLSRC_HSE
:
510 pllsrc
= stm32_get_rate(regs
, HSE
);
512 case RCC_PLLCKSELR_PLLSRC_NO_CLK
:
513 /* shouldn't happen */
514 pr_err("wrong value for RCC_PLLCKSELR register\n");
519 /* pllsrc = 0 ? no need to go ahead */
523 /* get divm1, divp1, divn1 and divr1 */
524 divm1
= readl(®s
->pllckselr
) & RCC_PLLCKSELR_DIVM1_MASK
;
525 divm1
= divm1
>> RCC_PLLCKSELR_DIVM1_SHIFT
;
527 divn1
= (readl(®s
->pll1divr
) & RCC_PLL1DIVR_DIVN1_MASK
) + 1;
529 divp1
= readl(®s
->pll1divr
) & RCC_PLL1DIVR_DIVP1_MASK
;
530 divp1
= (divp1
>> RCC_PLL1DIVR_DIVP1_SHIFT
) + 1;
532 divq1
= readl(®s
->pll1divr
) & RCC_PLL1DIVR_DIVQ1_MASK
;
533 divq1
= (divq1
>> RCC_PLL1DIVR_DIVQ1_SHIFT
) + 1;
535 divr1
= readl(®s
->pll1divr
) & RCC_PLL1DIVR_DIVR1_MASK
;
536 divr1
= (divr1
>> RCC_PLL1DIVR_DIVR1_SHIFT
) + 1;
538 fracn1
= readl(®s
->pll1fracr
) & RCC_PLL1DIVR_DIVR1_MASK
;
539 fracn1
= fracn1
& RCC_PLL1DIVR_DIVR1_SHIFT
;
541 vco
= (pllsrc
/ divm1
) * divn1
;
542 rate
= (pllsrc
* fracn1
) / (divm1
* 8192);
544 debug("%s divm1 = %d divn1 = %d divp1 = %d divq1 = %d divr1 = %d\n",
545 __func__
, divm1
, divn1
, divp1
, divq1
, divr1
);
546 debug("%s fracn1 = %d vco = %ld rate = %ld\n",
547 __func__
, fracn1
, vco
, rate
);
551 return (vco
+ rate
) / divp1
;
554 return (vco
+ rate
) / divq1
;
558 return (vco
+ rate
) / divr1
;
565 static ulong
stm32_clk_get_rate(struct clk
*clk
)
567 struct stm32_clk
*priv
= dev_get_priv(clk
->dev
);
568 struct stm32_rcc_regs
*regs
= priv
->rcc_base
;
572 /* prescaler table lookups for clock computation */
573 u16 prescaler_table
[8] = {2, 4, 8, 16, 64, 128, 256, 512};
577 * get system clock (sys_ck) source
578 * can be HSI_CK, CSI_CK, HSE_CK or pll1_p_ck
580 source
= readl(®s
->cfgr
) & RCC_CFGR_SW_MASK
;
582 case RCC_CFGR_SW_PLL1
:
583 sysclk
= stm32_get_PLL1_rate(regs
, PLL1_P_CK
);
585 case RCC_CFGR_SW_HSE
:
586 sysclk
= stm32_get_rate(regs
, HSE
);
589 case RCC_CFGR_SW_CSI
:
590 sysclk
= stm32_get_rate(regs
, CSI
);
593 case RCC_CFGR_SW_HSI
:
594 sysclk
= stm32_get_rate(regs
, HSI
);
598 /* sysclk = 0 ? no need to go ahead */
602 debug("%s system clock: source = %d freq = %ld\n",
603 __func__
, source
, sysclk
);
605 d1cfgr
= readl(®s
->d1cfgr
);
607 if (d1cfgr
& RCC_D1CFGR_D1CPRE_DIVIDED
) {
608 /* get D1 domain Core prescaler */
609 idx
= (d1cfgr
& RCC_D1CFGR_D1CPRE_DIVIDER
) >>
610 RCC_D1CFGR_D1CPRE_SHIFT
;
611 sysclk
= sysclk
/ prescaler_table
[idx
];
614 if (d1cfgr
& RCC_D1CFGR_HPRE_DIVIDED
) {
615 /* get D1 domain AHB prescaler */
616 idx
= d1cfgr
& RCC_D1CFGR_HPRE_DIVIDER
;
617 sysclk
= sysclk
/ prescaler_table
[idx
];
620 gate_offset
= clk_map
[clk
->id
].gate_offset
;
622 debug("%s clk->id=%ld gate_offset=0x%x sysclk=%ld\n",
623 __func__
, clk
->id
, gate_offset
, sysclk
);
625 switch (gate_offset
) {
634 if (d1cfgr
& RCC_D1CFGR_D1PPRE_DIVIDED
) {
635 /* get D1 domain APB3 prescaler */
636 idx
= (d1cfgr
& RCC_D1CFGR_D1PPRE_DIVIDER
) >>
637 RCC_D1CFGR_D1PPRE_SHIFT
;
638 sysclk
= sysclk
/ prescaler_table
[idx
];
641 debug("%s system clock: freq after APB3 prescaler = %ld\n",
648 if (d1cfgr
& RCC_D3CFGR_D3PPRE_DIVIDED
) {
649 /* get D3 domain APB4 prescaler */
650 idx
= (d1cfgr
& RCC_D3CFGR_D3PPRE_DIVIDER
) >>
651 RCC_D3CFGR_D3PPRE_SHIFT
;
652 sysclk
= sysclk
/ prescaler_table
[idx
];
655 debug("%s system clock: freq after APB4 prescaler = %ld\n",
663 if (d1cfgr
& RCC_D2CFGR_D2PPRE1_DIVIDED
) {
664 /* get D2 domain APB1 prescaler */
665 idx
= (d1cfgr
& RCC_D2CFGR_D2PPRE1_DIVIDER
) >>
666 RCC_D2CFGR_D2PPRE1_SHIFT
;
667 sysclk
= sysclk
/ prescaler_table
[idx
];
670 debug("%s system clock: freq after APB1 prescaler = %ld\n",
677 if (d1cfgr
& RCC_D2CFGR_D2PPRE2_DIVIDED
) {
678 /* get D2 domain APB1 prescaler */
679 idx
= (d1cfgr
& RCC_D2CFGR_D2PPRE2_DIVIDER
) >>
680 RCC_D2CFGR_D2PPRE2_SHIFT
;
681 sysclk
= sysclk
/ prescaler_table
[idx
];
684 debug("%s system clock: freq after APB2 prescaler = %ld\n",
691 pr_err("unexpected gate_offset value (0x%x)\n", gate_offset
);
697 static int stm32_clk_enable(struct clk
*clk
)
699 struct stm32_clk
*priv
= dev_get_priv(clk
->dev
);
700 struct stm32_rcc_regs
*regs
= priv
->rcc_base
;
703 unsigned long clk_id
= clk
->id
;
705 gate_offset
= clk_map
[clk_id
].gate_offset
;
706 gate_bit_index
= clk_map
[clk_id
].gate_bit_idx
;
708 debug("%s: clkid=%ld gate offset=0x%x bit_index=%d name=%s\n",
709 __func__
, clk
->id
, gate_offset
, gate_bit_index
,
710 clk_map
[clk_id
].name
);
712 setbits_le32(®s
->cr
+ (gate_offset
/ 4), BIT(gate_bit_index
));
717 static int stm32_clk_probe(struct udevice
*dev
)
719 struct stm32_clk
*priv
= dev_get_priv(dev
);
720 struct udevice
*syscon
;
724 addr
= dev_read_addr(dev
);
725 if (addr
== FDT_ADDR_T_NONE
)
728 priv
->rcc_base
= (struct stm32_rcc_regs
*)addr
;
730 /* get corresponding syscon phandle */
731 err
= uclass_get_device_by_phandle(UCLASS_SYSCON
, dev
,
732 "st,syscfg", &syscon
);
735 pr_err("unable to find syscon device\n");
739 priv
->pwr_regmap
= syscon_get_regmap(syscon
);
740 if (!priv
->pwr_regmap
) {
741 pr_err("unable to find regmap\n");
745 configure_clocks(dev
);
750 static int stm32_clk_of_xlate(struct clk
*clk
,
751 struct ofnode_phandle_args
*args
)
753 if (args
->args_count
!= 1) {
754 debug("Invaild args_count: %d\n", args
->args_count
);
758 if (args
->args_count
) {
759 clk
->id
= args
->args
[0];
761 * this computation convert DT clock index which is used to
762 * point into 2 separate clock arrays (peripheral and kernel
763 * clocks bank) (see include/dt-bindings/clock/stm32h7-clks.h)
764 * into index to point into only one array where peripheral
765 * and kernel clocks are consecutive
767 if (clk
->id
>= KERN_BANK
) {
768 clk
->id
-= KERN_BANK
;
769 clk
->id
+= LAST_PERIF_BANK
- PERIF_BANK
+ 1;
771 clk
->id
-= PERIF_BANK
;
777 debug("%s clk->id %ld\n", __func__
, clk
->id
);
782 static struct clk_ops stm32_clk_ops
= {
783 .of_xlate
= stm32_clk_of_xlate
,
784 .enable
= stm32_clk_enable
,
785 .get_rate
= stm32_clk_get_rate
,
788 U_BOOT_DRIVER(stm32h7_clk
) = {
789 .name
= "stm32h7_rcc_clock",
791 .ops
= &stm32_clk_ops
,
792 .probe
= stm32_clk_probe
,
793 .priv_auto_alloc_size
= sizeof(struct stm32_clk
),
794 .flags
= DM_FLAG_PRE_RELOC
,