GNU Linux-libre 4.9.318-gnu1
[releases.git] / arch / m68k / coldfire / m53xx.c
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 }