blob: 634f0717c68a29af192785e20a2d2a250f5608fd [file] [log] [blame]
Vikas Manocha1b51c932016-02-11 15:47:20 -08001/*
Patrice Chotard789ee0e2017-10-23 09:53:58 +02002 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
3 * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
Vikas Manocha1b51c932016-02-11 15:47:20 -08004 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
Patrice Chotard789ee0e2017-10-23 09:53:58 +02007
Vikas Manocha1b51c932016-02-11 15:47:20 -08008#include <common.h>
Vikas Manochadaaeaab2017-02-12 10:25:45 -08009#include <clk-uclass.h>
10#include <dm.h>
Patrice Chotard03f10a12017-11-15 13:14:51 +010011#include <stm32_rcc.h>
Patrice Chotard22768d52017-11-15 13:14:44 +010012
Vikas Manocha1b51c932016-02-11 15:47:20 -080013#include <asm/io.h>
Vikas Manocha1b51c932016-02-11 15:47:20 -080014#include <asm/arch/stm32.h>
15#include <asm/arch/stm32_periph.h>
Patrice Chotard22768d52017-11-15 13:14:44 +010016#include <asm/arch/stm32_pwr.h>
Vikas Manocha1b51c932016-02-11 15:47:20 -080017
Patrice Chotard7bdf9712017-07-18 09:29:05 +020018#include <dt-bindings/mfd/stm32f7-rcc.h>
19
Michael Kurzc204fb72017-01-22 16:04:24 +010020#define RCC_CR_HSION BIT(0)
21#define RCC_CR_HSEON BIT(16)
22#define RCC_CR_HSERDY BIT(17)
23#define RCC_CR_HSEBYP BIT(18)
24#define RCC_CR_CSSON BIT(19)
25#define RCC_CR_PLLON BIT(24)
26#define RCC_CR_PLLRDY BIT(25)
Patrice Chotard369d4832017-11-15 13:14:52 +010027#define RCC_CR_PLLSAION BIT(28)
28#define RCC_CR_PLLSAIRDY BIT(29)
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +090029
Michael Kurzc204fb72017-01-22 16:04:24 +010030#define RCC_PLLCFGR_PLLM_MASK GENMASK(5, 0)
31#define RCC_PLLCFGR_PLLN_MASK GENMASK(14, 6)
32#define RCC_PLLCFGR_PLLP_MASK GENMASK(17, 16)
33#define RCC_PLLCFGR_PLLQ_MASK GENMASK(27, 24)
34#define RCC_PLLCFGR_PLLSRC BIT(22)
35#define RCC_PLLCFGR_PLLM_SHIFT 0
36#define RCC_PLLCFGR_PLLN_SHIFT 6
37#define RCC_PLLCFGR_PLLP_SHIFT 16
38#define RCC_PLLCFGR_PLLQ_SHIFT 24
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +090039
Michael Kurzc204fb72017-01-22 16:04:24 +010040#define RCC_CFGR_AHB_PSC_MASK GENMASK(7, 4)
41#define RCC_CFGR_APB1_PSC_MASK GENMASK(12, 10)
42#define RCC_CFGR_APB2_PSC_MASK GENMASK(15, 13)
43#define RCC_CFGR_SW0 BIT(0)
44#define RCC_CFGR_SW1 BIT(1)
45#define RCC_CFGR_SW_MASK GENMASK(1, 0)
46#define RCC_CFGR_SW_HSI 0
47#define RCC_CFGR_SW_HSE RCC_CFGR_SW0
48#define RCC_CFGR_SW_PLL RCC_CFGR_SW1
49#define RCC_CFGR_SWS0 BIT(2)
50#define RCC_CFGR_SWS1 BIT(3)
51#define RCC_CFGR_SWS_MASK GENMASK(3, 2)
52#define RCC_CFGR_SWS_HSI 0
53#define RCC_CFGR_SWS_HSE RCC_CFGR_SWS0
54#define RCC_CFGR_SWS_PLL RCC_CFGR_SWS1
55#define RCC_CFGR_HPRE_SHIFT 4
56#define RCC_CFGR_PPRE1_SHIFT 10
57#define RCC_CFGR_PPRE2_SHIFT 13
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +090058
Patrice Chotard369d4832017-11-15 13:14:52 +010059#define RCC_PLLCFGR_PLLSAIN_MASK GENMASK(14, 6)
60#define RCC_PLLCFGR_PLLSAIP_MASK GENMASK(17, 16)
61#define RCC_PLLSAICFGR_PLLSAIN_SHIFT 6
62#define RCC_PLLSAICFGR_PLLSAIP_SHIFT 16
63#define RCC_PLLSAICFGR_PLLSAIP_4 BIT(17)
64#define RCC_PLLSAICFGR_PLLSAIQ_4 BIT(26)
65#define RCC_PLLSAICFGR_PLLSAIR_2 BIT(29)
66
67#define RCC_DCKCFGRX_CK48MSEL BIT(27)
68#define RCC_DCKCFGRX_SDMMC1SEL BIT(28)
69#define RCC_DCKCFGR2_SDMMC2SEL BIT(29)
70
71#define RCC_APB2ENR_SAI1EN BIT(22)
72
Patrice Chotard06fc6482017-11-15 13:14:49 +010073/*
74 * RCC AHB1ENR specific definitions
75 */
76#define RCC_AHB1ENR_ETHMAC_EN BIT(25)
77#define RCC_AHB1ENR_ETHMAC_TX_EN BIT(26)
78#define RCC_AHB1ENR_ETHMAC_RX_EN BIT(27)
79
80/*
81 * RCC APB1ENR specific definitions
82 */
83#define RCC_APB1ENR_TIM2EN BIT(0)
84#define RCC_APB1ENR_PWREN BIT(28)
85
86/*
87 * RCC APB2ENR specific definitions
88 */
89#define RCC_APB2ENR_SYSCFGEN BIT(14)
90
Patrice Chotard1509d662017-11-15 13:14:47 +010091struct stm32_clk_info stm32f4_clk_info = {
92 /* 180 MHz */
93 .sys_pll_psc = {
94 .pll_m = 8,
95 .pll_n = 360,
96 .pll_p = 2,
97 .pll_q = 8,
98 .ahb_psc = AHB_PSC_1,
99 .apb1_psc = APB_PSC_4,
100 .apb2_psc = APB_PSC_2,
101 },
102 .has_overdrive = false,
Patrice Chotard369d4832017-11-15 13:14:52 +0100103 .v2 = false,
Patrice Chotard1509d662017-11-15 13:14:47 +0100104};
105
106struct stm32_clk_info stm32f7_clk_info = {
107 /* 200 MHz */
108 .sys_pll_psc = {
109 .pll_m = 25,
110 .pll_n = 400,
111 .pll_p = 2,
112 .pll_q = 8,
113 .ahb_psc = AHB_PSC_1,
114 .apb1_psc = APB_PSC_4,
115 .apb2_psc = APB_PSC_2,
116 },
117 .has_overdrive = true,
Patrice Chotard369d4832017-11-15 13:14:52 +0100118 .v2 = true,
Patrice Chotard1509d662017-11-15 13:14:47 +0100119};
120
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200121struct stm32_clk {
122 struct stm32_rcc_regs *base;
Patrice Chotard22768d52017-11-15 13:14:44 +0100123 struct stm32_pwr_regs *pwr_regs;
Patrice Chotard1509d662017-11-15 13:14:47 +0100124 struct stm32_clk_info *info;
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900125};
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900126
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200127static int configure_clocks(struct udevice *dev)
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900128{
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200129 struct stm32_clk *priv = dev_get_priv(dev);
130 struct stm32_rcc_regs *regs = priv->base;
Patrice Chotard22768d52017-11-15 13:14:44 +0100131 struct stm32_pwr_regs *pwr = priv->pwr_regs;
Patrice Chotard1509d662017-11-15 13:14:47 +0100132 struct pll_psc sys_pll_psc = priv->info->sys_pll_psc;
Patrice Chotard369d4832017-11-15 13:14:52 +0100133 u32 pllsaicfgr = 0;
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200134
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900135 /* Reset RCC configuration */
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200136 setbits_le32(&regs->cr, RCC_CR_HSION);
137 writel(0, &regs->cfgr); /* Reset CFGR */
138 clrbits_le32(&regs->cr, (RCC_CR_HSEON | RCC_CR_CSSON
Patrice Chotard369d4832017-11-15 13:14:52 +0100139 | RCC_CR_PLLON | RCC_CR_PLLSAION));
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200140 writel(0x24003010, &regs->pllcfgr); /* Reset value from RM */
141 clrbits_le32(&regs->cr, RCC_CR_HSEBYP);
142 writel(0, &regs->cir); /* Disable all interrupts */
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900143
144 /* Configure for HSE+PLL operation */
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200145 setbits_le32(&regs->cr, RCC_CR_HSEON);
146 while (!(readl(&regs->cr) & RCC_CR_HSERDY))
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900147 ;
148
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200149 setbits_le32(&regs->cfgr, ((
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900150 sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT)
151 | (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT)
152 | (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
153
154 /* Configure the main PLL */
Patrice Chotardb6653f62017-10-26 13:23:19 +0200155 setbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLSRC); /* pll source HSE */
156 clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLM_MASK,
157 sys_pll_psc.pll_m << RCC_PLLCFGR_PLLM_SHIFT);
158 clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLN_MASK,
159 sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT);
160 clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLP_MASK,
161 ((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT);
162 clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLQ_MASK,
163 sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT);
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900164
Patrice Chotard369d4832017-11-15 13:14:52 +0100165 /* Configure the SAI PLL to get a 48 MHz source */
166 pllsaicfgr = RCC_PLLSAICFGR_PLLSAIR_2 | RCC_PLLSAICFGR_PLLSAIQ_4 |
167 RCC_PLLSAICFGR_PLLSAIP_4;
168 pllsaicfgr |= 192 << RCC_PLLSAICFGR_PLLSAIN_SHIFT;
169 writel(pllsaicfgr, &regs->pllsaicfgr);
170
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900171 /* Enable the main PLL */
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200172 setbits_le32(&regs->cr, RCC_CR_PLLON);
173 while (!(readl(&regs->cr) & RCC_CR_PLLRDY))
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900174 ;
175
Patrice Chotard369d4832017-11-15 13:14:52 +0100176 if (priv->info->v2) { /*stm32f7 case */
177 /* select PLLSAI as 48MHz clock source */
178 setbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
179
180 /* select 48MHz as SDMMC1 clock source */
181 clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_SDMMC1SEL);
182
183 /* select 48MHz as SDMMC2 clock source */
184 clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGR2_SDMMC2SEL);
185 } else { /* stm32f4 case */
186 /* select PLLSAI as 48MHz clock source */
187 setbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
188
189 /* select 48MHz as SDMMC1 clock source */
190 clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_SDMMC1SEL);
191 }
192
193 /* Enable the SAI PLL */
194 setbits_le32(&regs->cr, RCC_CR_PLLSAION);
195 while (!(readl(&regs->cr) & RCC_CR_PLLSAIRDY))
196 ;
197
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200198 setbits_le32(&regs->apb1enr, RCC_APB1ENR_PWREN);
Patrice Chotard1509d662017-11-15 13:14:47 +0100199
200 if (priv->info->has_overdrive) {
201 /*
202 * Enable high performance mode
203 * System frequency up to 200 MHz
204 */
205 setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
206 /* Infinite wait! */
207 while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY))
208 ;
209 /* Enable the Over-drive switch */
210 setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN);
211 /* Infinite wait! */
212 while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY))
213 ;
214 }
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900215
216 stm32_flash_latency_cfg(5);
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200217 clrbits_le32(&regs->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
218 setbits_le32(&regs->cfgr, RCC_CFGR_SW_PLL);
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900219
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200220 while ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) !=
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900221 RCC_CFGR_SWS_PLL)
222 ;
Patrice Chotard369d4832017-11-15 13:14:52 +0100223 /* gate the SAI clock, needed for MMC 1&2 clocks */
224 setbits_le32(&regs->apb2enr, RCC_APB2ENR_SAI1EN);
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900225
226 return 0;
227}
228
Patrice Chotard369d4832017-11-15 13:14:52 +0100229static unsigned long stm32_clk_pll48clk_rate(struct stm32_clk *priv,
230 u32 sysclk)
231{
232 struct stm32_rcc_regs *regs = priv->base;
233 u16 pllq, pllm, pllsain, pllsaip;
234 bool pllsai;
235
236 pllq = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLQ_MASK)
237 >> RCC_PLLCFGR_PLLQ_SHIFT;
238
239 if (priv->info->v2) /*stm32f7 case */
240 pllsai = readl(&regs->dckcfgr2) & RCC_DCKCFGRX_CK48MSEL;
241 else
242 pllsai = readl(&regs->dckcfgr) & RCC_DCKCFGRX_CK48MSEL;
243
244 if (pllsai) {
245 /* PLL48CLK is selected from PLLSAI, get PLLSAI value */
246 pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
247 pllsain = ((readl(&regs->pllsaicfgr) & RCC_PLLCFGR_PLLSAIN_MASK)
248 >> RCC_PLLSAICFGR_PLLSAIN_SHIFT);
249 pllsaip = ((((readl(&regs->pllsaicfgr) & RCC_PLLCFGR_PLLSAIP_MASK)
250 >> RCC_PLLSAICFGR_PLLSAIP_SHIFT) + 1) << 1);
251 return ((CONFIG_STM32_HSE_HZ / pllm) * pllsain) / pllsaip;
252 }
253 /* PLL48CLK is selected from PLLQ */
254 return sysclk / pllq;
255}
256
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200257static unsigned long stm32_clk_get_rate(struct clk *clk)
258{
259 struct stm32_clk *priv = dev_get_priv(clk->dev);
260 struct stm32_rcc_regs *regs = priv->base;
261 u32 sysclk = 0;
262 u32 shift = 0;
Patrice Chotardd4f2d202017-11-15 13:14:48 +0100263 u16 pllm, plln, pllp;
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200264 /* Prescaler table lookups for clock computation */
265 u8 ahb_psc_table[16] = {
266 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
267 };
268 u8 apb_psc_table[8] = {
269 0, 0, 0, 0, 1, 2, 3, 4
270 };
271
272 if ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) ==
273 RCC_CFGR_SWS_PLL) {
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200274 pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
275 plln = ((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
276 >> RCC_PLLCFGR_PLLN_SHIFT);
277 pllp = ((((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
278 >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
279 sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp;
280 } else {
281 return -EINVAL;
282 }
283
284 switch (clk->id) {
285 /*
286 * AHB CLOCK: 3 x 32 bits consecutive registers are used :
287 * AHB1, AHB2 and AHB3
288 */
289 case STM32F7_AHB1_CLOCK(GPIOA) ... STM32F7_AHB3_CLOCK(QSPI):
290 shift = ahb_psc_table[(
291 (readl(&regs->cfgr) & RCC_CFGR_AHB_PSC_MASK)
292 >> RCC_CFGR_HPRE_SHIFT)];
293 return sysclk >>= shift;
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200294 /* APB1 CLOCK */
295 case STM32F7_APB1_CLOCK(TIM2) ... STM32F7_APB1_CLOCK(UART8):
296 shift = apb_psc_table[(
297 (readl(&regs->cfgr) & RCC_CFGR_APB1_PSC_MASK)
298 >> RCC_CFGR_PPRE1_SHIFT)];
299 return sysclk >>= shift;
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200300 /* APB2 CLOCK */
301 case STM32F7_APB2_CLOCK(TIM1) ... STM32F7_APB2_CLOCK(LTDC):
Patrice Chotard369d4832017-11-15 13:14:52 +0100302 /*
303 * particular case for SDMMC1 and SDMMC2 :
304 * 48Mhz source clock can be from main PLL or from
305 * SAI PLL
306 */
307 switch (clk->id) {
308 case STM32F7_APB2_CLOCK(SDMMC1):
309 if (readl(&regs->dckcfgr2) & RCC_DCKCFGRX_SDMMC1SEL)
310 /* System clock is selected as SDMMC1 clock */
311 return sysclk;
312 else
313 return stm32_clk_pll48clk_rate(priv, sysclk);
314 break;
315 case STM32F7_APB2_CLOCK(SDMMC2):
316 if (readl(&regs->dckcfgr2) & RCC_DCKCFGR2_SDMMC2SEL)
317 /* System clock is selected as SDMMC2 clock */
318 return sysclk;
319 else
320 return stm32_clk_pll48clk_rate(priv, sysclk);
321 break;
322 }
323
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200324 shift = apb_psc_table[(
325 (readl(&regs->cfgr) & RCC_CFGR_APB2_PSC_MASK)
326 >> RCC_CFGR_PPRE2_SHIFT)];
327 return sysclk >>= shift;
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200328 default:
Masahiro Yamada81e10422017-09-16 14:10:41 +0900329 pr_err("clock index %ld out of range\n", clk->id);
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200330 return -EINVAL;
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200331 }
332}
333
Vikas Manochadaaeaab2017-02-12 10:25:45 -0800334static int stm32_clk_enable(struct clk *clk)
335{
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200336 struct stm32_clk *priv = dev_get_priv(clk->dev);
337 struct stm32_rcc_regs *regs = priv->base;
Vikas Manochadaaeaab2017-02-12 10:25:45 -0800338 u32 offset = clk->id / 32;
339 u32 bit_index = clk->id % 32;
340
341 debug("%s: clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n",
342 __func__, clk->id, offset, bit_index);
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200343 setbits_le32(&regs->ahb1enr + offset, BIT(bit_index));
Vikas Manochadaaeaab2017-02-12 10:25:45 -0800344
345 return 0;
346}
Toshifumi NISHINAGA65bfb9c2016-07-08 01:02:24 +0900347
Vikas Manocha1b51c932016-02-11 15:47:20 -0800348void clock_setup(int peripheral)
349{
350 switch (peripheral) {
Michael Kurz04bb8db2017-01-22 16:04:26 +0100351 case SYSCFG_CLOCK_CFG:
352 setbits_le32(&STM32_RCC->apb2enr, RCC_APB2ENR_SYSCFGEN);
353 break;
354 case TIMER2_CLOCK_CFG:
355 setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_TIM2EN);
356 break;
Michael Kurz812962b2017-01-22 16:04:27 +0100357 case STMMAC_CLOCK_CFG:
358 setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_EN);
359 setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_RX_EN);
360 setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_TX_EN);
361 break;
Vikas Manocha1b51c932016-02-11 15:47:20 -0800362 default:
363 break;
364 }
365}
Vikas Manochadaaeaab2017-02-12 10:25:45 -0800366
367static int stm32_clk_probe(struct udevice *dev)
368{
Patrice Chotard22768d52017-11-15 13:14:44 +0100369 struct ofnode_phandle_args args;
370 int err;
371
Patrice Chotardd4f2d202017-11-15 13:14:48 +0100372 debug("%s\n", __func__);
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200373
374 struct stm32_clk *priv = dev_get_priv(dev);
375 fdt_addr_t addr;
376
Patrice Chotard1509d662017-11-15 13:14:47 +0100377 addr = dev_read_addr(dev);
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200378 if (addr == FDT_ADDR_T_NONE)
379 return -EINVAL;
380
381 priv->base = (struct stm32_rcc_regs *)addr;
Patrice Chotard03f10a12017-11-15 13:14:51 +0100382
383 switch (dev_get_driver_data(dev)) {
384 case STM32F4:
385 priv->info = &stm32f4_clk_info;
386 break;
387 case STM32F7:
388 priv->info = &stm32f7_clk_info;
389 break;
390 default:
391 return -EINVAL;
392 }
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200393
Patrice Chotard1509d662017-11-15 13:14:47 +0100394 if (priv->info->has_overdrive) {
395 err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
396 &args);
397 if (err) {
398 debug("%s: can't find syscon device (%d)\n", __func__,
399 err);
400 return err;
401 }
Patrice Chotard22768d52017-11-15 13:14:44 +0100402
Patrice Chotard1509d662017-11-15 13:14:47 +0100403 priv->pwr_regs = (struct stm32_pwr_regs *)ofnode_get_addr(args.node);
404 }
Patrice Chotard22768d52017-11-15 13:14:44 +0100405
Patrice Chotardd93fc2c2017-07-18 09:29:04 +0200406 configure_clocks(dev);
Vikas Manochadaaeaab2017-02-12 10:25:45 -0800407
408 return 0;
409}
410
Simon Glassb7ae2772017-05-18 20:09:40 -0600411static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
Vikas Manochadaaeaab2017-02-12 10:25:45 -0800412{
413 debug("%s(clk=%p)\n", __func__, clk);
414
415 if (args->args_count != 2) {
416 debug("Invaild args_count: %d\n", args->args_count);
417 return -EINVAL;
418 }
419
420 if (args->args_count)
421 clk->id = args->args[1];
422 else
423 clk->id = 0;
424
425 return 0;
426}
427
428static struct clk_ops stm32_clk_ops = {
429 .of_xlate = stm32_clk_of_xlate,
430 .enable = stm32_clk_enable,
Patrice Chotard7bdf9712017-07-18 09:29:05 +0200431 .get_rate = stm32_clk_get_rate,
Vikas Manochadaaeaab2017-02-12 10:25:45 -0800432};
433
Patrice Chotardd4f2d202017-11-15 13:14:48 +0100434U_BOOT_DRIVER(stm32fx_clk) = {
Patrice Chotard03f10a12017-11-15 13:14:51 +0100435 .name = "stm32fx_rcc_clock",
Patrice Chotardb323de52017-09-21 10:08:09 +0200436 .id = UCLASS_CLK,
Patrice Chotardb323de52017-09-21 10:08:09 +0200437 .ops = &stm32_clk_ops,
438 .probe = stm32_clk_probe,
439 .priv_auto_alloc_size = sizeof(struct stm32_clk),
440 .flags = DM_FLAG_PRE_RELOC,
Vikas Manochadaaeaab2017-02-12 10:25:45 -0800441};