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