]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-socfpga/clock_manager_arria10.c
Merge git://git.denx.de/u-boot-mmc
[people/ms/u-boot.git] / arch / arm / mach-socfpga / clock_manager_arria10.c
1 /*
2 * Copyright (C) 2016-2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7 #include <common.h>
8 #include <fdtdec.h>
9 #include <asm/io.h>
10 #include <dm.h>
11 #include <asm/arch/clock_manager.h>
12
13 DECLARE_GLOBAL_DATA_PTR;
14
15 static u32 eosc1_hz;
16 static u32 cb_intosc_hz;
17 static u32 f2s_free_hz;
18 static u32 cm_l4_main_clk_hz;
19 static u32 cm_l4_sp_clk_hz;
20 static u32 cm_l4_mp_clk_hz;
21 static u32 cm_l4_sys_free_clk_hz;
22
23 struct mainpll_cfg {
24 u32 vco0_psrc;
25 u32 vco1_denom;
26 u32 vco1_numer;
27 u32 mpuclk;
28 u32 mpuclk_cnt;
29 u32 mpuclk_src;
30 u32 nocclk;
31 u32 nocclk_cnt;
32 u32 nocclk_src;
33 u32 cntr2clk_cnt;
34 u32 cntr3clk_cnt;
35 u32 cntr4clk_cnt;
36 u32 cntr5clk_cnt;
37 u32 cntr6clk_cnt;
38 u32 cntr7clk_cnt;
39 u32 cntr7clk_src;
40 u32 cntr8clk_cnt;
41 u32 cntr9clk_cnt;
42 u32 cntr9clk_src;
43 u32 cntr15clk_cnt;
44 u32 nocdiv_l4mainclk;
45 u32 nocdiv_l4mpclk;
46 u32 nocdiv_l4spclk;
47 u32 nocdiv_csatclk;
48 u32 nocdiv_cstraceclk;
49 u32 nocdiv_cspdbclk;
50 };
51
52 struct perpll_cfg {
53 u32 vco0_psrc;
54 u32 vco1_denom;
55 u32 vco1_numer;
56 u32 cntr2clk_cnt;
57 u32 cntr2clk_src;
58 u32 cntr3clk_cnt;
59 u32 cntr3clk_src;
60 u32 cntr4clk_cnt;
61 u32 cntr4clk_src;
62 u32 cntr5clk_cnt;
63 u32 cntr5clk_src;
64 u32 cntr6clk_cnt;
65 u32 cntr6clk_src;
66 u32 cntr7clk_cnt;
67 u32 cntr8clk_cnt;
68 u32 cntr8clk_src;
69 u32 cntr9clk_cnt;
70 u32 emacctl_emac0sel;
71 u32 emacctl_emac1sel;
72 u32 emacctl_emac2sel;
73 u32 gpiodiv_gpiodbclk;
74 };
75
76 struct alteragrp_cfg {
77 u32 nocclk;
78 u32 mpuclk;
79 };
80
81 static const struct socfpga_clock_manager *clock_manager_base =
82 (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
83
84 static int of_to_struct(const void *blob, int node, int cfg_len, void *cfg)
85 {
86 if (fdtdec_get_int_array(blob, node, "altr,of_reg_value",
87 (u32 *)cfg, cfg_len)) {
88 /* could not find required property */
89 return -EINVAL;
90 }
91
92 return 0;
93 }
94
95 static int of_get_input_clks(const void *blob, int node, u32 *val)
96 {
97 *val = fdtdec_get_uint(blob, node, "clock-frequency", 0);
98 if (!*val)
99 return -EINVAL;
100
101 return 0;
102 }
103
104 static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg,
105 struct perpll_cfg *per_cfg,
106 struct alteragrp_cfg *altrgrp_cfg)
107 {
108 int node, child, len;
109 const char *node_name;
110
111 node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK);
112 if (node < 0)
113 return -EINVAL;
114
115 child = fdt_first_subnode(blob, node);
116 if (child < 0)
117 return -EINVAL;
118
119 child = fdt_first_subnode(blob, child);
120 if (child < 0)
121 return -EINVAL;
122
123 node_name = fdt_get_name(blob, child, &len);
124
125 while (node_name) {
126 if (!strcmp(node_name, "osc1")) {
127 if (of_get_input_clks(blob, child, &eosc1_hz))
128 return -EINVAL;
129 } else if (!strcmp(node_name, "cb_intosc_ls_clk")) {
130 if (of_get_input_clks(blob, child, &cb_intosc_hz))
131 return -EINVAL;
132 } else if (!strcmp(node_name, "f2s_free_clk")) {
133 if (of_get_input_clks(blob, child, &f2s_free_hz))
134 return -EINVAL;
135 } else if (!strcmp(node_name, "main_pll")) {
136 if (of_to_struct(blob, child,
137 sizeof(*main_cfg)/sizeof(u32),
138 main_cfg))
139 return -EINVAL;
140 } else if (!strcmp(node_name, "periph_pll")) {
141 if (of_to_struct(blob, child,
142 sizeof(*per_cfg)/sizeof(u32),
143 per_cfg))
144 return -EINVAL;
145 } else if (!strcmp(node_name, "altera")) {
146 if (of_to_struct(blob, child,
147 sizeof(*altrgrp_cfg)/sizeof(u32),
148 altrgrp_cfg))
149 return -EINVAL;
150
151 main_cfg->mpuclk = altrgrp_cfg->mpuclk;
152 main_cfg->nocclk = altrgrp_cfg->nocclk;
153 }
154 child = fdt_next_subnode(blob, child);
155
156 if (child < 0)
157 break;
158
159 node_name = fdt_get_name(blob, child, &len);
160 }
161
162 return 0;
163 }
164
165 /* calculate the intended main VCO frequency based on handoff */
166 static unsigned int cm_calc_handoff_main_vco_clk_hz
167 (struct mainpll_cfg *main_cfg)
168 {
169 unsigned int clk_hz;
170
171 /* Check main VCO clock source: eosc, intosc or f2s? */
172 switch (main_cfg->vco0_psrc) {
173 case CLKMGR_MAINPLL_VCO0_PSRC_EOSC:
174 clk_hz = eosc1_hz;
175 break;
176 case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC:
177 clk_hz = cb_intosc_hz;
178 break;
179 case CLKMGR_MAINPLL_VCO0_PSRC_F2S:
180 clk_hz = f2s_free_hz;
181 break;
182 default:
183 return 0;
184 }
185
186 /* calculate the VCO frequency */
187 clk_hz /= 1 + main_cfg->vco1_denom;
188 clk_hz *= 1 + main_cfg->vco1_numer;
189
190 return clk_hz;
191 }
192
193 /* calculate the intended periph VCO frequency based on handoff */
194 static unsigned int cm_calc_handoff_periph_vco_clk_hz(
195 struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
196 {
197 unsigned int clk_hz;
198
199 /* Check periph VCO clock source: eosc, intosc, f2s or mainpll? */
200 switch (per_cfg->vco0_psrc) {
201 case CLKMGR_PERPLL_VCO0_PSRC_EOSC:
202 clk_hz = eosc1_hz;
203 break;
204 case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC:
205 clk_hz = cb_intosc_hz;
206 break;
207 case CLKMGR_PERPLL_VCO0_PSRC_F2S:
208 clk_hz = f2s_free_hz;
209 break;
210 case CLKMGR_PERPLL_VCO0_PSRC_MAIN:
211 clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
212 clk_hz /= main_cfg->cntr15clk_cnt;
213 break;
214 default:
215 return 0;
216 }
217
218 /* calculate the VCO frequency */
219 clk_hz /= 1 + per_cfg->vco1_denom;
220 clk_hz *= 1 + per_cfg->vco1_numer;
221
222 return clk_hz;
223 }
224
225 /* calculate the intended MPU clock frequency based on handoff */
226 static unsigned int cm_calc_handoff_mpu_clk_hz(struct mainpll_cfg *main_cfg,
227 struct perpll_cfg *per_cfg)
228 {
229 unsigned int clk_hz;
230
231 /* Check MPU clock source: main, periph, osc1, intosc or f2s? */
232 switch (main_cfg->mpuclk_src) {
233 case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN:
234 clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
235 clk_hz /= (main_cfg->mpuclk & CLKMGR_MAINPLL_MPUCLK_CNT_MSK)
236 + 1;
237 break;
238 case CLKMGR_MAINPLL_MPUCLK_SRC_PERI:
239 clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg);
240 clk_hz /= ((main_cfg->mpuclk >>
241 CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) &
242 CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1;
243 break;
244 case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1:
245 clk_hz = eosc1_hz;
246 break;
247 case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC:
248 clk_hz = cb_intosc_hz;
249 break;
250 case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA:
251 clk_hz = f2s_free_hz;
252 break;
253 default:
254 return 0;
255 }
256
257 clk_hz /= main_cfg->mpuclk_cnt + 1;
258 return clk_hz;
259 }
260
261 /* calculate the intended NOC clock frequency based on handoff */
262 static unsigned int cm_calc_handoff_noc_clk_hz(struct mainpll_cfg *main_cfg,
263 struct perpll_cfg *per_cfg)
264 {
265 unsigned int clk_hz;
266
267 /* Check MPU clock source: main, periph, osc1, intosc or f2s? */
268 switch (main_cfg->nocclk_src) {
269 case CLKMGR_MAINPLL_NOCCLK_SRC_MAIN:
270 clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
271 clk_hz /= (main_cfg->nocclk & CLKMGR_MAINPLL_NOCCLK_CNT_MSK)
272 + 1;
273 break;
274 case CLKMGR_MAINPLL_NOCCLK_SRC_PERI:
275 clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg);
276 clk_hz /= ((main_cfg->nocclk >>
277 CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) &
278 CLKMGR_MAINPLL_NOCCLK_CNT_MSK) + 1;
279 break;
280 case CLKMGR_MAINPLL_NOCCLK_SRC_OSC1:
281 clk_hz = eosc1_hz;
282 break;
283 case CLKMGR_MAINPLL_NOCCLK_SRC_INTOSC:
284 clk_hz = cb_intosc_hz;
285 break;
286 case CLKMGR_MAINPLL_NOCCLK_SRC_FPGA:
287 clk_hz = f2s_free_hz;
288 break;
289 default:
290 return 0;
291 }
292
293 clk_hz /= main_cfg->nocclk_cnt + 1;
294 return clk_hz;
295 }
296
297 /* return 1 if PLL ramp is required */
298 static int cm_is_pll_ramp_required(int main0periph1,
299 struct mainpll_cfg *main_cfg,
300 struct perpll_cfg *per_cfg)
301 {
302 /* Check for main PLL */
303 if (main0periph1 == 0) {
304 /*
305 * PLL ramp is not required if both MPU clock and NOC clock are
306 * not sourced from main PLL
307 */
308 if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_MAIN &&
309 main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_MAIN)
310 return 0;
311
312 /*
313 * PLL ramp is required if MPU clock is sourced from main PLL
314 * and MPU clock is over 900MHz (as advised by HW team)
315 */
316 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN &&
317 (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) >
318 CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ))
319 return 1;
320
321 /*
322 * PLL ramp is required if NOC clock is sourced from main PLL
323 * and NOC clock is over 300MHz (as advised by HW team)
324 */
325 if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN &&
326 (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) >
327 CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ))
328 return 2;
329
330 } else if (main0periph1 == 1) {
331 /*
332 * PLL ramp is not required if both MPU clock and NOC clock are
333 * not sourced from periph PLL
334 */
335 if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_PERI &&
336 main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_PERI)
337 return 0;
338
339 /*
340 * PLL ramp is required if MPU clock are source from periph PLL
341 * and MPU clock is over 900MHz (as advised by HW team)
342 */
343 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI &&
344 (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) >
345 CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ))
346 return 1;
347
348 /*
349 * PLL ramp is required if NOC clock are source from periph PLL
350 * and NOC clock is over 300MHz (as advised by HW team)
351 */
352 if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI &&
353 (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) >
354 CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ))
355 return 2;
356 }
357
358 return 0;
359 }
360
361 static u32 cm_calculate_numer(struct mainpll_cfg *main_cfg,
362 struct perpll_cfg *per_cfg,
363 u32 safe_hz, u32 clk_hz)
364 {
365 u32 cnt;
366 u32 clk;
367 u32 shift;
368 u32 mask;
369 u32 denom;
370
371 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) {
372 cnt = main_cfg->mpuclk_cnt;
373 clk = main_cfg->mpuclk;
374 shift = 0;
375 mask = CLKMGR_MAINPLL_MPUCLK_CNT_MSK;
376 denom = main_cfg->vco1_denom;
377 } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) {
378 cnt = main_cfg->nocclk_cnt;
379 clk = main_cfg->nocclk;
380 shift = 0;
381 mask = CLKMGR_MAINPLL_NOCCLK_CNT_MSK;
382 denom = main_cfg->vco1_denom;
383 } else if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) {
384 cnt = main_cfg->mpuclk_cnt;
385 clk = main_cfg->mpuclk;
386 shift = CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB;
387 mask = CLKMGR_MAINPLL_MPUCLK_CNT_MSK;
388 denom = per_cfg->vco1_denom;
389 } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) {
390 cnt = main_cfg->nocclk_cnt;
391 clk = main_cfg->nocclk;
392 shift = CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB;
393 mask = CLKMGR_MAINPLL_NOCCLK_CNT_MSK;
394 denom = per_cfg->vco1_denom;
395 } else {
396 return 0;
397 }
398
399 return (safe_hz / clk_hz) * (cnt + 1) * (((clk >> shift) & mask) + 1) *
400 (1 + denom) - 1;
401 }
402
403 /*
404 * Calculate the new PLL numerator which is based on existing DTS hand off and
405 * intended safe frequency (safe_hz). Note that PLL ramp is only modifying the
406 * numerator while maintaining denominator as denominator will influence the
407 * jitter condition. Please refer A10 HPS TRM for the jitter guide. Note final
408 * value for numerator is minus with 1 to cater our register value
409 * representation.
410 */
411 static unsigned int cm_calc_safe_pll_numer(int main0periph1,
412 struct mainpll_cfg *main_cfg,
413 struct perpll_cfg *per_cfg,
414 unsigned int safe_hz)
415 {
416 unsigned int clk_hz = 0;
417
418 /* Check for main PLL */
419 if (main0periph1 == 0) {
420 /* Check main VCO clock source: eosc, intosc or f2s? */
421 switch (main_cfg->vco0_psrc) {
422 case CLKMGR_MAINPLL_VCO0_PSRC_EOSC:
423 clk_hz = eosc1_hz;
424 break;
425 case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC:
426 clk_hz = cb_intosc_hz;
427 break;
428 case CLKMGR_MAINPLL_VCO0_PSRC_F2S:
429 clk_hz = f2s_free_hz;
430 break;
431 default:
432 return 0;
433 }
434 } else if (main0periph1 == 1) {
435 /* Check periph VCO clock source: eosc, intosc, f2s, mainpll */
436 switch (per_cfg->vco0_psrc) {
437 case CLKMGR_PERPLL_VCO0_PSRC_EOSC:
438 clk_hz = eosc1_hz;
439 break;
440 case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC:
441 clk_hz = cb_intosc_hz;
442 break;
443 case CLKMGR_PERPLL_VCO0_PSRC_F2S:
444 clk_hz = f2s_free_hz;
445 break;
446 case CLKMGR_PERPLL_VCO0_PSRC_MAIN:
447 clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
448 clk_hz /= main_cfg->cntr15clk_cnt;
449 break;
450 default:
451 return 0;
452 }
453 } else {
454 return 0;
455 }
456
457 return cm_calculate_numer(main_cfg, per_cfg, safe_hz, clk_hz);
458 }
459
460 /* ramping the main PLL to final value */
461 static void cm_pll_ramp_main(struct mainpll_cfg *main_cfg,
462 struct perpll_cfg *per_cfg,
463 unsigned int pll_ramp_main_hz)
464 {
465 unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0;
466
467 /* find out the increment value */
468 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) {
469 clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ;
470 clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg);
471 } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) {
472 clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ;
473 clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg);
474 }
475
476 /* execute the ramping here */
477 for (clk_hz = pll_ramp_main_hz + clk_incr_hz;
478 clk_hz < clk_final_hz; clk_hz += clk_incr_hz) {
479 writel((main_cfg->vco1_denom <<
480 CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
481 cm_calc_safe_pll_numer(0, main_cfg, per_cfg, clk_hz),
482 &clock_manager_base->main_pll.vco1);
483 mdelay(1);
484 cm_wait_for_lock(LOCKED_MASK);
485 }
486 writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
487 main_cfg->vco1_numer, &clock_manager_base->main_pll.vco1);
488 mdelay(1);
489 cm_wait_for_lock(LOCKED_MASK);
490 }
491
492 /* ramping the periph PLL to final value */
493 static void cm_pll_ramp_periph(struct mainpll_cfg *main_cfg,
494 struct perpll_cfg *per_cfg,
495 unsigned int pll_ramp_periph_hz)
496 {
497 unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0;
498
499 /* find out the increment value */
500 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) {
501 clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ;
502 clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg);
503 } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) {
504 clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ;
505 clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg);
506 }
507 /* execute the ramping here */
508 for (clk_hz = pll_ramp_periph_hz + clk_incr_hz;
509 clk_hz < clk_final_hz; clk_hz += clk_incr_hz) {
510 writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
511 cm_calc_safe_pll_numer(1, main_cfg, per_cfg, clk_hz),
512 &clock_manager_base->per_pll.vco1);
513 mdelay(1);
514 cm_wait_for_lock(LOCKED_MASK);
515 }
516 writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
517 per_cfg->vco1_numer, &clock_manager_base->per_pll.vco1);
518 mdelay(1);
519 cm_wait_for_lock(LOCKED_MASK);
520 }
521
522 /*
523 * Setup clocks while making no assumptions of the
524 * previous state of the clocks.
525 *
526 * Start by being paranoid and gate all sw managed clocks
527 *
528 * Put all plls in bypass
529 *
530 * Put all plls VCO registers back to reset value (bgpwr dwn).
531 *
532 * Put peripheral and main pll src to reset value to avoid glitch.
533 *
534 * Delay 5 us.
535 *
536 * Deassert bg pwr dn and set numerator and denominator
537 *
538 * Start 7 us timer.
539 *
540 * set internal dividers
541 *
542 * Wait for 7 us timer.
543 *
544 * Enable plls
545 *
546 * Set external dividers while plls are locking
547 *
548 * Wait for pll lock
549 *
550 * Assert/deassert outreset all.
551 *
552 * Take all pll's out of bypass
553 *
554 * Clear safe mode
555 *
556 * set source main and peripheral clocks
557 *
558 * Ungate clocks
559 */
560
561 static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
562 {
563 unsigned int pll_ramp_main_hz = 0, pll_ramp_periph_hz = 0,
564 ramp_required;
565
566 /* gate off all mainpll clock excpet HW managed clock */
567 writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK |
568 CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK,
569 &clock_manager_base->main_pll.enr);
570
571 /* now we can gate off the rest of the peripheral clocks */
572 writel(0, &clock_manager_base->per_pll.en);
573
574 /* Put all plls in external bypass */
575 writel(CLKMGR_MAINPLL_BYPASS_RESET,
576 &clock_manager_base->main_pll.bypasss);
577 writel(CLKMGR_PERPLL_BYPASS_RESET,
578 &clock_manager_base->per_pll.bypasss);
579
580 /*
581 * Put all plls VCO registers back to reset value.
582 * Some code might have messed with them. At same time set the
583 * desired clock source
584 */
585 writel(CLKMGR_MAINPLL_VCO0_RESET |
586 CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK |
587 (main_cfg->vco0_psrc << CLKMGR_MAINPLL_VCO0_PSRC_LSB),
588 &clock_manager_base->main_pll.vco0);
589
590 writel(CLKMGR_PERPLL_VCO0_RESET |
591 CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK |
592 (per_cfg->vco0_psrc << CLKMGR_PERPLL_VCO0_PSRC_LSB),
593 &clock_manager_base->per_pll.vco0);
594
595 writel(CLKMGR_MAINPLL_VCO1_RESET, &clock_manager_base->main_pll.vco1);
596 writel(CLKMGR_PERPLL_VCO1_RESET, &clock_manager_base->per_pll.vco1);
597
598 /* clear the interrupt register status register */
599 writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK |
600 CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK |
601 CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK |
602 CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK |
603 CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK |
604 CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK |
605 CLKMGR_CLKMGR_INTR_MAINPLLACHIEVED_SET_MSK |
606 CLKMGR_CLKMGR_INTR_PERPLLACHIEVED_SET_MSK,
607 &clock_manager_base->intr);
608
609 /* Program VCO Numerator and Denominator for main PLL */
610 ramp_required = cm_is_pll_ramp_required(0, main_cfg, per_cfg);
611 if (ramp_required) {
612 /* set main PLL to safe starting threshold frequency */
613 if (ramp_required == 1)
614 pll_ramp_main_hz = CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ;
615 else if (ramp_required == 2)
616 pll_ramp_main_hz = CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ;
617
618 writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
619 cm_calc_safe_pll_numer(0, main_cfg, per_cfg,
620 pll_ramp_main_hz),
621 &clock_manager_base->main_pll.vco1);
622 } else
623 writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
624 main_cfg->vco1_numer,
625 &clock_manager_base->main_pll.vco1);
626
627 /* Program VCO Numerator and Denominator for periph PLL */
628 ramp_required = cm_is_pll_ramp_required(1, main_cfg, per_cfg);
629 if (ramp_required) {
630 /* set periph PLL to safe starting threshold frequency */
631 if (ramp_required == 1)
632 pll_ramp_periph_hz =
633 CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ;
634 else if (ramp_required == 2)
635 pll_ramp_periph_hz =
636 CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ;
637
638 writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
639 cm_calc_safe_pll_numer(1, main_cfg, per_cfg,
640 pll_ramp_periph_hz),
641 &clock_manager_base->per_pll.vco1);
642 } else
643 writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
644 per_cfg->vco1_numer,
645 &clock_manager_base->per_pll.vco1);
646
647 /* Wait for at least 5 us */
648 udelay(5);
649
650 /* Now deassert BGPWRDN and PWRDN */
651 clrbits_le32(&clock_manager_base->main_pll.vco0,
652 CLKMGR_MAINPLL_VCO0_BGPWRDN_SET_MSK |
653 CLKMGR_MAINPLL_VCO0_PWRDN_SET_MSK);
654 clrbits_le32(&clock_manager_base->per_pll.vco0,
655 CLKMGR_PERPLL_VCO0_BGPWRDN_SET_MSK |
656 CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK);
657
658 /* Wait for at least 7 us */
659 udelay(7);
660
661 /* enable the VCO and disable the external regulator to PLL */
662 writel((readl(&clock_manager_base->main_pll.vco0) &
663 ~CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK) |
664 CLKMGR_MAINPLL_VCO0_EN_SET_MSK,
665 &clock_manager_base->main_pll.vco0);
666 writel((readl(&clock_manager_base->per_pll.vco0) &
667 ~CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK) |
668 CLKMGR_PERPLL_VCO0_EN_SET_MSK,
669 &clock_manager_base->per_pll.vco0);
670
671 /* setup all the main PLL counter and clock source */
672 writel(main_cfg->nocclk,
673 SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOC_CLK_OFFSET);
674 writel(main_cfg->mpuclk,
675 SOCFPGA_CLKMGR_ADDRESS + CLKMGR_ALTERAGRP_MPU_CLK_OFFSET);
676
677 /* main_emaca_clk divider */
678 writel(main_cfg->cntr2clk_cnt, &clock_manager_base->main_pll.cntr2clk);
679 /* main_emacb_clk divider */
680 writel(main_cfg->cntr3clk_cnt, &clock_manager_base->main_pll.cntr3clk);
681 /* main_emac_ptp_clk divider */
682 writel(main_cfg->cntr4clk_cnt, &clock_manager_base->main_pll.cntr4clk);
683 /* main_gpio_db_clk divider */
684 writel(main_cfg->cntr5clk_cnt, &clock_manager_base->main_pll.cntr5clk);
685 /* main_sdmmc_clk divider */
686 writel(main_cfg->cntr6clk_cnt, &clock_manager_base->main_pll.cntr6clk);
687 /* main_s2f_user0_clk divider */
688 writel(main_cfg->cntr7clk_cnt |
689 (main_cfg->cntr7clk_src << CLKMGR_MAINPLL_CNTR7CLK_SRC_LSB),
690 &clock_manager_base->main_pll.cntr7clk);
691 /* main_s2f_user1_clk divider */
692 writel(main_cfg->cntr8clk_cnt, &clock_manager_base->main_pll.cntr8clk);
693 /* main_hmc_pll_clk divider */
694 writel(main_cfg->cntr9clk_cnt |
695 (main_cfg->cntr9clk_src << CLKMGR_MAINPLL_CNTR9CLK_SRC_LSB),
696 &clock_manager_base->main_pll.cntr9clk);
697 /* main_periph_ref_clk divider */
698 writel(main_cfg->cntr15clk_cnt,
699 &clock_manager_base->main_pll.cntr15clk);
700
701 /* setup all the peripheral PLL counter and clock source */
702 /* peri_emaca_clk divider */
703 writel(per_cfg->cntr2clk_cnt |
704 (per_cfg->cntr2clk_src << CLKMGR_PERPLL_CNTR2CLK_SRC_LSB),
705 &clock_manager_base->per_pll.cntr2clk);
706 /* peri_emacb_clk divider */
707 writel(per_cfg->cntr3clk_cnt |
708 (per_cfg->cntr3clk_src << CLKMGR_PERPLL_CNTR3CLK_SRC_LSB),
709 &clock_manager_base->per_pll.cntr3clk);
710 /* peri_emac_ptp_clk divider */
711 writel(per_cfg->cntr4clk_cnt |
712 (per_cfg->cntr4clk_src << CLKMGR_PERPLL_CNTR4CLK_SRC_LSB),
713 &clock_manager_base->per_pll.cntr4clk);
714 /* peri_gpio_db_clk divider */
715 writel(per_cfg->cntr5clk_cnt |
716 (per_cfg->cntr5clk_src << CLKMGR_PERPLL_CNTR5CLK_SRC_LSB),
717 &clock_manager_base->per_pll.cntr5clk);
718 /* peri_sdmmc_clk divider */
719 writel(per_cfg->cntr6clk_cnt |
720 (per_cfg->cntr6clk_src << CLKMGR_PERPLL_CNTR6CLK_SRC_LSB),
721 &clock_manager_base->per_pll.cntr6clk);
722 /* peri_s2f_user0_clk divider */
723 writel(per_cfg->cntr7clk_cnt, &clock_manager_base->per_pll.cntr7clk);
724 /* peri_s2f_user1_clk divider */
725 writel(per_cfg->cntr8clk_cnt |
726 (per_cfg->cntr8clk_src << CLKMGR_PERPLL_CNTR8CLK_SRC_LSB),
727 &clock_manager_base->per_pll.cntr8clk);
728 /* peri_hmc_pll_clk divider */
729 writel(per_cfg->cntr9clk_cnt, &clock_manager_base->per_pll.cntr9clk);
730
731 /* setup all the external PLL counter */
732 /* mpu wrapper / external divider */
733 writel(main_cfg->mpuclk_cnt |
734 (main_cfg->mpuclk_src << CLKMGR_MAINPLL_MPUCLK_SRC_LSB),
735 &clock_manager_base->main_pll.mpuclk);
736 /* NOC wrapper / external divider */
737 writel(main_cfg->nocclk_cnt |
738 (main_cfg->nocclk_src << CLKMGR_MAINPLL_NOCCLK_SRC_LSB),
739 &clock_manager_base->main_pll.nocclk);
740 /* NOC subclock divider such as l4 */
741 writel(main_cfg->nocdiv_l4mainclk |
742 (main_cfg->nocdiv_l4mpclk <<
743 CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) |
744 (main_cfg->nocdiv_l4spclk <<
745 CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB) |
746 (main_cfg->nocdiv_csatclk <<
747 CLKMGR_MAINPLL_NOCDIV_CSATCLK_LSB) |
748 (main_cfg->nocdiv_cstraceclk <<
749 CLKMGR_MAINPLL_NOCDIV_CSTRACECLK_LSB) |
750 (main_cfg->nocdiv_cspdbclk <<
751 CLKMGR_MAINPLL_NOCDIV_CSPDBGCLK_LSB),
752 &clock_manager_base->main_pll.nocdiv);
753 /* gpio_db external divider */
754 writel(per_cfg->gpiodiv_gpiodbclk,
755 &clock_manager_base->per_pll.gpiodiv);
756
757 /* setup the EMAC clock mux select */
758 writel((per_cfg->emacctl_emac0sel <<
759 CLKMGR_PERPLL_EMACCTL_EMAC0SEL_LSB) |
760 (per_cfg->emacctl_emac1sel <<
761 CLKMGR_PERPLL_EMACCTL_EMAC1SEL_LSB) |
762 (per_cfg->emacctl_emac2sel <<
763 CLKMGR_PERPLL_EMACCTL_EMAC2SEL_LSB),
764 &clock_manager_base->per_pll.emacctl);
765
766 /* at this stage, check for PLL lock status */
767 cm_wait_for_lock(LOCKED_MASK);
768
769 /*
770 * after locking, but before taking out of bypass,
771 * assert/deassert outresetall
772 */
773 /* assert mainpll outresetall */
774 setbits_le32(&clock_manager_base->main_pll.vco0,
775 CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK);
776 /* assert perpll outresetall */
777 setbits_le32(&clock_manager_base->per_pll.vco0,
778 CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK);
779 /* de-assert mainpll outresetall */
780 clrbits_le32(&clock_manager_base->main_pll.vco0,
781 CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK);
782 /* de-assert perpll outresetall */
783 clrbits_le32(&clock_manager_base->per_pll.vco0,
784 CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK);
785
786 /* Take all PLLs out of bypass when boot mode is cleared. */
787 /* release mainpll from bypass */
788 writel(CLKMGR_MAINPLL_BYPASS_RESET,
789 &clock_manager_base->main_pll.bypassr);
790 /* wait till Clock Manager is not busy */
791 cm_wait_for_fsm();
792
793 /* release perpll from bypass */
794 writel(CLKMGR_PERPLL_BYPASS_RESET,
795 &clock_manager_base->per_pll.bypassr);
796 /* wait till Clock Manager is not busy */
797 cm_wait_for_fsm();
798
799 /* clear boot mode */
800 clrbits_le32(&clock_manager_base->ctrl,
801 CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK);
802 /* wait till Clock Manager is not busy */
803 cm_wait_for_fsm();
804
805 /* At here, we need to ramp to final value if needed */
806 if (pll_ramp_main_hz != 0)
807 cm_pll_ramp_main(main_cfg, per_cfg, pll_ramp_main_hz);
808 if (pll_ramp_periph_hz != 0)
809 cm_pll_ramp_periph(main_cfg, per_cfg, pll_ramp_periph_hz);
810
811 /* Now ungate non-hw-managed clocks */
812 writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK |
813 CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK,
814 &clock_manager_base->main_pll.ens);
815 writel(CLKMGR_PERPLL_EN_RESET, &clock_manager_base->per_pll.ens);
816
817 /* Clear the loss lock and slip bits as they might set during
818 clock reconfiguration */
819 writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK |
820 CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK |
821 CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK |
822 CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK |
823 CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK |
824 CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK,
825 &clock_manager_base->intr);
826
827 return 0;
828 }
829
830 void cm_use_intosc(void)
831 {
832 setbits_le32(&clock_manager_base->ctrl,
833 CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK);
834 }
835
836 unsigned int cm_get_noc_clk_hz(void)
837 {
838 unsigned int clk_src, divisor, nocclk, src_hz;
839
840 nocclk = readl(&clock_manager_base->main_pll.nocclk);
841 clk_src = (nocclk >> CLKMGR_MAINPLL_NOCCLK_SRC_LSB) &
842 CLKMGR_MAINPLL_NOCCLK_SRC_MSK;
843
844 divisor = 1 + (nocclk & CLKMGR_MAINPLL_NOCDIV_MSK);
845
846 if (clk_src == CLKMGR_PERPLLGRP_SRC_MAIN) {
847 src_hz = cm_get_main_vco_clk_hz();
848 src_hz /= 1 +
849 (readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOC_CLK_OFFSET) &
850 CLKMGR_MAINPLL_NOCCLK_CNT_MSK);
851 } else if (clk_src == CLKMGR_PERPLLGRP_SRC_PERI) {
852 src_hz = cm_get_per_vco_clk_hz();
853 src_hz /= 1 +
854 ((readl(SOCFPGA_CLKMGR_ADDRESS +
855 CLKMGR_MAINPLL_NOC_CLK_OFFSET) >>
856 CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) &
857 CLKMGR_MAINPLL_NOCCLK_CNT_MSK);
858 } else if (clk_src == CLKMGR_PERPLLGRP_SRC_OSC1) {
859 src_hz = eosc1_hz;
860 } else if (clk_src == CLKMGR_PERPLLGRP_SRC_INTOSC) {
861 src_hz = cb_intosc_hz;
862 } else if (clk_src == CLKMGR_PERPLLGRP_SRC_FPGA) {
863 src_hz = f2s_free_hz;
864 } else {
865 src_hz = 0;
866 }
867
868 return src_hz / divisor;
869 }
870
871 unsigned int cm_get_l4_noc_hz(unsigned int nocdivshift)
872 {
873 unsigned int divisor2 = 1 <<
874 ((readl(&clock_manager_base->main_pll.nocdiv) >>
875 nocdivshift) & CLKMGR_MAINPLL_NOCDIV_MSK);
876
877 return cm_get_noc_clk_hz() / divisor2;
878 }
879
880 int cm_basic_init(const void *blob)
881 {
882 struct mainpll_cfg main_cfg;
883 struct perpll_cfg per_cfg;
884 struct alteragrp_cfg altrgrp_cfg;
885 int rval;
886
887 /* initialize to zero for use case of optional node */
888 memset(&main_cfg, 0, sizeof(main_cfg));
889 memset(&per_cfg, 0, sizeof(per_cfg));
890 memset(&altrgrp_cfg, 0, sizeof(altrgrp_cfg));
891
892 rval = of_get_clk_cfg(blob, &main_cfg, &per_cfg, &altrgrp_cfg);
893 if (rval)
894 return rval;
895
896 rval = cm_full_cfg(&main_cfg, &per_cfg);
897
898 cm_l4_main_clk_hz =
899 cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB);
900
901 cm_l4_mp_clk_hz = cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB);
902
903 cm_l4_sp_clk_hz = cm_get_l4_sp_clk_hz();
904
905 cm_l4_sys_free_clk_hz = cm_get_noc_clk_hz() / 4;
906
907 return rval;
908 }
909
910 unsigned long cm_get_mpu_clk_hz(void)
911 {
912 u32 reg, clk_hz;
913 u32 clk_src, mainmpuclk_reg;
914
915 mainmpuclk_reg = readl(&clock_manager_base->main_pll.mpuclk);
916
917 clk_src = (mainmpuclk_reg >> CLKMGR_MAINPLL_MPUCLK_SRC_LSB) &
918 CLKMGR_MAINPLL_MPUCLK_SRC_MSK;
919
920 reg = readl(&clock_manager_base->altera.mpuclk);
921 /* Check MPU clock source: main, periph, osc1, intosc or f2s? */
922 switch (clk_src) {
923 case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN:
924 clk_hz = cm_get_main_vco_clk_hz();
925 clk_hz /= (reg & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1;
926 break;
927 case CLKMGR_MAINPLL_MPUCLK_SRC_PERI:
928 clk_hz = cm_get_per_vco_clk_hz();
929 clk_hz /= (((reg >> CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) &
930 CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1);
931 break;
932 case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1:
933 clk_hz = eosc1_hz;
934 break;
935 case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC:
936 clk_hz = cb_intosc_hz;
937 break;
938 case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA:
939 clk_hz = f2s_free_hz;
940 break;
941 default:
942 printf("cm_get_mpu_clk_hz invalid clk_src %d\n", clk_src);
943 return 0;
944 }
945
946 clk_hz /= (mainmpuclk_reg & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1;
947
948 return clk_hz;
949 }
950
951 unsigned int cm_get_per_vco_clk_hz(void)
952 {
953 u32 src_hz = 0;
954 u32 clk_src = 0;
955 u32 numer = 0;
956 u32 denom = 0;
957 u32 vco = 0;
958
959 clk_src = readl(&clock_manager_base->per_pll.vco0);
960
961 clk_src = (clk_src >> CLKMGR_PERPLL_VCO0_PSRC_LSB) &
962 CLKMGR_PERPLL_VCO0_PSRC_MSK;
963
964 if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_EOSC) {
965 src_hz = eosc1_hz;
966 } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC) {
967 src_hz = cb_intosc_hz;
968 } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_F2S) {
969 src_hz = f2s_free_hz;
970 } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_MAIN) {
971 src_hz = cm_get_main_vco_clk_hz();
972 src_hz /= (readl(&clock_manager_base->main_pll.cntr15clk) &
973 CLKMGR_MAINPLL_CNTRCLK_MSK) + 1;
974 } else {
975 printf("cm_get_per_vco_clk_hz invalid clk_src %d\n", clk_src);
976 return 0;
977 }
978
979 vco = readl(&clock_manager_base->per_pll.vco1);
980
981 numer = vco & CLKMGR_PERPLL_VCO1_NUMER_MSK;
982
983 denom = (vco >> CLKMGR_PERPLL_VCO1_DENOM_LSB) &
984 CLKMGR_PERPLL_VCO1_DENOM_MSK;
985
986 vco = src_hz;
987 vco /= 1 + denom;
988 vco *= 1 + numer;
989
990 return vco;
991 }
992
993 unsigned int cm_get_main_vco_clk_hz(void)
994 {
995 u32 src_hz, numer, denom, vco;
996
997 u32 clk_src = readl(&clock_manager_base->main_pll.vco0);
998
999 clk_src = (clk_src >> CLKMGR_MAINPLL_VCO0_PSRC_LSB) &
1000 CLKMGR_MAINPLL_VCO0_PSRC_MSK;
1001
1002 if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_EOSC) {
1003 src_hz = eosc1_hz;
1004 } else if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC) {
1005 src_hz = cb_intosc_hz;
1006 } else if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_F2S) {
1007 src_hz = f2s_free_hz;
1008 } else {
1009 printf("cm_get_main_vco_clk_hz invalid clk_src %d\n", clk_src);
1010 return 0;
1011 }
1012
1013 vco = readl(&clock_manager_base->main_pll.vco1);
1014
1015 numer = vco & CLKMGR_MAINPLL_VCO1_NUMER_MSK;
1016
1017 denom = (vco >> CLKMGR_MAINPLL_VCO1_DENOM_LSB) &
1018 CLKMGR_MAINPLL_VCO1_DENOM_MSK;
1019
1020 vco = src_hz;
1021 vco /= 1 + denom;
1022 vco *= 1 + numer;
1023
1024 return vco;
1025 }
1026
1027 unsigned int cm_get_l4_sp_clk_hz(void)
1028 {
1029 return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB);
1030 }
1031
1032 unsigned int cm_get_mmc_controller_clk_hz(void)
1033 {
1034 u32 clk_hz = 0;
1035 u32 clk_input = 0;
1036
1037 clk_input = readl(&clock_manager_base->per_pll.cntr6clk);
1038 clk_input = (clk_input >> CLKMGR_PERPLL_CNTR6CLK_SRC_LSB) &
1039 CLKMGR_PERPLLGRP_SRC_MSK;
1040
1041 switch (clk_input) {
1042 case CLKMGR_PERPLLGRP_SRC_MAIN:
1043 clk_hz = cm_get_main_vco_clk_hz();
1044 clk_hz /= 1 + (readl(&clock_manager_base->main_pll.cntr6clk) &
1045 CLKMGR_MAINPLL_CNTRCLK_MSK);
1046 break;
1047
1048 case CLKMGR_PERPLLGRP_SRC_PERI:
1049 clk_hz = cm_get_per_vco_clk_hz();
1050 clk_hz /= 1 + (readl(&clock_manager_base->per_pll.cntr6clk) &
1051 CLKMGR_PERPLL_CNTRCLK_MSK);
1052 break;
1053
1054 case CLKMGR_PERPLLGRP_SRC_OSC1:
1055 clk_hz = eosc1_hz;
1056 break;
1057
1058 case CLKMGR_PERPLLGRP_SRC_INTOSC:
1059 clk_hz = cb_intosc_hz;
1060 break;
1061
1062 case CLKMGR_PERPLLGRP_SRC_FPGA:
1063 clk_hz = f2s_free_hz;
1064 break;
1065 }
1066
1067 return clk_hz / 4;
1068 }
1069
1070 unsigned int cm_get_spi_controller_clk_hz(void)
1071 {
1072 return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB);
1073 }
1074
1075 unsigned int cm_get_qspi_controller_clk_hz(void)
1076 {
1077 return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB);
1078 }
1079
1080 /* Override weak dw_spi_get_clk implementation in designware_spi.c driver */
1081 int dw_spi_get_clk(struct udevice *bus, ulong *rate)
1082 {
1083 *rate = cm_get_spi_controller_clk_hz();
1084
1085 return 0;
1086 }
1087
1088 void cm_print_clock_quick_summary(void)
1089 {
1090 printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);
1091 printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
1092 printf("QSPI %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000);
1093 printf("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000);
1094 printf("EOSC1 %8d kHz\n", eosc1_hz / 1000);
1095 printf("cb_intosc %8d kHz\n", cb_intosc_hz / 1000);
1096 printf("f2s_free %8d kHz\n", f2s_free_hz / 1000);
1097 printf("Main VCO %8d kHz\n", cm_get_main_vco_clk_hz() / 1000);
1098 printf("NOC %8d kHz\n", cm_get_noc_clk_hz() / 1000);
1099 printf("L4 Main %8d kHz\n",
1100 cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB) / 1000);
1101 printf("L4 MP %8d kHz\n",
1102 cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) / 1000);
1103 printf("L4 SP %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
1104 printf("L4 sys free %8d kHz\n", cm_l4_sys_free_clk_hz / 1000);
1105 }