Merge tag 'gfs2-4.11.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2...
[sfrench/cifs-2.6.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, "imx1-i2c.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,    /* imx1-i2c.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,    /* imx1-i2c.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_i2c_init(void)
180 {
181 #if IS_ENABLED(CONFIG_I2C_IMX)
182         /* setup Port AS Pin Assignment Register for I2C */
183         /*  set PASPA0 to SCL and PASPA1 to SDA */
184         u8 r = readb(MCFGPIO_PAR_FECI2C);
185         r |= 0x0f;
186         writeb(r, MCFGPIO_PAR_FECI2C);
187 #endif /* IS_ENABLED(CONFIG_I2C_IMX) */
188 }
189
190 /***************************************************************************/
191
192 static void __init m53xx_uarts_init(void)
193 {
194         /* UART GPIO initialization */
195         writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
196 }
197
198 /***************************************************************************/
199
200 static void __init m53xx_fec_init(void)
201 {
202         u8 v;
203
204         /* Set multi-function pins to ethernet mode for fec0 */
205         v = readb(MCFGPIO_PAR_FECI2C);
206         v |= MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
207                 MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO;
208         writeb(v, MCFGPIO_PAR_FECI2C);
209
210         v = readb(MCFGPIO_PAR_FEC);
211         v = MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC;
212         writeb(v, MCFGPIO_PAR_FEC);
213 }
214
215 /***************************************************************************/
216
217 void __init config_BSP(char *commandp, int size)
218 {
219 #if !defined(CONFIG_BOOTPARAM)
220         /* Copy command line from FLASH to local buffer... */
221         memcpy(commandp, (char *) 0x4000, 4);
222         if(strncmp(commandp, "kcl ", 4) == 0){
223                 memcpy(commandp, (char *) 0x4004, size);
224                 commandp[size-1] = 0;
225         } else {
226                 memset(commandp, 0, size);
227         }
228 #endif
229         mach_sched_init = hw_timer_init;
230         m53xx_clk_init();
231         m53xx_uarts_init();
232         m53xx_fec_init();
233         m53xx_qspi_init();
234         m53xx_i2c_init();
235
236 #ifdef CONFIG_BDM_DISABLE
237         /*
238          * Disable the BDM clocking.  This also turns off most of the rest of
239          * the BDM device.  This is good for EMC reasons. This option is not
240          * incompatible with the memory protection option.
241          */
242         wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
243 #endif
244 }
245
246 /***************************************************************************/
247 /* Board initialization */
248 /***************************************************************************/
249 /* 
250  * PLL min/max specifications
251  */
252 #define MAX_FVCO        500000  /* KHz */
253 #define MAX_FSYS        80000   /* KHz */
254 #define MIN_FSYS        58333   /* KHz */
255 #define FREF            16000   /* KHz */
256
257
258 #define MAX_MFD         135     /* Multiplier */
259 #define MIN_MFD         88      /* Multiplier */
260 #define BUSDIV          6       /* Divider */
261
262 /*
263  * Low Power Divider specifications
264  */
265 #define MIN_LPD         (1 << 0)    /* Divider (not encoded) */
266 #define MAX_LPD         (1 << 15)   /* Divider (not encoded) */
267 #define DEFAULT_LPD     (1 << 1)        /* Divider (not encoded) */
268
269 #define SYS_CLK_KHZ     80000
270 #define SYSTEM_PERIOD   12.5
271 /*
272  *  SDRAM Timing Parameters
273  */  
274 #define SDRAM_BL        8       /* # of beats in a burst */
275 #define SDRAM_TWR       2       /* in clocks */
276 #define SDRAM_CASL      2.5     /* CASL in clocks */
277 #define SDRAM_TRCD      2       /* in clocks */
278 #define SDRAM_TRP       2       /* in clocks */
279 #define SDRAM_TRFC      7       /* in clocks */
280 #define SDRAM_TREFI     7800    /* in ns */
281
282 #define EXT_SRAM_ADDRESS        (0xC0000000)
283 #define FLASH_ADDRESS           (0x00000000)
284 #define SDRAM_ADDRESS           (0x40000000)
285
286 #define NAND_FLASH_ADDRESS      (0xD0000000)
287
288 void wtm_init(void);
289 void scm_init(void);
290 void gpio_init(void);
291 void fbcs_init(void);
292 void sdramc_init(void);
293 int  clock_pll (int fsys, int flags);
294 int  clock_limp (int);
295 int  clock_exit_limp (void);
296 int  get_sys_clock (void);
297
298 asmlinkage void __init sysinit(void)
299 {
300         clock_pll(0, 0);
301
302         wtm_init();
303         scm_init();
304         gpio_init();
305         fbcs_init();
306         sdramc_init();
307 }
308
309 void wtm_init(void)
310 {
311         /* Disable watchdog timer */
312         writew(0, MCF_WTM_WCR);
313 }
314
315 #define MCF_SCM_BCR_GBW         (0x00000100)
316 #define MCF_SCM_BCR_GBR         (0x00000200)
317
318 void scm_init(void)
319 {
320         /* All masters are trusted */
321         writel(0x77777777, MCF_SCM_MPR);
322     
323         /* Allow supervisor/user, read/write, and trusted/untrusted
324            access to all slaves */
325         writel(0, MCF_SCM_PACRA);
326         writel(0, MCF_SCM_PACRB);
327         writel(0, MCF_SCM_PACRC);
328         writel(0, MCF_SCM_PACRD);
329         writel(0, MCF_SCM_PACRE);
330         writel(0, MCF_SCM_PACRF);
331
332         /* Enable bursts */
333         writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
334 }
335
336
337 void fbcs_init(void)
338 {
339         writeb(0x3E, MCFGPIO_PAR_CS);
340
341         /* Latch chip select */
342         writel(0x10080000, MCF_FBCS1_CSAR);
343
344         writel(0x002A3780, MCF_FBCS1_CSCR);
345         writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
346
347         /* Initialize latch to drive signals to inactive states */
348         writew(0xffff, 0x10080000);
349
350         /* External SRAM */
351         writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
352         writel(MCF_FBCS_CSCR_PS_16 |
353                 MCF_FBCS_CSCR_AA |
354                 MCF_FBCS_CSCR_SBM |
355                 MCF_FBCS_CSCR_WS(1),
356                 MCF_FBCS1_CSCR);
357         writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
358
359         /* Boot Flash connected to FBCS0 */
360         writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
361         writel(MCF_FBCS_CSCR_PS_16 |
362                 MCF_FBCS_CSCR_BEM |
363                 MCF_FBCS_CSCR_AA |
364                 MCF_FBCS_CSCR_SBM |
365                 MCF_FBCS_CSCR_WS(7),
366                 MCF_FBCS0_CSCR);
367         writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
368 }
369
370 void sdramc_init(void)
371 {
372         /*
373          * Check to see if the SDRAM has already been initialized
374          * by a run control tool
375          */
376         if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
377                 /* SDRAM chip select initialization */
378                 
379                 /* Initialize SDRAM chip select */
380                 writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
381                         MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
382                         MCF_SDRAMC_SDCS0);
383
384         /*
385          * Basic configuration and initialization
386          */
387         writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
388                 MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
389                 MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
390                 MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
391                 MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
392                 MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
393                 MCF_SDRAMC_SDCFG1_WTLAT(3),
394                 MCF_SDRAMC_SDCFG1);
395         writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
396                 MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
397                 MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
398                 MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
399                 MCF_SDRAMC_SDCFG2);
400
401             
402         /*
403          * Precharge and enable write to SDMR
404          */
405         writel(MCF_SDRAMC_SDCR_MODE_EN |
406                 MCF_SDRAMC_SDCR_CKE |
407                 MCF_SDRAMC_SDCR_DDR |
408                 MCF_SDRAMC_SDCR_MUX(1) |
409                 MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
410                 MCF_SDRAMC_SDCR_PS_16 |
411                 MCF_SDRAMC_SDCR_IPALL,
412                 MCF_SDRAMC_SDCR);
413
414         /*
415          * Write extended mode register
416          */
417         writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
418                 MCF_SDRAMC_SDMR_AD(0x0) |
419                 MCF_SDRAMC_SDMR_CMD,
420                 MCF_SDRAMC_SDMR);
421
422         /*
423          * Write mode register and reset DLL
424          */
425         writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
426                 MCF_SDRAMC_SDMR_AD(0x163) |
427                 MCF_SDRAMC_SDMR_CMD,
428                 MCF_SDRAMC_SDMR);
429
430         /*
431          * Execute a PALL command
432          */
433         writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
434
435         /*
436          * Perform two REF cycles
437          */
438         writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
439         writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
440
441         /*
442          * Write mode register and clear reset DLL
443          */
444         writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
445                 MCF_SDRAMC_SDMR_AD(0x063) |
446                 MCF_SDRAMC_SDMR_CMD,
447                 MCF_SDRAMC_SDMR);
448                                 
449         /*
450          * Enable auto refresh and lock SDMR
451          */
452         writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
453                 MCF_SDRAMC_SDCR);
454         writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
455                 MCF_SDRAMC_SDCR);
456         }
457 }
458
459 void gpio_init(void)
460 {
461         /* Enable UART0 pins */
462         writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
463                 MCFGPIO_PAR_UART);
464
465         /*
466          * Initialize TIN3 as a GPIO output to enable the write
467          * half of the latch.
468          */
469         writeb(0x00, MCFGPIO_PAR_TIMER);
470         writeb(0x08, MCFGPIO_PDDR_TIMER);
471         writeb(0x00, MCFGPIO_PCLRR_TIMER);
472 }
473
474 int clock_pll(int fsys, int flags)
475 {
476         int fref, temp, fout, mfd;
477         u32 i;
478
479         fref = FREF;
480         
481         if (fsys == 0) {
482                 /* Return current PLL output */
483                 mfd = readb(MCF_PLL_PFDR);
484
485                 return (fref * mfd / (BUSDIV * 4));
486         }
487
488         /* Check bounds of requested system clock */
489         if (fsys > MAX_FSYS)
490                 fsys = MAX_FSYS;
491         if (fsys < MIN_FSYS)
492                 fsys = MIN_FSYS;
493
494         /* Multiplying by 100 when calculating the temp value,
495            and then dividing by 100 to calculate the mfd allows
496            for exact values without needing to include floating
497            point libraries. */
498         temp = 100 * fsys / fref;
499         mfd = 4 * BUSDIV * temp / 100;
500                         
501         /* Determine the output frequency for selected values */
502         fout = (fref * mfd / (BUSDIV * 4));
503
504         /*
505          * Check to see if the SDRAM has already been initialized.
506          * If it has then the SDRAM needs to be put into self refresh
507          * mode before reprogramming the PLL.
508          */
509         if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
510                 /* Put SDRAM into self refresh mode */
511                 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
512                         MCF_SDRAMC_SDCR);
513
514         /*
515          * Initialize the PLL to generate the new system clock frequency.
516          * The device must be put into LIMP mode to reprogram the PLL.
517          */
518
519         /* Enter LIMP mode */
520         clock_limp(DEFAULT_LPD);
521                                         
522         /* Reprogram PLL for desired fsys */
523         writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
524                 MCF_PLL_PODR);
525                                                 
526         writeb(mfd, MCF_PLL_PFDR);
527                 
528         /* Exit LIMP mode */
529         clock_exit_limp();
530         
531         /*
532          * Return the SDRAM to normal operation if it is in use.
533          */
534         if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
535                 /* Exit self refresh mode */
536                 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
537                         MCF_SDRAMC_SDCR);
538
539         /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
540         writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
541
542         /* wait for DQS logic to relock */
543         for (i = 0; i < 0x200; i++)
544                 ;
545
546         return fout;
547 }
548
549 int clock_limp(int div)
550 {
551         u32 temp;
552
553         /* Check bounds of divider */
554         if (div < MIN_LPD)
555                 div = MIN_LPD;
556         if (div > MAX_LPD)
557                 div = MAX_LPD;
558     
559         /* Save of the current value of the SSIDIV so we don't
560            overwrite the value*/
561         temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
562       
563         /* Apply the divider to the system clock */
564         writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
565     
566         writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
567     
568         return (FREF/(3*(1 << div)));
569 }
570
571 int clock_exit_limp(void)
572 {
573         int fout;
574         
575         /* Exit LIMP mode */
576         writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
577
578         /* Wait for PLL to lock */
579         while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
580                 ;
581         
582         fout = get_sys_clock();
583
584         return fout;
585 }
586
587 int get_sys_clock(void)
588 {
589         int divider;
590         
591         /* Test to see if device is in LIMP mode */
592         if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
593                 divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
594                 return (FREF/(2 << divider));
595         }
596         else
597                 return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
598 }