xref: /linux/arch/m68k/coldfire/m53xx.c (revision aea983801c6b5e4e9af333a32220d580a77f6783)
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 
34 DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
35 DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
36 DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
37 DEFINE_CLK(0, "edma", 17, MCF_CLK);
38 DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
39 DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
40 DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
41 DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
42 DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
43 DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
44 DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
45 DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
46 DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
47 DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
48 DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
49 DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
50 
51 DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
52 DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
53 DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
54 DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
55 DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK);
56 DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
57 DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK);
58 DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
59 DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
60 DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
61 DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK);
62 DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
63 DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
64 DEFINE_CLK(0, "sdram.0", 46, MCF_CLK);
65 DEFINE_CLK(0, "ssi.0", 47, MCF_CLK);
66 DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
67 
68 DEFINE_CLK(1, "mdha.0", 32, MCF_CLK);
69 DEFINE_CLK(1, "skha.0", 33, MCF_CLK);
70 DEFINE_CLK(1, "rng.0", 34, MCF_CLK);
71 
72 struct 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 
113 static 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 
132 static 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 
155 static 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 
169 static 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 
179 static 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 
187 static 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 
204 void __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 
274 void wtm_init(void);
275 void scm_init(void);
276 void gpio_init(void);
277 void fbcs_init(void);
278 void sdramc_init(void);
279 int  clock_pll (int fsys, int flags);
280 int  clock_limp (int);
281 int  clock_exit_limp (void);
282 int  get_sys_clock (void);
283 
284 asmlinkage void __init sysinit(void)
285 {
286 	clock_pll(0, 0);
287 
288 	wtm_init();
289 	scm_init();
290 	gpio_init();
291 	fbcs_init();
292 	sdramc_init();
293 }
294 
295 void wtm_init(void)
296 {
297 	/* Disable watchdog timer */
298 	writew(0, MCF_WTM_WCR);
299 }
300 
301 #define MCF_SCM_BCR_GBW		(0x00000100)
302 #define MCF_SCM_BCR_GBR		(0x00000200)
303 
304 void scm_init(void)
305 {
306 	/* All masters are trusted */
307 	writel(0x77777777, MCF_SCM_MPR);
308 
309 	/* Allow supervisor/user, read/write, and trusted/untrusted
310 	   access to all slaves */
311 	writel(0, MCF_SCM_PACRA);
312 	writel(0, MCF_SCM_PACRB);
313 	writel(0, MCF_SCM_PACRC);
314 	writel(0, MCF_SCM_PACRD);
315 	writel(0, MCF_SCM_PACRE);
316 	writel(0, MCF_SCM_PACRF);
317 
318 	/* Enable bursts */
319 	writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
320 }
321 
322 
323 void fbcs_init(void)
324 {
325 	writeb(0x3E, MCFGPIO_PAR_CS);
326 
327 	/* Latch chip select */
328 	writel(0x10080000, MCF_FBCS1_CSAR);
329 
330 	writel(0x002A3780, MCF_FBCS1_CSCR);
331 	writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
332 
333 	/* Initialize latch to drive signals to inactive states */
334 	writew(0xffff, 0x10080000);
335 
336 	/* External SRAM */
337 	writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
338 	writel(MCF_FBCS_CSCR_PS_16 |
339 		MCF_FBCS_CSCR_AA |
340 		MCF_FBCS_CSCR_SBM |
341 		MCF_FBCS_CSCR_WS(1),
342 		MCF_FBCS1_CSCR);
343 	writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
344 
345 	/* Boot Flash connected to FBCS0 */
346 	writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
347 	writel(MCF_FBCS_CSCR_PS_16 |
348 		MCF_FBCS_CSCR_BEM |
349 		MCF_FBCS_CSCR_AA |
350 		MCF_FBCS_CSCR_SBM |
351 		MCF_FBCS_CSCR_WS(7),
352 		MCF_FBCS0_CSCR);
353 	writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
354 }
355 
356 void sdramc_init(void)
357 {
358 	/*
359 	 * Check to see if the SDRAM has already been initialized
360 	 * by a run control tool
361 	 */
362 	if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
363 		/* SDRAM chip select initialization */
364 
365 		/* Initialize SDRAM chip select */
366 		writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
367 			MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
368 			MCF_SDRAMC_SDCS0);
369 
370 	/*
371 	 * Basic configuration and initialization
372 	 */
373 	writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
374 		MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
375 		MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
376 		MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
377 		MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
378 		MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
379 		MCF_SDRAMC_SDCFG1_WTLAT(3),
380 		MCF_SDRAMC_SDCFG1);
381 	writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
382 		MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
383 		MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
384 		MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
385 		MCF_SDRAMC_SDCFG2);
386 
387 
388 	/*
389 	 * Precharge and enable write to SDMR
390 	 */
391 	writel(MCF_SDRAMC_SDCR_MODE_EN |
392 		MCF_SDRAMC_SDCR_CKE |
393 		MCF_SDRAMC_SDCR_DDR |
394 		MCF_SDRAMC_SDCR_MUX(1) |
395 		MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
396 		MCF_SDRAMC_SDCR_PS_16 |
397 		MCF_SDRAMC_SDCR_IPALL,
398 		MCF_SDRAMC_SDCR);
399 
400 	/*
401 	 * Write extended mode register
402 	 */
403 	writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
404 		MCF_SDRAMC_SDMR_AD(0x0) |
405 		MCF_SDRAMC_SDMR_CMD,
406 		MCF_SDRAMC_SDMR);
407 
408 	/*
409 	 * Write mode register and reset DLL
410 	 */
411 	writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
412 		MCF_SDRAMC_SDMR_AD(0x163) |
413 		MCF_SDRAMC_SDMR_CMD,
414 		MCF_SDRAMC_SDMR);
415 
416 	/*
417 	 * Execute a PALL command
418 	 */
419 	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
420 
421 	/*
422 	 * Perform two REF cycles
423 	 */
424 	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
425 	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
426 
427 	/*
428 	 * Write mode register and clear reset DLL
429 	 */
430 	writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
431 		MCF_SDRAMC_SDMR_AD(0x063) |
432 		MCF_SDRAMC_SDMR_CMD,
433 		MCF_SDRAMC_SDMR);
434 
435 	/*
436 	 * Enable auto refresh and lock SDMR
437 	 */
438 	writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
439 		MCF_SDRAMC_SDCR);
440 	writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
441 		MCF_SDRAMC_SDCR);
442 	}
443 }
444 
445 void gpio_init(void)
446 {
447 	/* Enable UART0 pins */
448 	writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
449 		MCFGPIO_PAR_UART);
450 
451 	/*
452 	 * Initialize TIN3 as a GPIO output to enable the write
453 	 * half of the latch.
454 	 */
455 	writeb(0x00, MCFGPIO_PAR_TIMER);
456 	writeb(0x08, MCFGPIO_PDDR_TIMER);
457 	writeb(0x00, MCFGPIO_PCLRR_TIMER);
458 }
459 
460 int clock_pll(int fsys, int flags)
461 {
462 	int fref, temp, fout, mfd;
463 	u32 i;
464 
465 	fref = FREF;
466 
467 	if (fsys == 0) {
468 		/* Return current PLL output */
469 		mfd = readb(MCF_PLL_PFDR);
470 
471 		return (fref * mfd / (BUSDIV * 4));
472 	}
473 
474 	/* Check bounds of requested system clock */
475 	if (fsys > MAX_FSYS)
476 		fsys = MAX_FSYS;
477 	if (fsys < MIN_FSYS)
478 		fsys = MIN_FSYS;
479 
480 	/* Multiplying by 100 when calculating the temp value,
481 	   and then dividing by 100 to calculate the mfd allows
482 	   for exact values without needing to include floating
483 	   point libraries. */
484 	temp = 100 * fsys / fref;
485 	mfd = 4 * BUSDIV * temp / 100;
486 
487 	/* Determine the output frequency for selected values */
488 	fout = (fref * mfd / (BUSDIV * 4));
489 
490 	/*
491 	 * Check to see if the SDRAM has already been initialized.
492 	 * If it has then the SDRAM needs to be put into self refresh
493 	 * mode before reprogramming the PLL.
494 	 */
495 	if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
496 		/* Put SDRAM into self refresh mode */
497 		writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
498 			MCF_SDRAMC_SDCR);
499 
500 	/*
501 	 * Initialize the PLL to generate the new system clock frequency.
502 	 * The device must be put into LIMP mode to reprogram the PLL.
503 	 */
504 
505 	/* Enter LIMP mode */
506 	clock_limp(DEFAULT_LPD);
507 
508 	/* Reprogram PLL for desired fsys */
509 	writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
510 		MCF_PLL_PODR);
511 
512 	writeb(mfd, MCF_PLL_PFDR);
513 
514 	/* Exit LIMP mode */
515 	clock_exit_limp();
516 
517 	/*
518 	 * Return the SDRAM to normal operation if it is in use.
519 	 */
520 	if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
521 		/* Exit self refresh mode */
522 		writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
523 			MCF_SDRAMC_SDCR);
524 
525 	/* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
526 	writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
527 
528 	/* wait for DQS logic to relock */
529 	for (i = 0; i < 0x200; i++)
530 		;
531 
532 	return fout;
533 }
534 
535 int clock_limp(int div)
536 {
537 	u32 temp;
538 
539 	/* Check bounds of divider */
540 	if (div < MIN_LPD)
541 		div = MIN_LPD;
542 	if (div > MAX_LPD)
543 		div = MAX_LPD;
544 
545 	/* Save of the current value of the SSIDIV so we don't
546 	   overwrite the value*/
547 	temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
548 
549 	/* Apply the divider to the system clock */
550 	writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
551 
552 	writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
553 
554 	return (FREF/(3*(1 << div)));
555 }
556 
557 int clock_exit_limp(void)
558 {
559 	int fout;
560 
561 	/* Exit LIMP mode */
562 	writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
563 
564 	/* Wait for PLL to lock */
565 	while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
566 		;
567 
568 	fout = get_sys_clock();
569 
570 	return fout;
571 }
572 
573 int get_sys_clock(void)
574 {
575 	int divider;
576 
577 	/* Test to see if device is in LIMP mode */
578 	if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
579 		divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
580 		return (FREF/(2 << divider));
581 	}
582 	else
583 		return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
584 }
585