1/***************************************************************************/
2
3/*
4 *	m53xx.c -- platform support for ColdFire 53xx based boards
5 *
6 *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7 *	Copyright (C) 2000, Lineo (www.lineo.com)
8 *	Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
9 *	Copyright Freescale Semiconductor, Inc 2006
10 *	Copyright (c) 2006, emlix, Sebastian Hess <shess@hessware.de>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 */
17
18/***************************************************************************/
19
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <asm/machdep.h>
25#include <asm/coldfire.h>
26#include <asm/mcfsim.h>
27#include <asm/mcfuart.h>
28#include <asm/mcfdma.h>
29#include <asm/mcfwdebug.h>
30#include <asm/mcfclk.h>
31
32/***************************************************************************/
33
34DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
35DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
36DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
37DEFINE_CLK(0, "edma", 17, MCF_CLK);
38DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
39DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
40DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
41DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
42DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
43DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
44DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
45DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
46DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
47DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
48DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
49DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
50
51DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
52DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
53DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
54DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
55DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK);
56DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
57DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK);
58DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
59DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
60DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
61DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK);
62DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
63DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
64DEFINE_CLK(0, "sdram.0", 46, MCF_CLK);
65DEFINE_CLK(0, "ssi.0", 47, MCF_CLK);
66DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
67
68DEFINE_CLK(1, "mdha.0", 32, MCF_CLK);
69DEFINE_CLK(1, "skha.0", 33, MCF_CLK);
70DEFINE_CLK(1, "rng.0", 34, MCF_CLK);
71
72struct clk *mcf_clks[] = {
73	&__clk_0_2,	/* flexbus */
74	&__clk_0_8,	/* mcfcan.0 */
75	&__clk_0_12,	/* fec.0 */
76	&__clk_0_17,	/* edma */
77	&__clk_0_18,	/* intc.0 */
78	&__clk_0_19,	/* intc.1 */
79	&__clk_0_21,	/* iack.0 */
80	&__clk_0_22,	/* mcfi2c.0 */
81	&__clk_0_23,	/* mcfqspi.0 */
82	&__clk_0_24,	/* mcfuart.0 */
83	&__clk_0_25,	/* mcfuart.1 */
84	&__clk_0_26,	/* mcfuart.2 */
85	&__clk_0_28,	/* mcftmr.0 */
86	&__clk_0_29,	/* mcftmr.1 */
87	&__clk_0_30,	/* mcftmr.2 */
88	&__clk_0_31,	/* mcftmr.3 */
89
90	&__clk_0_32,	/* mcfpit.0 */
91	&__clk_0_33,	/* mcfpit.1 */
92	&__clk_0_34,	/* mcfpit.2 */
93	&__clk_0_35,	/* mcfpit.3 */
94	&__clk_0_36,	/* mcfpwm.0 */
95	&__clk_0_37,	/* mcfeport.0 */
96	&__clk_0_38,	/* mcfwdt.0 */
97	&__clk_0_40,	/* sys.0 */
98	&__clk_0_41,	/* gpio.0 */
99	&__clk_0_42,	/* mcfrtc.0 */
100	&__clk_0_43,	/* mcflcd.0 */
101	&__clk_0_44,	/* mcfusb-otg.0 */
102	&__clk_0_45,	/* mcfusb-host.0 */
103	&__clk_0_46,	/* sdram.0 */
104	&__clk_0_47,	/* ssi.0 */
105	&__clk_0_48,	/* pll.0 */
106
107	&__clk_1_32,	/* mdha.0 */
108	&__clk_1_33,	/* skha.0 */
109	&__clk_1_34,	/* rng.0 */
110	NULL,
111};
112
113static struct clk * const enable_clks[] __initconst = {
114	&__clk_0_2,	/* flexbus */
115	&__clk_0_18,	/* intc.0 */
116	&__clk_0_19,	/* intc.1 */
117	&__clk_0_21,	/* iack.0 */
118	&__clk_0_24,	/* mcfuart.0 */
119	&__clk_0_25,	/* mcfuart.1 */
120	&__clk_0_26,	/* mcfuart.2 */
121	&__clk_0_28,	/* mcftmr.0 */
122	&__clk_0_29,	/* mcftmr.1 */
123	&__clk_0_32,	/* mcfpit.0 */
124	&__clk_0_33,	/* mcfpit.1 */
125	&__clk_0_37,	/* mcfeport.0 */
126	&__clk_0_40,	/* sys.0 */
127	&__clk_0_41,	/* gpio.0 */
128	&__clk_0_46,	/* sdram.0 */
129	&__clk_0_48,	/* pll.0 */
130};
131
132static struct clk * const disable_clks[] __initconst = {
133	&__clk_0_8,	/* mcfcan.0 */
134	&__clk_0_12,	/* fec.0 */
135	&__clk_0_17,	/* edma */
136	&__clk_0_22,	/* mcfi2c.0 */
137	&__clk_0_23,	/* mcfqspi.0 */
138	&__clk_0_30,	/* mcftmr.2 */
139	&__clk_0_31,	/* mcftmr.3 */
140	&__clk_0_34,	/* mcfpit.2 */
141	&__clk_0_35,	/* mcfpit.3 */
142	&__clk_0_36,	/* mcfpwm.0 */
143	&__clk_0_38,	/* mcfwdt.0 */
144	&__clk_0_42,	/* mcfrtc.0 */
145	&__clk_0_43,	/* mcflcd.0 */
146	&__clk_0_44,	/* mcfusb-otg.0 */
147	&__clk_0_45,	/* mcfusb-host.0 */
148	&__clk_0_47,	/* ssi.0 */
149	&__clk_1_32,	/* mdha.0 */
150	&__clk_1_33,	/* skha.0 */
151	&__clk_1_34,	/* rng.0 */
152};
153
154
155static void __init m53xx_clk_init(void)
156{
157	unsigned i;
158
159	/* make sure these clocks are enabled */
160	for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
161		__clk_init_enabled(enable_clks[i]);
162	/* make sure these clocks are disabled */
163	for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
164		__clk_init_disabled(disable_clks[i]);
165}
166
167/***************************************************************************/
168
169static void __init m53xx_qspi_init(void)
170{
171#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
172	/* setup QSPS pins for QSPI with gpio CS control */
173	writew(0x01f0, MCFGPIO_PAR_QSPI);
174#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
175}
176
177/***************************************************************************/
178
179static void __init m53xx_uarts_init(void)
180{
181	/* UART GPIO initialization */
182	writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
183}
184
185/***************************************************************************/
186
187static void __init m53xx_fec_init(void)
188{
189	u8 v;
190
191	/* Set multi-function pins to ethernet mode for fec0 */
192	v = readb(MCFGPIO_PAR_FECI2C);
193	v |= MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
194		MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO;
195	writeb(v, MCFGPIO_PAR_FECI2C);
196
197	v = readb(MCFGPIO_PAR_FEC);
198	v = MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC;
199	writeb(v, MCFGPIO_PAR_FEC);
200}
201
202/***************************************************************************/
203
204void __init config_BSP(char *commandp, int size)
205{
206#if !defined(CONFIG_BOOTPARAM)
207	/* Copy command line from FLASH to local buffer... */
208	memcpy(commandp, (char *) 0x4000, 4);
209	if(strncmp(commandp, "kcl ", 4) == 0){
210		memcpy(commandp, (char *) 0x4004, size);
211		commandp[size-1] = 0;
212	} else {
213		memset(commandp, 0, size);
214	}
215#endif
216	mach_sched_init = hw_timer_init;
217	m53xx_clk_init();
218	m53xx_uarts_init();
219	m53xx_fec_init();
220	m53xx_qspi_init();
221
222#ifdef CONFIG_BDM_DISABLE
223	/*
224	 * Disable the BDM clocking.  This also turns off most of the rest of
225	 * the BDM device.  This is good for EMC reasons. This option is not
226	 * incompatible with the memory protection option.
227	 */
228	wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
229#endif
230}
231
232/***************************************************************************/
233/* Board initialization */
234/***************************************************************************/
235/*
236 * PLL min/max specifications
237 */
238#define MAX_FVCO	500000	/* KHz */
239#define MAX_FSYS	80000 	/* KHz */
240#define MIN_FSYS	58333 	/* KHz */
241#define FREF		16000   /* KHz */
242
243
244#define MAX_MFD		135     /* Multiplier */
245#define MIN_MFD		88      /* Multiplier */
246#define BUSDIV		6       /* Divider */
247
248/*
249 * Low Power Divider specifications
250 */
251#define MIN_LPD		(1 << 0)    /* Divider (not encoded) */
252#define MAX_LPD		(1 << 15)   /* Divider (not encoded) */
253#define DEFAULT_LPD	(1 << 1)	/* Divider (not encoded) */
254
255#define SYS_CLK_KHZ	80000
256#define SYSTEM_PERIOD	12.5
257/*
258 *  SDRAM Timing Parameters
259 */
260#define SDRAM_BL	8	/* # of beats in a burst */
261#define SDRAM_TWR	2	/* in clocks */
262#define SDRAM_CASL	2.5	/* CASL in clocks */
263#define SDRAM_TRCD	2	/* in clocks */
264#define SDRAM_TRP	2	/* in clocks */
265#define SDRAM_TRFC	7	/* in clocks */
266#define SDRAM_TREFI	7800	/* in ns */
267
268#define EXT_SRAM_ADDRESS	(0xC0000000)
269#define FLASH_ADDRESS		(0x00000000)
270#define SDRAM_ADDRESS		(0x40000000)
271
272#define NAND_FLASH_ADDRESS	(0xD0000000)
273
274int sys_clk_khz = 0;
275int sys_clk_mhz = 0;
276
277void wtm_init(void);
278void scm_init(void);
279void gpio_init(void);
280void fbcs_init(void);
281void sdramc_init(void);
282int  clock_pll (int fsys, int flags);
283int  clock_limp (int);
284int  clock_exit_limp (void);
285int  get_sys_clock (void);
286
287asmlinkage void __init sysinit(void)
288{
289	sys_clk_khz = clock_pll(0, 0);
290	sys_clk_mhz = sys_clk_khz/1000;
291
292	wtm_init();
293	scm_init();
294	gpio_init();
295	fbcs_init();
296	sdramc_init();
297}
298
299void wtm_init(void)
300{
301	/* Disable watchdog timer */
302	writew(0, MCF_WTM_WCR);
303}
304
305#define MCF_SCM_BCR_GBW		(0x00000100)
306#define MCF_SCM_BCR_GBR		(0x00000200)
307
308void scm_init(void)
309{
310	/* All masters are trusted */
311	writel(0x77777777, MCF_SCM_MPR);
312
313	/* Allow supervisor/user, read/write, and trusted/untrusted
314	   access to all slaves */
315	writel(0, MCF_SCM_PACRA);
316	writel(0, MCF_SCM_PACRB);
317	writel(0, MCF_SCM_PACRC);
318	writel(0, MCF_SCM_PACRD);
319	writel(0, MCF_SCM_PACRE);
320	writel(0, MCF_SCM_PACRF);
321
322	/* Enable bursts */
323	writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
324}
325
326
327void fbcs_init(void)
328{
329	writeb(0x3E, MCFGPIO_PAR_CS);
330
331	/* Latch chip select */
332	writel(0x10080000, MCF_FBCS1_CSAR);
333
334	writel(0x002A3780, MCF_FBCS1_CSCR);
335	writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
336
337	/* Initialize latch to drive signals to inactive states */
338	writew(0xffff, 0x10080000);
339
340	/* External SRAM */
341	writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
342	writel(MCF_FBCS_CSCR_PS_16 |
343		MCF_FBCS_CSCR_AA |
344		MCF_FBCS_CSCR_SBM |
345		MCF_FBCS_CSCR_WS(1),
346		MCF_FBCS1_CSCR);
347	writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
348
349	/* Boot Flash connected to FBCS0 */
350	writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
351	writel(MCF_FBCS_CSCR_PS_16 |
352		MCF_FBCS_CSCR_BEM |
353		MCF_FBCS_CSCR_AA |
354		MCF_FBCS_CSCR_SBM |
355		MCF_FBCS_CSCR_WS(7),
356		MCF_FBCS0_CSCR);
357	writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
358}
359
360void sdramc_init(void)
361{
362	/*
363	 * Check to see if the SDRAM has already been initialized
364	 * by a run control tool
365	 */
366	if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
367		/* SDRAM chip select initialization */
368
369		/* Initialize SDRAM chip select */
370		writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
371			MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
372			MCF_SDRAMC_SDCS0);
373
374	/*
375	 * Basic configuration and initialization
376	 */
377	writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
378		MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
379		MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
380		MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
381		MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
382		MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
383		MCF_SDRAMC_SDCFG1_WTLAT(3),
384		MCF_SDRAMC_SDCFG1);
385	writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
386		MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
387		MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
388		MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
389		MCF_SDRAMC_SDCFG2);
390
391
392	/*
393	 * Precharge and enable write to SDMR
394	 */
395	writel(MCF_SDRAMC_SDCR_MODE_EN |
396		MCF_SDRAMC_SDCR_CKE |
397		MCF_SDRAMC_SDCR_DDR |
398		MCF_SDRAMC_SDCR_MUX(1) |
399		MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
400		MCF_SDRAMC_SDCR_PS_16 |
401		MCF_SDRAMC_SDCR_IPALL,
402		MCF_SDRAMC_SDCR);
403
404	/*
405	 * Write extended mode register
406	 */
407	writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
408		MCF_SDRAMC_SDMR_AD(0x0) |
409		MCF_SDRAMC_SDMR_CMD,
410		MCF_SDRAMC_SDMR);
411
412	/*
413	 * Write mode register and reset DLL
414	 */
415	writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
416		MCF_SDRAMC_SDMR_AD(0x163) |
417		MCF_SDRAMC_SDMR_CMD,
418		MCF_SDRAMC_SDMR);
419
420	/*
421	 * Execute a PALL command
422	 */
423	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
424
425	/*
426	 * Perform two REF cycles
427	 */
428	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
429	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
430
431	/*
432	 * Write mode register and clear reset DLL
433	 */
434	writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
435		MCF_SDRAMC_SDMR_AD(0x063) |
436		MCF_SDRAMC_SDMR_CMD,
437		MCF_SDRAMC_SDMR);
438
439	/*
440	 * Enable auto refresh and lock SDMR
441	 */
442	writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
443		MCF_SDRAMC_SDCR);
444	writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
445		MCF_SDRAMC_SDCR);
446	}
447}
448
449void gpio_init(void)
450{
451	/* Enable UART0 pins */
452	writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
453		MCFGPIO_PAR_UART);
454
455	/*
456	 * Initialize TIN3 as a GPIO output to enable the write
457	 * half of the latch.
458	 */
459	writeb(0x00, MCFGPIO_PAR_TIMER);
460	writeb(0x08, MCFGPIO_PDDR_TIMER);
461	writeb(0x00, MCFGPIO_PCLRR_TIMER);
462}
463
464int clock_pll(int fsys, int flags)
465{
466	int fref, temp, fout, mfd;
467	u32 i;
468
469	fref = FREF;
470
471	if (fsys == 0) {
472		/* Return current PLL output */
473		mfd = readb(MCF_PLL_PFDR);
474
475		return (fref * mfd / (BUSDIV * 4));
476	}
477
478	/* Check bounds of requested system clock */
479	if (fsys > MAX_FSYS)
480		fsys = MAX_FSYS;
481	if (fsys < MIN_FSYS)
482		fsys = MIN_FSYS;
483
484	/* Multiplying by 100 when calculating the temp value,
485	   and then dividing by 100 to calculate the mfd allows
486	   for exact values without needing to include floating
487	   point libraries. */
488	temp = 100 * fsys / fref;
489	mfd = 4 * BUSDIV * temp / 100;
490
491	/* Determine the output frequency for selected values */
492	fout = (fref * mfd / (BUSDIV * 4));
493
494	/*
495	 * Check to see if the SDRAM has already been initialized.
496	 * If it has then the SDRAM needs to be put into self refresh
497	 * mode before reprogramming the PLL.
498	 */
499	if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
500		/* Put SDRAM into self refresh mode */
501		writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
502			MCF_SDRAMC_SDCR);
503
504	/*
505	 * Initialize the PLL to generate the new system clock frequency.
506	 * The device must be put into LIMP mode to reprogram the PLL.
507	 */
508
509	/* Enter LIMP mode */
510	clock_limp(DEFAULT_LPD);
511
512	/* Reprogram PLL for desired fsys */
513	writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
514		MCF_PLL_PODR);
515
516	writeb(mfd, MCF_PLL_PFDR);
517
518	/* Exit LIMP mode */
519	clock_exit_limp();
520
521	/*
522	 * Return the SDRAM to normal operation if it is in use.
523	 */
524	if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
525		/* Exit self refresh mode */
526		writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
527			MCF_SDRAMC_SDCR);
528
529	/* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
530	writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
531
532	/* wait for DQS logic to relock */
533	for (i = 0; i < 0x200; i++)
534		;
535
536	return fout;
537}
538
539int clock_limp(int div)
540{
541	u32 temp;
542
543	/* Check bounds of divider */
544	if (div < MIN_LPD)
545		div = MIN_LPD;
546	if (div > MAX_LPD)
547		div = MAX_LPD;
548
549	/* Save of the current value of the SSIDIV so we don't
550	   overwrite the value*/
551	temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
552
553	/* Apply the divider to the system clock */
554	writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
555
556	writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
557
558	return (FREF/(3*(1 << div)));
559}
560
561int clock_exit_limp(void)
562{
563	int fout;
564
565	/* Exit LIMP mode */
566	writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
567
568	/* Wait for PLL to lock */
569	while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
570		;
571
572	fout = get_sys_clock();
573
574	return fout;
575}
576
577int get_sys_clock(void)
578{
579	int divider;
580
581	/* Test to see if device is in LIMP mode */
582	if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
583		divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
584		return (FREF/(2 << divider));
585	}
586	else
587		return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
588}
589