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
m53xx_clk_init(void)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
m53xx_qspi_init(void)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
m53xx_i2c_init(void)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
m53xx_uarts_init(void)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
m53xx_fec_init(void)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
config_BSP(char * commandp,int size)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
sysinit(void)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
wtm_init(void)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
scm_init(void)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
fbcs_init(void)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
sdramc_init(void)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
gpio_init(void)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
clock_pll(int fsys,int flags)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
clock_limp(int div)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
clock_exit_limp(void)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
get_sys_clock(void)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 }
599