1
2
3
4
5
6#include <common.h>
7#include <fdtdec.h>
8#include <asm/io.h>
9#include <dm.h>
10#include <clk.h>
11#include <dm/device-internal.h>
12#include <asm/arch/clock_manager.h>
13
14#ifdef CONFIG_SPL_BUILD
15
16static u32 eosc1_hz;
17static u32 cb_intosc_hz;
18static u32 f2s_free_hz;
19
20struct mainpll_cfg {
21 u32 vco0_psrc;
22 u32 vco1_denom;
23 u32 vco1_numer;
24 u32 mpuclk;
25 u32 mpuclk_cnt;
26 u32 mpuclk_src;
27 u32 nocclk;
28 u32 nocclk_cnt;
29 u32 nocclk_src;
30 u32 cntr2clk_cnt;
31 u32 cntr3clk_cnt;
32 u32 cntr4clk_cnt;
33 u32 cntr5clk_cnt;
34 u32 cntr6clk_cnt;
35 u32 cntr7clk_cnt;
36 u32 cntr7clk_src;
37 u32 cntr8clk_cnt;
38 u32 cntr9clk_cnt;
39 u32 cntr9clk_src;
40 u32 cntr15clk_cnt;
41 u32 nocdiv_l4mainclk;
42 u32 nocdiv_l4mpclk;
43 u32 nocdiv_l4spclk;
44 u32 nocdiv_csatclk;
45 u32 nocdiv_cstraceclk;
46 u32 nocdiv_cspdbclk;
47};
48
49struct perpll_cfg {
50 u32 vco0_psrc;
51 u32 vco1_denom;
52 u32 vco1_numer;
53 u32 cntr2clk_cnt;
54 u32 cntr2clk_src;
55 u32 cntr3clk_cnt;
56 u32 cntr3clk_src;
57 u32 cntr4clk_cnt;
58 u32 cntr4clk_src;
59 u32 cntr5clk_cnt;
60 u32 cntr5clk_src;
61 u32 cntr6clk_cnt;
62 u32 cntr6clk_src;
63 u32 cntr7clk_cnt;
64 u32 cntr8clk_cnt;
65 u32 cntr8clk_src;
66 u32 cntr9clk_cnt;
67 u32 cntr9clk_src;
68 u32 emacctl_emac0sel;
69 u32 emacctl_emac1sel;
70 u32 emacctl_emac2sel;
71 u32 gpiodiv_gpiodbclk;
72};
73
74struct strtou32 {
75 const char *str;
76 const u32 val;
77};
78
79static const struct strtou32 mainpll_cfg_tab[] = {
80 { "vco0-psrc", offsetof(struct mainpll_cfg, vco0_psrc) },
81 { "vco1-denom", offsetof(struct mainpll_cfg, vco1_denom) },
82 { "vco1-numer", offsetof(struct mainpll_cfg, vco1_numer) },
83 { "mpuclk-cnt", offsetof(struct mainpll_cfg, mpuclk_cnt) },
84 { "mpuclk-src", offsetof(struct mainpll_cfg, mpuclk_src) },
85 { "nocclk-cnt", offsetof(struct mainpll_cfg, nocclk_cnt) },
86 { "nocclk-src", offsetof(struct mainpll_cfg, nocclk_src) },
87 { "cntr2clk-cnt", offsetof(struct mainpll_cfg, cntr2clk_cnt) },
88 { "cntr3clk-cnt", offsetof(struct mainpll_cfg, cntr3clk_cnt) },
89 { "cntr4clk-cnt", offsetof(struct mainpll_cfg, cntr4clk_cnt) },
90 { "cntr5clk-cnt", offsetof(struct mainpll_cfg, cntr5clk_cnt) },
91 { "cntr6clk-cnt", offsetof(struct mainpll_cfg, cntr6clk_cnt) },
92 { "cntr7clk-cnt", offsetof(struct mainpll_cfg, cntr7clk_cnt) },
93 { "cntr7clk-src", offsetof(struct mainpll_cfg, cntr7clk_src) },
94 { "cntr8clk-cnt", offsetof(struct mainpll_cfg, cntr8clk_cnt) },
95 { "cntr9clk-cnt", offsetof(struct mainpll_cfg, cntr9clk_cnt) },
96 { "cntr9clk-src", offsetof(struct mainpll_cfg, cntr9clk_src) },
97 { "cntr15clk-cnt", offsetof(struct mainpll_cfg, cntr15clk_cnt) },
98 { "nocdiv-l4mainclk", offsetof(struct mainpll_cfg, nocdiv_l4mainclk) },
99 { "nocdiv-l4mpclk", offsetof(struct mainpll_cfg, nocdiv_l4mpclk) },
100 { "nocdiv-l4spclk", offsetof(struct mainpll_cfg, nocdiv_l4spclk) },
101 { "nocdiv-csatclk", offsetof(struct mainpll_cfg, nocdiv_csatclk) },
102 { "nocdiv-cstraceclk", offsetof(struct mainpll_cfg, nocdiv_cstraceclk) },
103 { "nocdiv-cspdbgclk", offsetof(struct mainpll_cfg, nocdiv_cspdbclk) },
104};
105
106static const struct strtou32 perpll_cfg_tab[] = {
107 { "vco0-psrc", offsetof(struct perpll_cfg, vco0_psrc) },
108 { "vco1-denom", offsetof(struct perpll_cfg, vco1_denom) },
109 { "vco1-numer", offsetof(struct perpll_cfg, vco1_numer) },
110 { "cntr2clk-cnt", offsetof(struct perpll_cfg, cntr2clk_cnt) },
111 { "cntr2clk-src", offsetof(struct perpll_cfg, cntr2clk_src) },
112 { "cntr3clk-cnt", offsetof(struct perpll_cfg, cntr3clk_cnt) },
113 { "cntr3clk-src", offsetof(struct perpll_cfg, cntr3clk_src) },
114 { "cntr4clk-cnt", offsetof(struct perpll_cfg, cntr4clk_cnt) },
115 { "cntr4clk-src", offsetof(struct perpll_cfg, cntr4clk_src) },
116 { "cntr5clk-cnt", offsetof(struct perpll_cfg, cntr5clk_cnt) },
117 { "cntr5clk-src", offsetof(struct perpll_cfg, cntr5clk_src) },
118 { "cntr6clk-cnt", offsetof(struct perpll_cfg, cntr6clk_cnt) },
119 { "cntr6clk-src", offsetof(struct perpll_cfg, cntr6clk_src) },
120 { "cntr7clk-cnt", offsetof(struct perpll_cfg, cntr7clk_cnt) },
121 { "cntr8clk-cnt", offsetof(struct perpll_cfg, cntr8clk_cnt) },
122 { "cntr8clk-src", offsetof(struct perpll_cfg, cntr8clk_src) },
123 { "cntr9clk-cnt", offsetof(struct perpll_cfg, cntr9clk_cnt) },
124 { "emacctl-emac0sel", offsetof(struct perpll_cfg, emacctl_emac0sel) },
125 { "emacctl-emac1sel", offsetof(struct perpll_cfg, emacctl_emac1sel) },
126 { "emacctl-emac2sel", offsetof(struct perpll_cfg, emacctl_emac2sel) },
127 { "gpiodiv-gpiodbclk", offsetof(struct perpll_cfg, gpiodiv_gpiodbclk) },
128};
129
130static const struct strtou32 alteragrp_cfg_tab[] = {
131 { "nocclk", offsetof(struct mainpll_cfg, nocclk) },
132 { "mpuclk", offsetof(struct mainpll_cfg, mpuclk) },
133};
134
135struct strtopu32 {
136 const char *str;
137 u32 *p;
138};
139
140const struct strtopu32 dt_to_val[] = {
141 { "altera_arria10_hps_eosc1", &eosc1_hz },
142 { "altera_arria10_hps_cb_intosc_ls", &cb_intosc_hz },
143 { "altera_arria10_hps_f2h_free", &f2s_free_hz },
144};
145
146static int of_to_struct(const void *blob, int node, const struct strtou32 *cfg_tab,
147 int cfg_tab_len, void *cfg)
148{
149 int i;
150 u32 val;
151
152 for (i = 0; i < cfg_tab_len; i++) {
153 if (fdtdec_get_int_array(blob, node, cfg_tab[i].str, &val, 1)) {
154
155 return -EINVAL;
156 }
157 *(u32 *)(cfg + cfg_tab[i].val) = val;
158 }
159
160 return 0;
161}
162
163static int of_get_input_clks(const void *blob)
164{
165 struct udevice *dev;
166 struct clk clk;
167 int i, ret;
168
169 for (i = 0; i < ARRAY_SIZE(dt_to_val); i++) {
170 memset(&clk, 0, sizeof(clk));
171
172 ret = uclass_get_device_by_name(UCLASS_CLK, dt_to_val[i].str,
173 &dev);
174 if (ret)
175 return ret;
176
177 ret = clk_request(dev, &clk);
178 if (ret)
179 return ret;
180
181 *dt_to_val[i].p = clk_get_rate(&clk);
182 }
183
184 return 0;
185}
186
187static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg,
188 struct perpll_cfg *per_cfg)
189{
190 int ret, node, child, len;
191 const char *node_name;
192
193 ret = of_get_input_clks(blob);
194 if (ret)
195 return ret;
196
197 node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK_INIT);
198
199 if (node < 0)
200 return -EINVAL;
201
202 child = fdt_first_subnode(blob, node);
203
204 if (child < 0)
205 return -EINVAL;
206
207 node_name = fdt_get_name(blob, child, &len);
208
209 while (node_name) {
210 if (!strcmp(node_name, "mainpll")) {
211 if (of_to_struct(blob, child, mainpll_cfg_tab,
212 ARRAY_SIZE(mainpll_cfg_tab), main_cfg))
213 return -EINVAL;
214 } else if (!strcmp(node_name, "perpll")) {
215 if (of_to_struct(blob, child, perpll_cfg_tab,
216 ARRAY_SIZE(perpll_cfg_tab), per_cfg))
217 return -EINVAL;
218 } else if (!strcmp(node_name, "alteragrp")) {
219 if (of_to_struct(blob, child, alteragrp_cfg_tab,
220 ARRAY_SIZE(alteragrp_cfg_tab), main_cfg))
221 return -EINVAL;
222 }
223 child = fdt_next_subnode(blob, child);
224
225 if (child < 0)
226 break;
227
228 node_name = fdt_get_name(blob, child, &len);
229 }
230
231 return 0;
232}
233
234static const struct socfpga_clock_manager *clock_manager_base =
235 (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
236
237
238static unsigned int cm_calc_handoff_main_vco_clk_hz
239 (struct mainpll_cfg *main_cfg)
240{
241 unsigned int clk_hz;
242
243
244 switch (main_cfg->vco0_psrc) {
245 case CLKMGR_MAINPLL_VCO0_PSRC_EOSC:
246 clk_hz = eosc1_hz;
247 break;
248 case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC:
249 clk_hz = cb_intosc_hz;
250 break;
251 case CLKMGR_MAINPLL_VCO0_PSRC_F2S:
252 clk_hz = f2s_free_hz;
253 break;
254 default:
255 return 0;
256 }
257
258
259 clk_hz /= 1 + main_cfg->vco1_denom;
260 clk_hz *= 1 + main_cfg->vco1_numer;
261
262 return clk_hz;
263}
264
265
266static unsigned int cm_calc_handoff_periph_vco_clk_hz(
267 struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
268{
269 unsigned int clk_hz;
270
271
272 switch (per_cfg->vco0_psrc) {
273 case CLKMGR_PERPLL_VCO0_PSRC_EOSC:
274 clk_hz = eosc1_hz;
275 break;
276 case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC:
277 clk_hz = cb_intosc_hz;
278 break;
279 case CLKMGR_PERPLL_VCO0_PSRC_F2S:
280 clk_hz = f2s_free_hz;
281 break;
282 case CLKMGR_PERPLL_VCO0_PSRC_MAIN:
283 clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
284 clk_hz /= main_cfg->cntr15clk_cnt;
285 break;
286 default:
287 return 0;
288 }
289
290
291 clk_hz /= 1 + per_cfg->vco1_denom;
292 clk_hz *= 1 + per_cfg->vco1_numer;
293
294 return clk_hz;
295}
296
297
298static unsigned int cm_calc_handoff_mpu_clk_hz(struct mainpll_cfg *main_cfg,
299 struct perpll_cfg *per_cfg)
300{
301 unsigned int clk_hz;
302
303
304 switch (main_cfg->mpuclk_src) {
305 case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN:
306 clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
307 clk_hz /= (main_cfg->mpuclk & CLKMGR_MAINPLL_MPUCLK_CNT_MSK)
308 + 1;
309 break;
310 case CLKMGR_MAINPLL_MPUCLK_SRC_PERI:
311 clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg);
312 clk_hz /= ((main_cfg->mpuclk >>
313 CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) &
314 CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1;
315 break;
316 case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1:
317 clk_hz = eosc1_hz;
318 break;
319 case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC:
320 clk_hz = cb_intosc_hz;
321 break;
322 case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA:
323 clk_hz = f2s_free_hz;
324 break;
325 default:
326 return 0;
327 }
328
329 clk_hz /= main_cfg->mpuclk_cnt + 1;
330 return clk_hz;
331}
332
333
334static unsigned int cm_calc_handoff_noc_clk_hz(struct mainpll_cfg *main_cfg,
335 struct perpll_cfg *per_cfg)
336{
337 unsigned int clk_hz;
338
339
340 switch (main_cfg->nocclk_src) {
341 case CLKMGR_MAINPLL_NOCCLK_SRC_MAIN:
342 clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
343 clk_hz /= (main_cfg->nocclk & CLKMGR_MAINPLL_NOCCLK_CNT_MSK)
344 + 1;
345 break;
346 case CLKMGR_MAINPLL_NOCCLK_SRC_PERI:
347 clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg);
348 clk_hz /= ((main_cfg->nocclk >>
349 CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) &
350 CLKMGR_MAINPLL_NOCCLK_CNT_MSK) + 1;
351 break;
352 case CLKMGR_MAINPLL_NOCCLK_SRC_OSC1:
353 clk_hz = eosc1_hz;
354 break;
355 case CLKMGR_MAINPLL_NOCCLK_SRC_INTOSC:
356 clk_hz = cb_intosc_hz;
357 break;
358 case CLKMGR_MAINPLL_NOCCLK_SRC_FPGA:
359 clk_hz = f2s_free_hz;
360 break;
361 default:
362 return 0;
363 }
364
365 clk_hz /= main_cfg->nocclk_cnt + 1;
366 return clk_hz;
367}
368
369
370static int cm_is_pll_ramp_required(int main0periph1,
371 struct mainpll_cfg *main_cfg,
372 struct perpll_cfg *per_cfg)
373{
374
375 if (main0periph1 == 0) {
376
377
378
379
380 if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_MAIN &&
381 main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_MAIN)
382 return 0;
383
384
385
386
387
388 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN &&
389 (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) >
390 CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ))
391 return 1;
392
393
394
395
396
397 if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN &&
398 (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) >
399 CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ))
400 return 2;
401
402 } else if (main0periph1 == 1) {
403
404
405
406
407 if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_PERI &&
408 main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_PERI)
409 return 0;
410
411
412
413
414
415 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI &&
416 (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) >
417 CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ))
418 return 1;
419
420
421
422
423
424 if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI &&
425 (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) >
426 CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ))
427 return 2;
428 }
429
430 return 0;
431}
432
433static u32 cm_calculate_numer(struct mainpll_cfg *main_cfg,
434 struct perpll_cfg *per_cfg,
435 u32 safe_hz, u32 clk_hz)
436{
437 u32 cnt;
438 u32 clk;
439 u32 shift;
440 u32 mask;
441 u32 denom;
442
443 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) {
444 cnt = main_cfg->mpuclk_cnt;
445 clk = main_cfg->mpuclk;
446 shift = 0;
447 mask = CLKMGR_MAINPLL_MPUCLK_CNT_MSK;
448 denom = main_cfg->vco1_denom;
449 } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) {
450 cnt = main_cfg->nocclk_cnt;
451 clk = main_cfg->nocclk;
452 shift = 0;
453 mask = CLKMGR_MAINPLL_NOCCLK_CNT_MSK;
454 denom = main_cfg->vco1_denom;
455 } else if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) {
456 cnt = main_cfg->mpuclk_cnt;
457 clk = main_cfg->mpuclk;
458 shift = CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB;
459 mask = CLKMGR_MAINPLL_MPUCLK_CNT_MSK;
460 denom = per_cfg->vco1_denom;
461 } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) {
462 cnt = main_cfg->nocclk_cnt;
463 clk = main_cfg->nocclk;
464 shift = CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB;
465 mask = CLKMGR_MAINPLL_NOCCLK_CNT_MSK;
466 denom = per_cfg->vco1_denom;
467 } else {
468 return 0;
469 }
470
471 return (safe_hz / clk_hz) * (cnt + 1) * (((clk >> shift) & mask) + 1) *
472 (1 + denom) - 1;
473}
474
475
476
477
478
479
480
481
482
483static unsigned int cm_calc_safe_pll_numer(int main0periph1,
484 struct mainpll_cfg *main_cfg,
485 struct perpll_cfg *per_cfg,
486 unsigned int safe_hz)
487{
488 unsigned int clk_hz = 0;
489
490
491 if (main0periph1 == 0) {
492
493 switch (main_cfg->vco0_psrc) {
494 case CLKMGR_MAINPLL_VCO0_PSRC_EOSC:
495 clk_hz = eosc1_hz;
496 break;
497 case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC:
498 clk_hz = cb_intosc_hz;
499 break;
500 case CLKMGR_MAINPLL_VCO0_PSRC_F2S:
501 clk_hz = f2s_free_hz;
502 break;
503 default:
504 return 0;
505 }
506 } else if (main0periph1 == 1) {
507
508 switch (per_cfg->vco0_psrc) {
509 case CLKMGR_PERPLL_VCO0_PSRC_EOSC:
510 clk_hz = eosc1_hz;
511 break;
512 case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC:
513 clk_hz = cb_intosc_hz;
514 break;
515 case CLKMGR_PERPLL_VCO0_PSRC_F2S:
516 clk_hz = f2s_free_hz;
517 break;
518 case CLKMGR_PERPLL_VCO0_PSRC_MAIN:
519 clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
520 clk_hz /= main_cfg->cntr15clk_cnt;
521 break;
522 default:
523 return 0;
524 }
525 } else {
526 return 0;
527 }
528
529 return cm_calculate_numer(main_cfg, per_cfg, safe_hz, clk_hz);
530}
531
532
533static void cm_pll_ramp_main(struct mainpll_cfg *main_cfg,
534 struct perpll_cfg *per_cfg,
535 unsigned int pll_ramp_main_hz)
536{
537 unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0;
538
539
540 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) {
541 clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ;
542 clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg);
543 } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) {
544 clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ;
545 clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg);
546 }
547
548
549 for (clk_hz = pll_ramp_main_hz + clk_incr_hz;
550 clk_hz < clk_final_hz; clk_hz += clk_incr_hz) {
551 writel((main_cfg->vco1_denom <<
552 CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
553 cm_calc_safe_pll_numer(0, main_cfg, per_cfg, clk_hz),
554 &clock_manager_base->main_pll.vco1);
555 mdelay(1);
556 cm_wait_for_lock(LOCKED_MASK);
557 }
558 writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
559 main_cfg->vco1_numer, &clock_manager_base->main_pll.vco1);
560 mdelay(1);
561 cm_wait_for_lock(LOCKED_MASK);
562}
563
564
565static void cm_pll_ramp_periph(struct mainpll_cfg *main_cfg,
566 struct perpll_cfg *per_cfg,
567 unsigned int pll_ramp_periph_hz)
568{
569 unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0;
570
571
572 if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) {
573 clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ;
574 clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg);
575 } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) {
576 clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ;
577 clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg);
578 }
579
580 for (clk_hz = pll_ramp_periph_hz + clk_incr_hz;
581 clk_hz < clk_final_hz; clk_hz += clk_incr_hz) {
582 writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
583 cm_calc_safe_pll_numer(1, main_cfg, per_cfg, clk_hz),
584 &clock_manager_base->per_pll.vco1);
585 mdelay(1);
586 cm_wait_for_lock(LOCKED_MASK);
587 }
588 writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
589 per_cfg->vco1_numer, &clock_manager_base->per_pll.vco1);
590 mdelay(1);
591 cm_wait_for_lock(LOCKED_MASK);
592}
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
634{
635 unsigned int pll_ramp_main_hz = 0, pll_ramp_periph_hz = 0,
636 ramp_required;
637
638
639 writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK |
640 CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK,
641 &clock_manager_base->main_pll.enr);
642
643
644 writel(0, &clock_manager_base->per_pll.en);
645
646
647 writel(CLKMGR_MAINPLL_BYPASS_RESET,
648 &clock_manager_base->main_pll.bypasss);
649 writel(CLKMGR_PERPLL_BYPASS_RESET,
650 &clock_manager_base->per_pll.bypasss);
651
652
653
654
655
656
657 writel(CLKMGR_MAINPLL_VCO0_RESET |
658 CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK |
659 (main_cfg->vco0_psrc << CLKMGR_MAINPLL_VCO0_PSRC_LSB),
660 &clock_manager_base->main_pll.vco0);
661
662 writel(CLKMGR_PERPLL_VCO0_RESET |
663 CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK |
664 (per_cfg->vco0_psrc << CLKMGR_PERPLL_VCO0_PSRC_LSB),
665 &clock_manager_base->per_pll.vco0);
666
667 writel(CLKMGR_MAINPLL_VCO1_RESET, &clock_manager_base->main_pll.vco1);
668 writel(CLKMGR_PERPLL_VCO1_RESET, &clock_manager_base->per_pll.vco1);
669
670
671 writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK |
672 CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK |
673 CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK |
674 CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK |
675 CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK |
676 CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK |
677 CLKMGR_CLKMGR_INTR_MAINPLLACHIEVED_SET_MSK |
678 CLKMGR_CLKMGR_INTR_PERPLLACHIEVED_SET_MSK,
679 &clock_manager_base->intr);
680
681
682 ramp_required = cm_is_pll_ramp_required(0, main_cfg, per_cfg);
683 if (ramp_required) {
684
685 if (ramp_required == 1)
686 pll_ramp_main_hz = CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ;
687 else if (ramp_required == 2)
688 pll_ramp_main_hz = CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ;
689
690 writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
691 cm_calc_safe_pll_numer(0, main_cfg, per_cfg,
692 pll_ramp_main_hz),
693 &clock_manager_base->main_pll.vco1);
694 } else
695 writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
696 main_cfg->vco1_numer,
697 &clock_manager_base->main_pll.vco1);
698
699
700 ramp_required = cm_is_pll_ramp_required(1, main_cfg, per_cfg);
701 if (ramp_required) {
702
703 if (ramp_required == 1)
704 pll_ramp_periph_hz =
705 CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ;
706 else if (ramp_required == 2)
707 pll_ramp_periph_hz =
708 CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ;
709
710 writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
711 cm_calc_safe_pll_numer(1, main_cfg, per_cfg,
712 pll_ramp_periph_hz),
713 &clock_manager_base->per_pll.vco1);
714 } else
715 writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
716 per_cfg->vco1_numer,
717 &clock_manager_base->per_pll.vco1);
718
719
720 udelay(5);
721
722
723 clrbits_le32(&clock_manager_base->main_pll.vco0,
724 CLKMGR_MAINPLL_VCO0_BGPWRDN_SET_MSK |
725 CLKMGR_MAINPLL_VCO0_PWRDN_SET_MSK);
726 clrbits_le32(&clock_manager_base->per_pll.vco0,
727 CLKMGR_PERPLL_VCO0_BGPWRDN_SET_MSK |
728 CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK);
729
730
731 udelay(7);
732
733
734 writel((readl(&clock_manager_base->main_pll.vco0) &
735 ~CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK) |
736 CLKMGR_MAINPLL_VCO0_EN_SET_MSK,
737 &clock_manager_base->main_pll.vco0);
738 writel((readl(&clock_manager_base->per_pll.vco0) &
739 ~CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK) |
740 CLKMGR_PERPLL_VCO0_EN_SET_MSK,
741 &clock_manager_base->per_pll.vco0);
742
743
744 writel(main_cfg->nocclk,
745 SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOC_CLK_OFFSET);
746 writel(main_cfg->mpuclk,
747 SOCFPGA_CLKMGR_ADDRESS + CLKMGR_ALTERAGRP_MPU_CLK_OFFSET);
748
749
750 writel(main_cfg->cntr2clk_cnt, &clock_manager_base->main_pll.cntr2clk);
751
752 writel(main_cfg->cntr3clk_cnt, &clock_manager_base->main_pll.cntr3clk);
753
754 writel(main_cfg->cntr4clk_cnt, &clock_manager_base->main_pll.cntr4clk);
755
756 writel(main_cfg->cntr5clk_cnt, &clock_manager_base->main_pll.cntr5clk);
757
758 writel(main_cfg->cntr6clk_cnt, &clock_manager_base->main_pll.cntr6clk);
759
760 writel(main_cfg->cntr7clk_cnt |
761 (main_cfg->cntr7clk_src << CLKMGR_MAINPLL_CNTR7CLK_SRC_LSB),
762 &clock_manager_base->main_pll.cntr7clk);
763
764 writel(main_cfg->cntr8clk_cnt, &clock_manager_base->main_pll.cntr8clk);
765
766 writel(main_cfg->cntr9clk_cnt |
767 (main_cfg->cntr9clk_src << CLKMGR_MAINPLL_CNTR9CLK_SRC_LSB),
768 &clock_manager_base->main_pll.cntr9clk);
769
770 writel(main_cfg->cntr15clk_cnt,
771 &clock_manager_base->main_pll.cntr15clk);
772
773
774
775 writel(per_cfg->cntr2clk_cnt |
776 (per_cfg->cntr2clk_src << CLKMGR_PERPLL_CNTR2CLK_SRC_LSB),
777 &clock_manager_base->per_pll.cntr2clk);
778
779 writel(per_cfg->cntr3clk_cnt |
780 (per_cfg->cntr3clk_src << CLKMGR_PERPLL_CNTR3CLK_SRC_LSB),
781 &clock_manager_base->per_pll.cntr3clk);
782
783 writel(per_cfg->cntr4clk_cnt |
784 (per_cfg->cntr4clk_src << CLKMGR_PERPLL_CNTR4CLK_SRC_LSB),
785 &clock_manager_base->per_pll.cntr4clk);
786
787 writel(per_cfg->cntr5clk_cnt |
788 (per_cfg->cntr5clk_src << CLKMGR_PERPLL_CNTR5CLK_SRC_LSB),
789 &clock_manager_base->per_pll.cntr5clk);
790
791 writel(per_cfg->cntr6clk_cnt |
792 (per_cfg->cntr6clk_src << CLKMGR_PERPLL_CNTR6CLK_SRC_LSB),
793 &clock_manager_base->per_pll.cntr6clk);
794
795 writel(per_cfg->cntr7clk_cnt, &clock_manager_base->per_pll.cntr7clk);
796
797 writel(per_cfg->cntr8clk_cnt |
798 (per_cfg->cntr8clk_src << CLKMGR_PERPLL_CNTR8CLK_SRC_LSB),
799 &clock_manager_base->per_pll.cntr8clk);
800
801 writel(per_cfg->cntr9clk_cnt, &clock_manager_base->per_pll.cntr9clk);
802
803
804
805 writel(main_cfg->mpuclk_cnt |
806 (main_cfg->mpuclk_src << CLKMGR_MAINPLL_MPUCLK_SRC_LSB),
807 &clock_manager_base->main_pll.mpuclk);
808
809 writel(main_cfg->nocclk_cnt |
810 (main_cfg->nocclk_src << CLKMGR_MAINPLL_NOCCLK_SRC_LSB),
811 &clock_manager_base->main_pll.nocclk);
812
813 writel(main_cfg->nocdiv_l4mainclk |
814 (main_cfg->nocdiv_l4mpclk <<
815 CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) |
816 (main_cfg->nocdiv_l4spclk <<
817 CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB) |
818 (main_cfg->nocdiv_csatclk <<
819 CLKMGR_MAINPLL_NOCDIV_CSATCLK_LSB) |
820 (main_cfg->nocdiv_cstraceclk <<
821 CLKMGR_MAINPLL_NOCDIV_CSTRACECLK_LSB) |
822 (main_cfg->nocdiv_cspdbclk <<
823 CLKMGR_MAINPLL_NOCDIV_CSPDBGCLK_LSB),
824 &clock_manager_base->main_pll.nocdiv);
825
826 writel(per_cfg->gpiodiv_gpiodbclk,
827 &clock_manager_base->per_pll.gpiodiv);
828
829
830 writel((per_cfg->emacctl_emac0sel <<
831 CLKMGR_PERPLL_EMACCTL_EMAC0SEL_LSB) |
832 (per_cfg->emacctl_emac1sel <<
833 CLKMGR_PERPLL_EMACCTL_EMAC1SEL_LSB) |
834 (per_cfg->emacctl_emac2sel <<
835 CLKMGR_PERPLL_EMACCTL_EMAC2SEL_LSB),
836 &clock_manager_base->per_pll.emacctl);
837
838
839 cm_wait_for_lock(LOCKED_MASK);
840
841
842
843
844
845
846 setbits_le32(&clock_manager_base->main_pll.vco0,
847 CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK);
848
849 setbits_le32(&clock_manager_base->per_pll.vco0,
850 CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK);
851
852 clrbits_le32(&clock_manager_base->main_pll.vco0,
853 CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK);
854
855 clrbits_le32(&clock_manager_base->per_pll.vco0,
856 CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK);
857
858
859
860 writel(CLKMGR_MAINPLL_BYPASS_RESET,
861 &clock_manager_base->main_pll.bypassr);
862
863 cm_wait_for_fsm();
864
865
866 writel(CLKMGR_PERPLL_BYPASS_RESET,
867 &clock_manager_base->per_pll.bypassr);
868
869 cm_wait_for_fsm();
870
871
872 clrbits_le32(&clock_manager_base->ctrl,
873 CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK);
874
875 cm_wait_for_fsm();
876
877
878 if (pll_ramp_main_hz != 0)
879 cm_pll_ramp_main(main_cfg, per_cfg, pll_ramp_main_hz);
880 if (pll_ramp_periph_hz != 0)
881 cm_pll_ramp_periph(main_cfg, per_cfg, pll_ramp_periph_hz);
882
883
884 writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK |
885 CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK,
886 &clock_manager_base->main_pll.ens);
887 writel(CLKMGR_PERPLL_EN_RESET, &clock_manager_base->per_pll.ens);
888
889
890
891 writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK |
892 CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK |
893 CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK |
894 CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK |
895 CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK |
896 CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK,
897 &clock_manager_base->intr);
898
899 return 0;
900}
901
902static void cm_use_intosc(void)
903{
904 setbits_le32(&clock_manager_base->ctrl,
905 CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK);
906}
907
908int cm_basic_init(const void *blob)
909{
910 struct mainpll_cfg main_cfg;
911 struct perpll_cfg per_cfg;
912 int rval;
913
914
915 memset(&main_cfg, 0, sizeof(main_cfg));
916 memset(&per_cfg, 0, sizeof(per_cfg));
917
918 rval = of_get_clk_cfg(blob, &main_cfg, &per_cfg);
919 if (rval)
920 return rval;
921
922 cm_use_intosc();
923
924 return cm_full_cfg(&main_cfg, &per_cfg);
925}
926#endif
927
928static u32 cm_get_rate_dm(char *name)
929{
930 struct uclass *uc;
931 struct udevice *dev = NULL;
932 struct clk clk = { 0 };
933 ulong rate;
934 int ret;
935
936
937 ret = uclass_get(UCLASS_CLK, &uc);
938 if (ret)
939 return 0;
940
941 ret = uclass_get_device_by_name(UCLASS_CLK, name, &dev);
942 if (ret)
943 return 0;
944
945 ret = device_probe(dev);
946 if (ret)
947 return 0;
948
949 ret = clk_request(dev, &clk);
950 if (ret)
951 return 0;
952
953 rate = clk_get_rate(&clk);
954
955 clk_free(&clk);
956
957 return rate;
958}
959
960static u32 cm_get_rate_dm_khz(char *name)
961{
962 return cm_get_rate_dm(name) / 1000;
963}
964
965unsigned long cm_get_mpu_clk_hz(void)
966{
967 return cm_get_rate_dm("main_mpu_base_clk");
968}
969
970unsigned int cm_get_qspi_controller_clk_hz(void)
971{
972 return cm_get_rate_dm("qspi_clk");
973}
974
975unsigned int cm_get_l4_sp_clk_hz(void)
976{
977 return cm_get_rate_dm("l4_sp_clk");
978}
979
980void cm_print_clock_quick_summary(void)
981{
982 printf("MPU %10d kHz\n", cm_get_rate_dm_khz("main_mpu_base_clk"));
983 printf("MMC %8d kHz\n", cm_get_rate_dm_khz("sdmmc_clk"));
984 printf("QSPI %8d kHz\n", cm_get_rate_dm_khz("qspi_clk"));
985 printf("SPI %8d kHz\n", cm_get_rate_dm_khz("spi_m_clk"));
986 printf("EOSC1 %8d kHz\n", cm_get_rate_dm_khz("osc1"));
987 printf("cb_intosc %8d kHz\n", cm_get_rate_dm_khz("cb_intosc_ls_clk"));
988 printf("f2s_free %8d kHz\n", cm_get_rate_dm_khz("f2s_free_clk"));
989 printf("Main VCO %8d kHz\n", cm_get_rate_dm_khz("main_pll@40"));
990 printf("NOC %8d kHz\n", cm_get_rate_dm_khz("main_noc_base_clk"));
991 printf("L4 Main %8d kHz\n", cm_get_rate_dm_khz("l4_main_clk"));
992 printf("L4 MP %8d kHz\n", cm_get_rate_dm_khz("l4_mp_clk"));
993 printf("L4 SP %8d kHz\n", cm_get_rate_dm_khz("l4_sp_clk"));
994 printf("L4 sys free %8d kHz\n", cm_get_rate_dm_khz("l4_sys_free_clk"));
995}
996