1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2000-2002
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 *
6 * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
7 */
8
9 #ifndef CONFIG_CLK_MPC83XX
10
11 #include <common.h>
12 #include <mpc83xx.h>
13 #include <command.h>
14 #include <vsprintf.h>
15 #include <asm/processor.h>
16
17 DECLARE_GLOBAL_DATA_PTR;
18
19 /* ----------------------------------------------------------------- */
20
21 typedef enum {
22 _unk,
23 _off,
24 _byp,
25 _x8,
26 _x4,
27 _x2,
28 _x1,
29 _1x,
30 _1_5x,
31 _2x,
32 _2_5x,
33 _3x
34 } mult_t;
35
36 typedef struct {
37 mult_t core_csb_ratio;
38 mult_t vco_divider;
39 } corecnf_t;
40
41 static corecnf_t corecnf_tab[] = {
42 {_byp, _byp}, /* 0x00 */
43 {_byp, _byp}, /* 0x01 */
44 {_byp, _byp}, /* 0x02 */
45 {_byp, _byp}, /* 0x03 */
46 {_byp, _byp}, /* 0x04 */
47 {_byp, _byp}, /* 0x05 */
48 {_byp, _byp}, /* 0x06 */
49 {_byp, _byp}, /* 0x07 */
50 {_1x, _x2}, /* 0x08 */
51 {_1x, _x4}, /* 0x09 */
52 {_1x, _x8}, /* 0x0A */
53 {_1x, _x8}, /* 0x0B */
54 {_1_5x, _x2}, /* 0x0C */
55 {_1_5x, _x4}, /* 0x0D */
56 {_1_5x, _x8}, /* 0x0E */
57 {_1_5x, _x8}, /* 0x0F */
58 {_2x, _x2}, /* 0x10 */
59 {_2x, _x4}, /* 0x11 */
60 {_2x, _x8}, /* 0x12 */
61 {_2x, _x8}, /* 0x13 */
62 {_2_5x, _x2}, /* 0x14 */
63 {_2_5x, _x4}, /* 0x15 */
64 {_2_5x, _x8}, /* 0x16 */
65 {_2_5x, _x8}, /* 0x17 */
66 {_3x, _x2}, /* 0x18 */
67 {_3x, _x4}, /* 0x19 */
68 {_3x, _x8}, /* 0x1A */
69 {_3x, _x8}, /* 0x1B */
70 };
71
72 /* ----------------------------------------------------------------- */
73
74 /*
75 *
76 */
get_clocks(void)77 int get_clocks(void)
78 {
79 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
80 u32 pci_sync_in;
81 u8 spmf;
82 u8 clkin_div;
83 u32 sccr;
84 u32 corecnf_tab_index;
85 u8 corepll;
86 u32 lcrr;
87
88 u32 csb_clk;
89 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
90 defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
91 u32 tsec1_clk;
92 u32 tsec2_clk;
93 u32 usbdr_clk;
94 #elif defined(CONFIG_ARCH_MPC8309)
95 u32 usbdr_clk;
96 #endif
97 #ifdef CONFIG_ARCH_MPC834X
98 u32 usbmph_clk;
99 #endif
100 u32 core_clk;
101 u32 i2c1_clk;
102 #if !defined(CONFIG_ARCH_MPC832X)
103 u32 i2c2_clk;
104 #endif
105 #if defined(CONFIG_ARCH_MPC8315)
106 u32 tdm_clk;
107 #endif
108 #if defined(CONFIG_FSL_ESDHC)
109 u32 sdhc_clk;
110 #endif
111 #if !defined(CONFIG_ARCH_MPC8309)
112 u32 enc_clk;
113 #endif
114 u32 lbiu_clk;
115 u32 lclk_clk;
116 u32 mem_clk;
117 #if defined(CONFIG_ARCH_MPC8360)
118 u32 mem_sec_clk;
119 #endif
120 #if defined(CONFIG_QE)
121 u32 qepmf;
122 u32 qepdf;
123 u32 qe_clk;
124 u32 brg_clk;
125 #endif
126 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
127 defined(CONFIG_ARCH_MPC837X)
128 u32 pciexp1_clk;
129 u32 pciexp2_clk;
130 #endif
131 #if defined(CONFIG_ARCH_MPC837X) || defined(CONFIG_ARCH_MPC8315)
132 u32 sata_clk;
133 #endif
134
135 if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
136 return -1;
137
138 clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT);
139
140 if (im->reset.rcwh & HRCWH_PCI_HOST) {
141 #if defined(CONFIG_SYS_CLK_FREQ)
142 pci_sync_in = CONFIG_SYS_CLK_FREQ / (1 + clkin_div);
143 #else
144 pci_sync_in = 0xDEADBEEF;
145 #endif
146 } else {
147 #if defined(CONFIG_83XX_PCICLK)
148 pci_sync_in = CONFIG_83XX_PCICLK;
149 #else
150 pci_sync_in = 0xDEADBEEF;
151 #endif
152 }
153
154 spmf = (im->clk.spmr & SPMR_SPMF) >> SPMR_SPMF_SHIFT;
155 csb_clk = pci_sync_in * (1 + clkin_div) * spmf;
156
157 sccr = im->clk.sccr;
158
159 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
160 defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
161 switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) {
162 case 0:
163 tsec1_clk = 0;
164 break;
165 case 1:
166 tsec1_clk = csb_clk;
167 break;
168 case 2:
169 tsec1_clk = csb_clk / 2;
170 break;
171 case 3:
172 tsec1_clk = csb_clk / 3;
173 break;
174 default:
175 /* unknown SCCR_TSEC1CM value */
176 return -2;
177 }
178 #endif
179
180 #if defined(CONFIG_ARCH_MPC830X) || defined(CONFIG_ARCH_MPC831X) || \
181 defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
182 switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) {
183 case 0:
184 usbdr_clk = 0;
185 break;
186 case 1:
187 usbdr_clk = csb_clk;
188 break;
189 case 2:
190 usbdr_clk = csb_clk / 2;
191 break;
192 case 3:
193 usbdr_clk = csb_clk / 3;
194 break;
195 default:
196 /* unknown SCCR_USBDRCM value */
197 return -3;
198 }
199 #endif
200
201 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC8315) || \
202 defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
203 switch ((sccr & SCCR_TSEC2CM) >> SCCR_TSEC2CM_SHIFT) {
204 case 0:
205 tsec2_clk = 0;
206 break;
207 case 1:
208 tsec2_clk = csb_clk;
209 break;
210 case 2:
211 tsec2_clk = csb_clk / 2;
212 break;
213 case 3:
214 tsec2_clk = csb_clk / 3;
215 break;
216 default:
217 /* unknown SCCR_TSEC2CM value */
218 return -4;
219 }
220 #elif defined(CONFIG_ARCH_MPC8313)
221 tsec2_clk = tsec1_clk;
222
223 if (!(sccr & SCCR_TSEC1ON))
224 tsec1_clk = 0;
225 if (!(sccr & SCCR_TSEC2ON))
226 tsec2_clk = 0;
227 #endif
228
229 #if defined(CONFIG_ARCH_MPC834X)
230 switch ((sccr & SCCR_USBMPHCM) >> SCCR_USBMPHCM_SHIFT) {
231 case 0:
232 usbmph_clk = 0;
233 break;
234 case 1:
235 usbmph_clk = csb_clk;
236 break;
237 case 2:
238 usbmph_clk = csb_clk / 2;
239 break;
240 case 3:
241 usbmph_clk = csb_clk / 3;
242 break;
243 default:
244 /* unknown SCCR_USBMPHCM value */
245 return -5;
246 }
247
248 if (usbmph_clk != 0 && usbdr_clk != 0 && usbmph_clk != usbdr_clk) {
249 /* if USB MPH clock is not disabled and
250 * USB DR clock is not disabled then
251 * USB MPH & USB DR must have the same rate
252 */
253 return -6;
254 }
255 #endif
256 #if !defined(CONFIG_ARCH_MPC8309)
257 switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
258 case 0:
259 enc_clk = 0;
260 break;
261 case 1:
262 enc_clk = csb_clk;
263 break;
264 case 2:
265 enc_clk = csb_clk / 2;
266 break;
267 case 3:
268 enc_clk = csb_clk / 3;
269 break;
270 default:
271 /* unknown SCCR_ENCCM value */
272 return -7;
273 }
274 #endif
275
276 #if defined(CONFIG_FSL_ESDHC)
277 switch ((sccr & SCCR_SDHCCM) >> SCCR_SDHCCM_SHIFT) {
278 case 0:
279 sdhc_clk = 0;
280 break;
281 case 1:
282 sdhc_clk = csb_clk;
283 break;
284 case 2:
285 sdhc_clk = csb_clk / 2;
286 break;
287 case 3:
288 sdhc_clk = csb_clk / 3;
289 break;
290 default:
291 /* unknown SCCR_SDHCCM value */
292 return -8;
293 }
294 #endif
295 #if defined(CONFIG_ARCH_MPC8315)
296 switch ((sccr & SCCR_TDMCM) >> SCCR_TDMCM_SHIFT) {
297 case 0:
298 tdm_clk = 0;
299 break;
300 case 1:
301 tdm_clk = csb_clk;
302 break;
303 case 2:
304 tdm_clk = csb_clk / 2;
305 break;
306 case 3:
307 tdm_clk = csb_clk / 3;
308 break;
309 default:
310 /* unknown SCCR_TDMCM value */
311 return -8;
312 }
313 #endif
314
315 #if defined(CONFIG_ARCH_MPC834X)
316 i2c1_clk = tsec2_clk;
317 #elif defined(CONFIG_ARCH_MPC8360)
318 i2c1_clk = csb_clk;
319 #elif defined(CONFIG_ARCH_MPC832X)
320 i2c1_clk = enc_clk;
321 #elif defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X)
322 i2c1_clk = enc_clk;
323 #elif defined(CONFIG_FSL_ESDHC)
324 i2c1_clk = sdhc_clk;
325 #elif defined(CONFIG_ARCH_MPC837X)
326 i2c1_clk = enc_clk;
327 #elif defined(CONFIG_ARCH_MPC8309)
328 i2c1_clk = csb_clk;
329 #endif
330 #if !defined(CONFIG_ARCH_MPC832X)
331 i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */
332 #endif
333
334 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
335 defined(CONFIG_ARCH_MPC837X)
336 switch ((sccr & SCCR_PCIEXP1CM) >> SCCR_PCIEXP1CM_SHIFT) {
337 case 0:
338 pciexp1_clk = 0;
339 break;
340 case 1:
341 pciexp1_clk = csb_clk;
342 break;
343 case 2:
344 pciexp1_clk = csb_clk / 2;
345 break;
346 case 3:
347 pciexp1_clk = csb_clk / 3;
348 break;
349 default:
350 /* unknown SCCR_PCIEXP1CM value */
351 return -9;
352 }
353
354 switch ((sccr & SCCR_PCIEXP2CM) >> SCCR_PCIEXP2CM_SHIFT) {
355 case 0:
356 pciexp2_clk = 0;
357 break;
358 case 1:
359 pciexp2_clk = csb_clk;
360 break;
361 case 2:
362 pciexp2_clk = csb_clk / 2;
363 break;
364 case 3:
365 pciexp2_clk = csb_clk / 3;
366 break;
367 default:
368 /* unknown SCCR_PCIEXP2CM value */
369 return -10;
370 }
371 #endif
372
373 #if defined(CONFIG_ARCH_MPC837X) || defined(CONFIG_ARCH_MPC8315)
374 switch ((sccr & SCCR_SATA1CM) >> SCCR_SATA1CM_SHIFT) {
375 case 0:
376 sata_clk = 0;
377 break;
378 case 1:
379 sata_clk = csb_clk;
380 break;
381 case 2:
382 sata_clk = csb_clk / 2;
383 break;
384 case 3:
385 sata_clk = csb_clk / 3;
386 break;
387 default:
388 /* unknown SCCR_SATA1CM value */
389 return -11;
390 }
391 #endif
392
393 lbiu_clk = csb_clk *
394 (1 + ((im->clk.spmr & SPMR_LBIUCM) >> SPMR_LBIUCM_SHIFT));
395 lcrr = (im->im_lbc.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT;
396 switch (lcrr) {
397 case 2:
398 case 4:
399 case 8:
400 lclk_clk = lbiu_clk / lcrr;
401 break;
402 default:
403 /* unknown lcrr */
404 return -12;
405 }
406
407 mem_clk = csb_clk *
408 (1 + ((im->clk.spmr & SPMR_DDRCM) >> SPMR_DDRCM_SHIFT));
409 corepll = (im->clk.spmr & SPMR_COREPLL) >> SPMR_COREPLL_SHIFT;
410
411 #if defined(CONFIG_ARCH_MPC8360)
412 mem_sec_clk = csb_clk * (1 +
413 ((im->clk.spmr & SPMR_LBIUCM) >> SPMR_LBIUCM_SHIFT));
414 #endif
415
416 corecnf_tab_index = ((corepll & 0x1F) << 2) | ((corepll & 0x60) >> 5);
417 if (corecnf_tab_index > (ARRAY_SIZE(corecnf_tab))) {
418 /* corecnf_tab_index is too high, possibly wrong value */
419 return -11;
420 }
421 switch (corecnf_tab[corecnf_tab_index].core_csb_ratio) {
422 case _byp:
423 case _x1:
424 case _1x:
425 core_clk = csb_clk;
426 break;
427 case _1_5x:
428 core_clk = (3 * csb_clk) / 2;
429 break;
430 case _2x:
431 core_clk = 2 * csb_clk;
432 break;
433 case _2_5x:
434 core_clk = (5 * csb_clk) / 2;
435 break;
436 case _3x:
437 core_clk = 3 * csb_clk;
438 break;
439 default:
440 /* unknown core to csb ratio */
441 return -13;
442 }
443
444 #if defined(CONFIG_QE)
445 qepmf = (im->clk.spmr & SPMR_CEPMF) >> SPMR_CEPMF_SHIFT;
446 qepdf = (im->clk.spmr & SPMR_CEPDF) >> SPMR_CEPDF_SHIFT;
447 qe_clk = (pci_sync_in * qepmf) / (1 + qepdf);
448 brg_clk = qe_clk / 2;
449 #endif
450
451 gd->arch.csb_clk = csb_clk;
452 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
453 defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
454 gd->arch.tsec1_clk = tsec1_clk;
455 gd->arch.tsec2_clk = tsec2_clk;
456 gd->arch.usbdr_clk = usbdr_clk;
457 #elif defined(CONFIG_ARCH_MPC8309)
458 gd->arch.usbdr_clk = usbdr_clk;
459 #endif
460 #if defined(CONFIG_ARCH_MPC834X)
461 gd->arch.usbmph_clk = usbmph_clk;
462 #endif
463 #if defined(CONFIG_ARCH_MPC8315)
464 gd->arch.tdm_clk = tdm_clk;
465 #endif
466 #if defined(CONFIG_FSL_ESDHC)
467 gd->arch.sdhc_clk = sdhc_clk;
468 #endif
469 gd->arch.core_clk = core_clk;
470 gd->arch.i2c1_clk = i2c1_clk;
471 #if !defined(CONFIG_ARCH_MPC832X)
472 gd->arch.i2c2_clk = i2c2_clk;
473 #endif
474 #if !defined(CONFIG_ARCH_MPC8309)
475 gd->arch.enc_clk = enc_clk;
476 #endif
477 gd->arch.lbiu_clk = lbiu_clk;
478 gd->arch.lclk_clk = lclk_clk;
479 gd->mem_clk = mem_clk;
480 #if defined(CONFIG_ARCH_MPC8360)
481 gd->arch.mem_sec_clk = mem_sec_clk;
482 #endif
483 #if defined(CONFIG_QE)
484 gd->arch.qe_clk = qe_clk;
485 gd->arch.brg_clk = brg_clk;
486 #endif
487 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
488 defined(CONFIG_ARCH_MPC837X)
489 gd->arch.pciexp1_clk = pciexp1_clk;
490 gd->arch.pciexp2_clk = pciexp2_clk;
491 #endif
492 #if defined(CONFIG_ARCH_MPC837X) || defined(CONFIG_ARCH_MPC8315)
493 gd->arch.sata_clk = sata_clk;
494 #endif
495 gd->pci_clk = pci_sync_in;
496 gd->cpu_clk = gd->arch.core_clk;
497 gd->bus_clk = gd->arch.csb_clk;
498 return 0;
499
500 }
501
502 /********************************************
503 * get_bus_freq
504 * return system bus freq in Hz
505 *********************************************/
get_bus_freq(ulong dummy)506 ulong get_bus_freq(ulong dummy)
507 {
508 return gd->arch.csb_clk;
509 }
510
511 /********************************************
512 * get_ddr_freq
513 * return ddr bus freq in Hz
514 *********************************************/
get_ddr_freq(ulong dummy)515 ulong get_ddr_freq(ulong dummy)
516 {
517 return gd->mem_clk;
518 }
519
get_serial_clock(void)520 int get_serial_clock(void)
521 {
522 return get_bus_freq(0);
523 }
524
do_clocks(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])525 static int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
526 {
527 char buf[32];
528
529 printf("Clock configuration:\n");
530 printf(" Core: %-4s MHz\n",
531 strmhz(buf, gd->arch.core_clk));
532 printf(" Coherent System Bus: %-4s MHz\n",
533 strmhz(buf, gd->arch.csb_clk));
534 #if defined(CONFIG_QE)
535 printf(" QE: %-4s MHz\n",
536 strmhz(buf, gd->arch.qe_clk));
537 printf(" BRG: %-4s MHz\n",
538 strmhz(buf, gd->arch.brg_clk));
539 #endif
540 printf(" Local Bus Controller:%-4s MHz\n",
541 strmhz(buf, gd->arch.lbiu_clk));
542 printf(" Local Bus: %-4s MHz\n",
543 strmhz(buf, gd->arch.lclk_clk));
544 printf(" DDR: %-4s MHz\n", strmhz(buf, gd->mem_clk));
545 #if defined(CONFIG_ARCH_MPC8360)
546 printf(" DDR Secondary: %-4s MHz\n",
547 strmhz(buf, gd->arch.mem_sec_clk));
548 #endif
549 #if !defined(CONFIG_ARCH_MPC8309)
550 printf(" SEC: %-4s MHz\n",
551 strmhz(buf, gd->arch.enc_clk));
552 #endif
553 printf(" I2C1: %-4s MHz\n",
554 strmhz(buf, gd->arch.i2c1_clk));
555 #if !defined(CONFIG_ARCH_MPC832X)
556 printf(" I2C2: %-4s MHz\n",
557 strmhz(buf, gd->arch.i2c2_clk));
558 #endif
559 #if defined(CONFIG_ARCH_MPC8315)
560 printf(" TDM: %-4s MHz\n",
561 strmhz(buf, gd->arch.tdm_clk));
562 #endif
563 #if defined(CONFIG_FSL_ESDHC)
564 printf(" SDHC: %-4s MHz\n",
565 strmhz(buf, gd->arch.sdhc_clk));
566 #endif
567 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
568 defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
569 printf(" TSEC1: %-4s MHz\n",
570 strmhz(buf, gd->arch.tsec1_clk));
571 printf(" TSEC2: %-4s MHz\n",
572 strmhz(buf, gd->arch.tsec2_clk));
573 printf(" USB DR: %-4s MHz\n",
574 strmhz(buf, gd->arch.usbdr_clk));
575 #elif defined(CONFIG_ARCH_MPC8309)
576 printf(" USB DR: %-4s MHz\n",
577 strmhz(buf, gd->arch.usbdr_clk));
578 #endif
579 #if defined(CONFIG_ARCH_MPC834X)
580 printf(" USB MPH: %-4s MHz\n",
581 strmhz(buf, gd->arch.usbmph_clk));
582 #endif
583 #if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
584 defined(CONFIG_ARCH_MPC837X)
585 printf(" PCIEXP1: %-4s MHz\n",
586 strmhz(buf, gd->arch.pciexp1_clk));
587 printf(" PCIEXP2: %-4s MHz\n",
588 strmhz(buf, gd->arch.pciexp2_clk));
589 #endif
590 #if defined(CONFIG_ARCH_MPC837X) || defined(CONFIG_ARCH_MPC8315)
591 printf(" SATA: %-4s MHz\n",
592 strmhz(buf, gd->arch.sata_clk));
593 #endif
594 return 0;
595 }
596
597 U_BOOT_CMD(clocks, 1, 0, do_clocks,
598 "print clock configuration",
599 " clocks"
600 );
601
602 #endif
603