]> Git Repo - J-u-boot.git/blob - arch/arm/mach-socfpga/clock_manager_gen5.c
Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"
[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         /*
130          * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN
131          * with numerator and denominator.
132          */
133         writel(cfg->main_vco_base,
134                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
135         writel(cfg->peri_vco_base,
136                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
137         writel(cfg->sdram_vco_base,
138                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
139
140         /*
141          * Time starts here. Must wait 7 us from
142          * BGPWRDN_SET(0) to VCO_ENABLE_SET(1).
143          */
144         end = timer_get_us() + 7;
145
146         /* main mpu */
147         writel(cfg->mpuclk,
148                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MPUCLK);
149
150         /* altera group mpuclk */
151         writel(cfg->altera_grp_mpuclk,
152                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_ALTR_MPUCLK);
153
154         /* main main clock */
155         writel(cfg->mainclk,
156                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MAINCLK);
157
158         /* main for dbg */
159         writel(cfg->dbgatclk,
160                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_DBGATCLK);
161
162         /* main for cfgs2fuser0clk */
163         writel(cfg->cfg2fuser0clk,
164                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_CFGS2FUSER0CLK);
165
166         /* Peri emac0 50 MHz default to RMII */
167         writel(cfg->emac0clk,
168                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EMAC0CLK);
169
170         /* Peri emac1 50 MHz default to RMII */
171         writel(cfg->emac1clk,
172                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EMAC1CLK);
173
174         /* Peri QSPI */
175         writel(cfg->mainqspiclk,
176                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MAINQSPICLK);
177
178         writel(cfg->perqspiclk,
179                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_PERQSPICLK);
180
181         /* Peri pernandsdmmcclk */
182         writel(cfg->mainnandsdmmcclk,
183                socfpga_get_clkmgr_addr() +
184                CLKMGR_GEN5_MAINPLL_MAINNANDSDMMCCLK);
185
186         writel(cfg->pernandsdmmcclk,
187                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_PERNANDSDMMCCLK);
188
189         /* Peri perbaseclk */
190         writel(cfg->perbaseclk,
191                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_PERBASECLK);
192
193         /* Peri s2fuser1clk */
194         writel(cfg->s2fuser1clk,
195                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_S2FUSER1CLK);
196
197         /* 7 us must have elapsed before we can enable the VCO */
198         while (timer_get_us() < end)
199                 ;
200
201         /* Enable vco */
202         /* main pll vco */
203         writel(cfg->main_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
204                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
205
206         /* periferal pll */
207         writel(cfg->peri_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
208                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
209
210         /* sdram pll vco */
211         writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
212                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
213
214         /* L3 MP and L3 SP */
215         writel(cfg->maindiv,
216                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MAINDIV);
217
218         writel(cfg->dbgdiv,
219                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_DBGDIV);
220
221         writel(cfg->tracediv,
222                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_TRACEDIV);
223
224         /* L4 MP, L4 SP, can0, and can1 */
225         writel(cfg->perdiv,
226                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_DIV);
227
228         writel(cfg->gpiodiv,
229                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_GPIODIV);
230
231         cm_wait_for_lock(LOCKED_MASK);
232
233         /* write the sdram clock counters before toggling outreset all */
234         writel(cfg->ddrdqsclk & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK,
235                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_DDRDQSCLK);
236
237         writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK,
238                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_DDR2XDQSCLK);
239
240         writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK,
241                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_DDRDQCLK);
242
243         writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK,
244                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_S2FUSER2CLK);
245
246         /*
247          * after locking, but before taking out of bypass
248          * assert/deassert outresetall
249          */
250         u32 mainvco = readl(socfpga_get_clkmgr_addr() +
251                             CLKMGR_GEN5_MAINPLL_VCO);
252
253         /* assert main outresetall */
254         writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK,
255                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
256
257         u32 periphvco = readl(socfpga_get_clkmgr_addr() +
258                               CLKMGR_GEN5_PERPLL_VCO);
259
260         /* assert pheriph outresetall */
261         writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK,
262                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
263
264         /* assert sdram outresetall */
265         writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN |
266                CLKMGR_SDRPLLGRP_VCO_OUTRESETALL,
267                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
268
269         /* deassert main outresetall */
270         writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK,
271                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
272
273         /* deassert pheriph outresetall */
274         writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK,
275                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
276
277         /* deassert sdram outresetall */
278         writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
279                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
280
281         /*
282          * now that we've toggled outreset all, all the clocks
283          * are aligned nicely; so we can change any phase.
284          */
285         ret = cm_write_with_phase(cfg->ddrdqsclk,
286                                   (const void *)(socfpga_get_clkmgr_addr() +
287                                   CLKMGR_GEN5_SDRPLL_DDRDQSCLK),
288                                   CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK);
289         if (ret)
290                 return ret;
291
292         /* SDRAM DDR2XDQSCLK */
293         ret = cm_write_with_phase(cfg->ddr2xdqsclk,
294                                   (const void *)(socfpga_get_clkmgr_addr() +
295                                   CLKMGR_GEN5_SDRPLL_DDR2XDQSCLK),
296                                   CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK);
297         if (ret)
298                 return ret;
299
300         ret = cm_write_with_phase(cfg->ddrdqclk,
301                                   (const void *)(socfpga_get_clkmgr_addr() +
302                                   CLKMGR_GEN5_SDRPLL_DDRDQCLK),
303                                   CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK);
304         if (ret)
305                 return ret;
306
307         ret = cm_write_with_phase(cfg->s2fuser2clk,
308                                   (const void *)(socfpga_get_clkmgr_addr() +
309                                   CLKMGR_GEN5_SDRPLL_S2FUSER2CLK),
310                                   CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK);
311         if (ret)
312                 return ret;
313
314         /* Take all three PLLs out of bypass when safe mode is cleared. */
315         cm_write_bypass(0);
316
317         /* clear safe mode */
318         cm_write_ctrl(readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_CTRL) |
319                       CLKMGR_CTRL_SAFEMODE);
320
321         /*
322          * now that safe mode is clear with clocks gated
323          * it safe to change the source mux for the flashes the the L4_MAIN
324          */
325         writel(cfg->persrc,
326                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_SRC);
327         writel(cfg->l4src,
328                socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_L4SRC);
329
330         /* Now ungate non-hw-managed clocks */
331         writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_EN);
332         writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_EN);
333         writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_EN);
334
335         /* Clear the loss of lock bits (write 1 to clear) */
336         writel(CLKMGR_INTER_SDRPLLLOST_MASK |
337                       CLKMGR_INTER_PERPLLLOST_MASK |
338                       CLKMGR_INTER_MAINPLLLOST_MASK,
339                       socfpga_get_clkmgr_addr() + CLKMGR_GEN5_INTER);
340
341         return 0;
342 }
343
344 static unsigned int cm_get_main_vco_clk_hz(void)
345 {
346         u32 reg, clock;
347
348         /* get the main VCO clock */
349         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_VCO);
350         clock = cm_get_osc_clk_hz(1);
351         clock /= ((reg & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >>
352                   CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) + 1;
353         clock *= ((reg & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >>
354                   CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) + 1;
355
356         return clock;
357 }
358
359 static unsigned int cm_get_per_vco_clk_hz(void)
360 {
361         u32 reg, clock = 0;
362
363         /* identify PER PLL clock source */
364         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
365         reg = (reg & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >>
366               CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET;
367         if (reg == CLKMGR_VCO_SSRC_EOSC1)
368                 clock = cm_get_osc_clk_hz(1);
369         else if (reg == CLKMGR_VCO_SSRC_EOSC2)
370                 clock = cm_get_osc_clk_hz(2);
371         else if (reg == CLKMGR_VCO_SSRC_F2S)
372                 clock = cm_get_f2s_per_ref_clk_hz();
373
374         /* get the PER VCO clock */
375         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_VCO);
376         clock /= ((reg & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >>
377                   CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) + 1;
378         clock *= ((reg & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >>
379                   CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) + 1;
380
381         return clock;
382 }
383
384 unsigned long cm_get_mpu_clk_hz(void)
385 {
386         u32 reg, clock;
387
388         clock = cm_get_main_vco_clk_hz();
389
390         /* get the MPU clock */
391         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_ALTR_MPUCLK);
392         clock /= (reg + 1);
393         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MPUCLK);
394         clock /= (reg + 1);
395         return clock;
396 }
397
398 unsigned long cm_get_sdram_clk_hz(void)
399 {
400         u32 reg, clock = 0;
401
402         /* identify SDRAM PLL clock source */
403         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
404         reg = (reg & CLKMGR_SDRPLLGRP_VCO_SSRC_MASK) >>
405               CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET;
406         if (reg == CLKMGR_VCO_SSRC_EOSC1)
407                 clock = cm_get_osc_clk_hz(1);
408         else if (reg == CLKMGR_VCO_SSRC_EOSC2)
409                 clock = cm_get_osc_clk_hz(2);
410         else if (reg == CLKMGR_VCO_SSRC_F2S)
411                 clock = cm_get_f2s_sdr_ref_clk_hz();
412
413         /* get the SDRAM VCO clock */
414         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_VCO);
415         clock /= ((reg & CLKMGR_SDRPLLGRP_VCO_DENOM_MASK) >>
416                   CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) + 1;
417         clock *= ((reg & CLKMGR_SDRPLLGRP_VCO_NUMER_MASK) >>
418                   CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) + 1;
419
420         /* get the SDRAM (DDR_DQS) clock */
421         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_SDRPLL_DDRDQSCLK);
422         reg = (reg & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK) >>
423               CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET;
424         clock /= (reg + 1);
425
426         return clock;
427 }
428
429 unsigned int cm_get_l4_sp_clk_hz(void)
430 {
431         u32 reg, clock = 0;
432
433         /* identify the source of L4 SP clock */
434         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_L4SRC);
435         reg = (reg & CLKMGR_MAINPLLGRP_L4SRC_L4SP) >>
436               CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET;
437
438         if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) {
439                 clock = cm_get_main_vco_clk_hz();
440
441                 /* get the clock prior L4 SP divider (main clk) */
442                 reg = readl(socfpga_get_clkmgr_addr() +
443                             CLKMGR_GEN5_ALTR_MAINCLK);
444                 clock /= (reg + 1);
445                 reg = readl(socfpga_get_clkmgr_addr() +
446                             CLKMGR_GEN5_MAINPLL_MAINCLK);
447                 clock /= (reg + 1);
448         } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) {
449                 clock = cm_get_per_vco_clk_hz();
450
451                 /* get the clock prior L4 SP divider (periph_base_clk) */
452                 reg = readl(socfpga_get_clkmgr_addr() +
453                             CLKMGR_GEN5_PERPLL_PERBASECLK);
454                 clock /= (reg + 1);
455         }
456
457         /* get the L4 SP clock which supplied to UART */
458         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_MAINPLL_MAINDIV);
459         reg = (reg & CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK) >>
460               CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET;
461         clock = clock / (1 << reg);
462
463         return clock;
464 }
465
466 unsigned int cm_get_mmc_controller_clk_hz(void)
467 {
468         u32 reg, clock = 0;
469
470         /* identify the source of MMC clock */
471         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_SRC);
472         reg = (reg & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >>
473               CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET;
474
475         if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) {
476                 clock = cm_get_f2s_per_ref_clk_hz();
477         } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) {
478                 clock = cm_get_main_vco_clk_hz();
479
480                 /* get the SDMMC clock */
481                 reg = readl(socfpga_get_clkmgr_addr() +
482                             CLKMGR_GEN5_MAINPLL_MAINNANDSDMMCCLK);
483                 clock /= (reg + 1);
484         } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) {
485                 clock = cm_get_per_vco_clk_hz();
486
487                 /* get the SDMMC clock */
488                 reg = readl(socfpga_get_clkmgr_addr() +
489                             CLKMGR_GEN5_PERPLL_PERNANDSDMMCCLK);
490                 clock /= (reg + 1);
491         }
492
493         /* further divide by 4 as we have fixed divider at wrapper */
494         clock /= 4;
495         return clock;
496 }
497
498 unsigned int cm_get_qspi_controller_clk_hz(void)
499 {
500         u32 reg, clock = 0;
501
502         /* identify the source of QSPI clock */
503         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_SRC);
504         reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >>
505               CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET;
506
507         if (reg == CLKMGR_QSPI_CLK_SRC_F2S) {
508                 clock = cm_get_f2s_per_ref_clk_hz();
509         } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) {
510                 clock = cm_get_main_vco_clk_hz();
511
512                 /* get the qspi clock */
513                 reg = readl(socfpga_get_clkmgr_addr() +
514                             CLKMGR_GEN5_MAINPLL_MAINQSPICLK);
515                 clock /= (reg + 1);
516         } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) {
517                 clock = cm_get_per_vco_clk_hz();
518
519                 /* get the qspi clock */
520                 reg = readl(socfpga_get_clkmgr_addr() +
521                             CLKMGR_GEN5_PERPLL_PERQSPICLK);
522                 clock /= (reg + 1);
523         }
524
525         return clock;
526 }
527
528 unsigned int cm_get_spi_controller_clk_hz(void)
529 {
530         u32 reg, clock = 0;
531
532         clock = cm_get_per_vco_clk_hz();
533
534         /* get the clock prior L4 SP divider (periph_base_clk) */
535         reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_GEN5_PERPLL_PERBASECLK);
536         clock /= (reg + 1);
537
538         return clock;
539 }
540
541 /* Override weak dw_spi_get_clk implementation in designware_spi.c driver */
542 int dw_spi_get_clk(struct udevice *bus, ulong *rate)
543 {
544         *rate = cm_get_spi_controller_clk_hz();
545
546         return 0;
547 }
548
549 void cm_print_clock_quick_summary(void)
550 {
551         printf("MPU       %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);
552         printf("DDR       %10ld kHz\n", cm_get_sdram_clk_hz() / 1000);
553         printf("EOSC1       %8d kHz\n", cm_get_osc_clk_hz(1) / 1000);
554         printf("EOSC2       %8d kHz\n", cm_get_osc_clk_hz(2) / 1000);
555         printf("F2S_SDR_REF %8d kHz\n", cm_get_f2s_sdr_ref_clk_hz() / 1000);
556         printf("F2S_PER_REF %8d kHz\n", cm_get_f2s_per_ref_clk_hz() / 1000);
557         printf("MMC         %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
558         printf("QSPI        %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000);
559         printf("UART        %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
560         printf("SPI         %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000);
561 }
This page took 0.063819 seconds and 4 git commands to generate.