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