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