]> Git Repo - J-u-boot.git/blob - arch/arm/mach-socfpga/clock_manager_gen5.c
Merge tag 'u-boot-imx-master-20250127' of https://gitlab.denx.de/u-boot/custodians...
[J-u-boot.git] / arch / arm / mach-socfpga / clock_manager_gen5.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Copyright (C) 2013-2017 Altera Corporation <www.altera.com>
4  */
5
6 #include <time.h>
7 #include <asm/io.h>
8 #include <dm.h>
9 #include <asm/arch/clock_manager.h>
10 #include <wait_bit.h>
11
12 /*
13  * function to write the bypass register which requires a poll of the
14  * busy bit
15  */
16 static void cm_write_bypass(u32 val)
17 {
18         writel(val, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_BYPASS);
19         cm_wait_for_fsm();
20 }
21
22 /* function to write the ctrl register which requires a poll of the busy bit */
23 static void cm_write_ctrl(u32 val)
24 {
25         writel(val, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_CTRL);
26         cm_wait_for_fsm();
27 }
28
29 /* function to write a clock register that has phase information */
30 static int cm_write_with_phase(u32 value, const void *reg_address, u32 mask)
31 {
32         int ret;
33
34         /* poll until phase is zero */
35         ret = wait_for_bit_le32(reg_address, mask, false, 20000, false);
36         if (ret)
37                 return ret;
38
39         writel(value, reg_address);
40
41         return wait_for_bit_le32(reg_address, mask, false, 20000, false);
42 }
43
44 /*
45  * Setup clocks while making no assumptions about previous state of the clocks.
46  *
47  * Start by being paranoid and gate all sw managed clocks
48  * Put all plls in bypass
49  * Put all plls VCO registers back to reset value (bandgap power down).
50  * Put peripheral and main pll src to reset value to avoid glitch.
51  * Delay 5 us.
52  * Deassert bandgap power down and set numerator and denominator
53  * Start 7 us timer.
54  * set internal dividers
55  * Wait for 7 us timer.
56  * Enable plls
57  * Set external dividers while plls are locking
58  * Wait for pll lock
59  * Assert/deassert outreset all.
60  * Take all pll's out of bypass
61  * Clear safe mode
62  * set source main and peripheral clocks
63  * Ungate clocks
64  */
65
66 int cm_basic_init(const struct cm_config * const cfg)
67 {
68         unsigned long end;
69         int ret;
70
71         /* Start by being paranoid and gate all sw managed clocks */
72
73         /*
74          * We need to disable nandclk
75          * and then do another apb access before disabling
76          * gatting off the rest of the periperal clocks.
77          */
78         writel(~CLKMGR_PERPLLGRP_EN_NANDCLK_MASK &
79                 readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EN),
80                 socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EN);
81
82         /* DO NOT GATE OFF DEBUG CLOCKS & BRIDGE CLOCKS */
83         writel(CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK |
84                 CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK |
85                 CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK |
86                 CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK |
87                 CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK |
88                 CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK,
89                 socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_EN);
90
91         writel(0, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_EN);
92
93         /* now we can gate off the rest of the peripheral clocks */
94         writel(0, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EN);
95
96         /* Put all plls in bypass */
97         cm_write_bypass(CLKMGR_BYPASS_PERPLL | CLKMGR_BYPASS_SDRPLL |
98                         CLKMGR_BYPASS_MAINPLL);
99
100         /* Put all plls VCO registers back to reset value. */
101         writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE &
102                ~CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK,
103                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
104         writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE &
105                ~CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK,
106                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
107         writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE &
108                ~CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK,
109                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
110
111         /*
112          * The clocks to the flash devices and the L4_MAIN clocks can
113          * glitch when coming out of safe mode if their source values
114          * are different from their reset value.  So the trick it to
115          * put them back to their reset state, and change input
116          * after exiting safe mode but before ungating the clocks.
117          */
118         writel(CLKMGR_PERPLLGRP_SRC_RESET_VALUE,
119                       socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_SRC);
120         writel(CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE,
121                       socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_L4SRC);
122
123         /* read back for the required 5 us delay. */
124         readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
125         readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
126         readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
127
128         /*
129          * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN
130          * with numerator and denominator.
131          */
132         writel(cfg->main_vco_base,
133                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
134         writel(cfg->peri_vco_base,
135                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
136         writel(cfg->sdram_vco_base,
137                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
138
139         /*
140          * Time starts here. Must wait 7 us from
141          * BGPWRDN_SET(0) to VCO_ENABLE_SET(1).
142          */
143         end = timer_get_us() + 7;
144
145         /* main mpu */
146         writel(cfg->mpuclk,
147                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MPUCLK);
148
149         /* altera group mpuclk */
150         writel(cfg->altera_grp_mpuclk,
151                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_ALTR_MPUCLK);
152
153         /* main main clock */
154         writel(cfg->mainclk,
155                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MAINCLK);
156
157         /* main for dbg */
158         writel(cfg->dbgatclk,
159                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_DBGATCLK);
160
161         /* main for cfgs2fuser0clk */
162         writel(cfg->cfg2fuser0clk,
163                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_CFGS2FUSER0CLK);
164
165         /* Peri emac0 50 MHz default to RMII */
166         writel(cfg->emac0clk,
167                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EMAC0CLK);
168
169         /* Peri emac1 50 MHz default to RMII */
170         writel(cfg->emac1clk,
171                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EMAC1CLK);
172
173         /* Peri QSPI */
174         writel(cfg->mainqspiclk,
175                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MAINQSPICLK);
176
177         writel(cfg->perqspiclk,
178                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_PERQSPICLK);
179
180         /* Peri pernandsdmmcclk */
181         writel(cfg->mainnandsdmmcclk,
182                socfpga_get_clkmgr_addr() +
183                CLKMGR_GEN5_MAINPLL_MAINNANDSDMMCCLK);
184
185         writel(cfg->pernandsdmmcclk,
186                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_PERNANDSDMMCCLK);
187
188         /* Peri perbaseclk */
189         writel(cfg->perbaseclk,
190                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_PERBASECLK);
191
192         /* Peri s2fuser1clk */
193         writel(cfg->s2fuser1clk,
194                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_S2FUSER1CLK);
195
196         /* 7 us must have elapsed before we can enable the VCO */
197         while (timer_get_us() < end)
198                 ;
199
200         /* Enable vco */
201         /* main pll vco */
202         writel(cfg->main_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
203                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
204
205         /* periferal pll */
206         writel(cfg->peri_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
207                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
208
209         /* sdram pll vco */
210         writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
211                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
212
213         /* L3 MP and L3 SP */
214         writel(cfg->maindiv,
215                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MAINDIV);
216
217         writel(cfg->dbgdiv,
218                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_DBGDIV);
219
220         writel(cfg->tracediv,
221                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_TRACEDIV);
222
223         /* L4 MP, L4 SP, can0, and can1 */
224         writel(cfg->perdiv,
225                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_DIV);
226
227         writel(cfg->gpiodiv,
228                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_GPIODIV);
229
230         cm_wait_for_lock(LOCKED_MASK);
231
232         /* write the sdram clock counters before toggling outreset all */
233         writel(cfg->ddrdqsclk & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK,
234                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_DDRDQSCLK);
235
236         writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK,
237                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_DDR2XDQSCLK);
238
239         writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK,
240                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_DDRDQCLK);
241
242         writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK,
243                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_S2FUSER2CLK);
244
245         /*
246          * after locking, but before taking out of bypass
247          * assert/deassert outresetall
248          */
249         u32 mainvco = readl(socfpga_get_clkmgr_addr() +
250                             CLKMGR_GEN5_MAINPLL_VCO);
251
252         /* assert main outresetall */
253         writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK,
254                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
255
256         u32 periphvco = readl(socfpga_get_clkmgr_addr() +
257                               CLKMGR_GEN5_PERPLL_VCO);
258
259         /* assert pheriph outresetall */
260         writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK,
261                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
262
263         /* assert sdram outresetall */
264         writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN |
265                CLKMGR_SDRPLLGRP_VCO_OUTRESETALL,
266                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
267
268         /* deassert main outresetall */
269         writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK,
270                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
271
272         /* deassert pheriph outresetall */
273         writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK,
274                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
275
276         /* deassert sdram outresetall */
277         writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
278                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
279
280         /*
281          * now that we've toggled outreset all, all the clocks
282          * are aligned nicely; so we can change any phase.
283          */
284         ret = cm_write_with_phase(cfg->ddrdqsclk,
285                                   (const void *)(socfpga_get_clkmgr_addr() +
286                                   CLKMGR_GEN5_SDRPLL_DDRDQSCLK),
287                                   CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK);
288         if (ret)
289                 return ret;
290
291         /* SDRAM DDR2XDQSCLK */
292         ret = cm_write_with_phase(cfg->ddr2xdqsclk,
293                                   (const void *)(socfpga_get_clkmgr_addr() +
294                                   CLKMGR_GEN5_SDRPLL_DDR2XDQSCLK),
295                                   CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK);
296         if (ret)
297                 return ret;
298
299         ret = cm_write_with_phase(cfg->ddrdqclk,
300                                   (const void *)(socfpga_get_clkmgr_addr() +
301                                   CLKMGR_GEN5_SDRPLL_DDRDQCLK),
302                                   CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK);
303         if (ret)
304                 return ret;
305
306         ret = cm_write_with_phase(cfg->s2fuser2clk,
307                                   (const void *)(socfpga_get_clkmgr_addr() +
308                                   CLKMGR_GEN5_SDRPLL_S2FUSER2CLK),
309                                   CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK);
310         if (ret)
311                 return ret;
312
313         /* Take all three PLLs out of bypass when safe mode is cleared. */
314         cm_write_bypass(0);
315
316         /* clear safe mode */
317         cm_write_ctrl(readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_CTRL) |
318                       CLKMGR_CTRL_SAFEMODE);
319
320         /*
321          * now that safe mode is clear with clocks gated
322          * it safe to change the source mux for the flashes the the L4_MAIN
323          */
324         writel(cfg->persrc,
325                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_SRC);
326         writel(cfg->l4src,
327                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_L4SRC);
328
329         /* Now ungate non-hw-managed clocks */
330         writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_EN);
331         writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EN);
332         writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_EN);
333
334         /* Clear the loss of lock bits (write 1 to clear) */
335         writel(CLKMGR_INTER_SDRPLLLOST_MASK |
336                       CLKMGR_INTER_PERPLLLOST_MASK |
337                       CLKMGR_INTER_MAINPLLLOST_MASK,
338                       socfpga_get_clkmgr_addr() + CLKMGR_GEN5_INTER);
339
340         return 0;
341 }
342
343 static unsigned int cm_get_main_vco_clk_hz(void)
344 {
345         u32 reg, clock;
346
347         /* get the main VCO clock */
348         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
349         clock = cm_get_osc_clk_hz(1);
350         clock /= ((reg & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >>
351                   CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) + 1;
352         clock *= ((reg & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >>
353                   CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) + 1;
354
355         return clock;
356 }
357
358 static unsigned int cm_get_per_vco_clk_hz(void)
359 {
360         u32 reg, clock = 0;
361
362         /* identify PER PLL clock source */
363         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
364         reg = (reg & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >>
365               CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET;
366         if (reg == CLKMGR_VCO_SSRC_EOSC1)
367                 clock = cm_get_osc_clk_hz(1);
368         else if (reg == CLKMGR_VCO_SSRC_EOSC2)
369                 clock = cm_get_osc_clk_hz(2);
370         else if (reg == CLKMGR_VCO_SSRC_F2S)
371                 clock = cm_get_f2s_per_ref_clk_hz();
372
373         /* get the PER VCO clock */
374         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
375         clock /= ((reg & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >>
376                   CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) + 1;
377         clock *= ((reg & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >>
378                   CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) + 1;
379
380         return clock;
381 }
382
383 unsigned long cm_get_mpu_clk_hz(void)
384 {
385         u32 reg, clock;
386
387         clock = cm_get_main_vco_clk_hz();
388
389         /* get the MPU clock */
390         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_ALTR_MPUCLK);
391         clock /= (reg + 1);
392         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MPUCLK);
393         clock /= (reg + 1);
394         return clock;
395 }
396
397 unsigned long cm_get_sdram_clk_hz(void)
398 {
399         u32 reg, clock = 0;
400
401         /* identify SDRAM PLL clock source */
402         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
403         reg = (reg & CLKMGR_SDRPLLGRP_VCO_SSRC_MASK) >>
404               CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET;
405         if (reg == CLKMGR_VCO_SSRC_EOSC1)
406                 clock = cm_get_osc_clk_hz(1);
407         else if (reg == CLKMGR_VCO_SSRC_EOSC2)
408                 clock = cm_get_osc_clk_hz(2);
409         else if (reg == CLKMGR_VCO_SSRC_F2S)
410                 clock = cm_get_f2s_sdr_ref_clk_hz();
411
412         /* get the SDRAM VCO clock */
413         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
414         clock /= ((reg & CLKMGR_SDRPLLGRP_VCO_DENOM_MASK) >>
415                   CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) + 1;
416         clock *= ((reg & CLKMGR_SDRPLLGRP_VCO_NUMER_MASK) >>
417                   CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) + 1;
418
419         /* get the SDRAM (DDR_DQS) clock */
420         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_DDRDQSCLK);
421         reg = (reg & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK) >>
422               CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET;
423         clock /= (reg + 1);
424
425         return clock;
426 }
427
428 unsigned int cm_get_l4_sp_clk_hz(void)
429 {
430         u32 reg, clock = 0;
431
432         /* identify the source of L4 SP clock */
433         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_L4SRC);
434         reg = (reg & CLKMGR_MAINPLLGRP_L4SRC_L4SP) >>
435               CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET;
436
437         if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) {
438                 clock = cm_get_main_vco_clk_hz();
439
440                 /* get the clock prior L4 SP divider (main clk) */
441                 reg = readl(socfpga_get_clkmgr_addr() +
442                             CLKMGR_GEN5_ALTR_MAINCLK);
443                 clock /= (reg + 1);
444                 reg = readl(socfpga_get_clkmgr_addr() +
445                             CLKMGR_GEN5_MAINPLL_MAINCLK);
446                 clock /= (reg + 1);
447         } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) {
448                 clock = cm_get_per_vco_clk_hz();
449
450                 /* get the clock prior L4 SP divider (periph_base_clk) */
451                 reg = readl(socfpga_get_clkmgr_addr() +
452                             CLKMGR_GEN5_PERPLL_PERBASECLK);
453                 clock /= (reg + 1);
454         }
455
456         /* get the L4 SP clock which supplied to UART */
457         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MAINDIV);
458         reg = (reg & CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK) >>
459               CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET;
460         clock = clock / (1 << reg);
461
462         return clock;
463 }
464
465 unsigned int cm_get_mmc_controller_clk_hz(void)
466 {
467         u32 reg, clock = 0;
468
469         /* identify the source of MMC clock */
470         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_SRC);
471         reg = (reg & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >>
472               CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET;
473
474         if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) {
475                 clock = cm_get_f2s_per_ref_clk_hz();
476         } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) {
477                 clock = cm_get_main_vco_clk_hz();
478
479                 /* get the SDMMC clock */
480                 reg = readl(socfpga_get_clkmgr_addr() +
481                             CLKMGR_GEN5_MAINPLL_MAINNANDSDMMCCLK);
482                 clock /= (reg + 1);
483         } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) {
484                 clock = cm_get_per_vco_clk_hz();
485
486                 /* get the SDMMC clock */
487                 reg = readl(socfpga_get_clkmgr_addr() +
488                             CLKMGR_GEN5_PERPLL_PERNANDSDMMCCLK);
489                 clock /= (reg + 1);
490         }
491
492         /* further divide by 4 as we have fixed divider at wrapper */
493         clock /= 4;
494         return clock;
495 }
496
497 unsigned int cm_get_qspi_controller_clk_hz(void)
498 {
499         u32 reg, clock = 0;
500
501         /* identify the source of QSPI clock */
502         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_SRC);
503         reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >>
504               CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET;
505
506         if (reg == CLKMGR_QSPI_CLK_SRC_F2S) {
507                 clock = cm_get_f2s_per_ref_clk_hz();
508         } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) {
509                 clock = cm_get_main_vco_clk_hz();
510
511                 /* get the qspi clock */
512                 reg = readl(socfpga_get_clkmgr_addr() +
513                             CLKMGR_GEN5_MAINPLL_MAINQSPICLK);
514                 clock /= (reg + 1);
515         } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) {
516                 clock = cm_get_per_vco_clk_hz();
517
518                 /* get the qspi clock */
519                 reg = readl(socfpga_get_clkmgr_addr() +
520                             CLKMGR_GEN5_PERPLL_PERQSPICLK);
521                 clock /= (reg + 1);
522         }
523
524         return clock;
525 }
526
527 unsigned int cm_get_spi_controller_clk_hz(void)
528 {
529         u32 reg, clock = 0;
530
531         clock = cm_get_per_vco_clk_hz();
532
533         /* get the clock prior L4 SP divider (periph_base_clk) */
534         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_PERBASECLK);
535         clock /= (reg + 1);
536
537         return clock;
538 }
539
540 /* Override weak dw_spi_get_clk implementation in designware_spi.c driver */
541 int dw_spi_get_clk(struct udevice *bus, ulong *rate)
542 {
543         *rate = cm_get_spi_controller_clk_hz();
544
545         return 0;
546 }
547
548 void cm_print_clock_quick_summary(void)
549 {
550         printf("MPU       %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);
551         printf("DDR       %10ld kHz\n", cm_get_sdram_clk_hz() / 1000);
552         printf("EOSC1       %8d kHz\n", cm_get_osc_clk_hz(1) / 1000);
553         printf("EOSC2       %8d kHz\n", cm_get_osc_clk_hz(2) / 1000);
554         printf("F2S_SDR_REF %8d kHz\n", cm_get_f2s_sdr_ref_clk_hz() / 1000);
555         printf("F2S_PER_REF %8d kHz\n", cm_get_f2s_per_ref_clk_hz() / 1000);
556         printf("MMC         %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
557         printf("QSPI        %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000);
558         printf("UART        %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
559         printf("SPI         %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000);
560 }
This page took 0.056866 seconds and 4 git commands to generate.