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