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