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