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