Merge remote-tracking branch 'selinux/next'
[deliverable/linux.git] / arch / m68k / coldfire / m53xx.c
CommitLineData
3196cf83
GU
1/***************************************************************************/
2
3/*
e73cbe21 4 * m53xx.c -- platform support for ColdFire 53xx based boards
3196cf83
GU
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
b7799b05 10 * Copyright (c) 2006, emlix, Sebastian Hess <shess@hessware.de>
3196cf83
GU
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
3196cf83 20#include <linux/kernel.h>
3196cf83
GU
21#include <linux/param.h>
22#include <linux/init.h>
b2e1810e 23#include <linux/io.h>
3196cf83
GU
24#include <asm/machdep.h>
25#include <asm/coldfire.h>
3196cf83 26#include <asm/mcfsim.h>
b2e1810e 27#include <asm/mcfuart.h>
3196cf83
GU
28#include <asm/mcfdma.h>
29#include <asm/mcfwdebug.h>
12ce4c1f
SK
30#include <asm/mcfclk.h>
31
32/***************************************************************************/
33
34DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
35DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
36DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
37DEFINE_CLK(0, "edma", 17, MCF_CLK);
38DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
39DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
40DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
41DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
42DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
43DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
44DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
45DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
46DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
47DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
48DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
49DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
50
51DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
52DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
53DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
54DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
55DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK);
56DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
57DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK);
58DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
59DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
60DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
61DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK);
62DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
63DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
64DEFINE_CLK(0, "sdram.0", 46, MCF_CLK);
65DEFINE_CLK(0, "ssi.0", 47, MCF_CLK);
66DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
67
68DEFINE_CLK(1, "mdha.0", 32, MCF_CLK);
69DEFINE_CLK(1, "skha.0", 33, MCF_CLK);
70DEFINE_CLK(1, "rng.0", 34, MCF_CLK);
71
72struct 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
113static 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 */
2842e5b0
GU
121 &__clk_0_28, /* mcftmr.0 */
122 &__clk_0_29, /* mcftmr.1 */
12ce4c1f
SK
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
132static 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 */
12ce4c1f
SK
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
e73cbe21 155static void __init m53xx_clk_init(void)
12ce4c1f
SK
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}
3196cf83
GU
166
167/***************************************************************************/
168
e73cbe21 169static void __init m53xx_qspi_init(void)
91d60417 170{
151d14f4 171#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
91d60417 172 /* setup QSPS pins for QSPI with gpio CS control */
e4c2b9be 173 writew(0x01f0, MCFGPIO_PAR_QSPI);
83ca6009 174#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
151d14f4 175}
b2e1810e
GU
176
177/***************************************************************************/
178
e73cbe21 179static void __init m53xx_uarts_init(void)
b2e1810e 180{
a75bc619 181 /* UART GPIO initialization */
e4c2b9be 182 writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
b2e1810e 183}
a75bc619 184
ffba3f48
GU
185/***************************************************************************/
186
e73cbe21 187static void __init m53xx_fec_init(void)
ffba3f48 188{
e4c2b9be
GU
189 u8 v;
190
ffba3f48 191 /* Set multi-function pins to ethernet mode for fec0 */
e4c2b9be
GU
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);
ffba3f48 200}
3196cf83
GU
201
202/***************************************************************************/
203
b2e1810e 204void __init config_BSP(char *commandp, int size)
3196cf83 205{
bc72450a 206#if !defined(CONFIG_BOOTPARAM)
3196cf83
GU
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
35aefb26 216 mach_sched_init = hw_timer_init;
e73cbe21
GU
217 m53xx_clk_init();
218 m53xx_uarts_init();
219 m53xx_fec_init();
e73cbe21 220 m53xx_qspi_init();
35aefb26 221
b2e1810e 222#ifdef CONFIG_BDM_DISABLE
3196cf83
GU
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
b2e1810e
GU
232/***************************************************************************/
233/* Board initialization */
234/***************************************************************************/
3196cf83
GU
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
3196cf83
GU
274void wtm_init(void);
275void scm_init(void);
276void gpio_init(void);
277void fbcs_init(void);
278void sdramc_init(void);
279int clock_pll (int fsys, int flags);
280int clock_limp (int);
281int clock_exit_limp (void);
282int get_sys_clock (void);
283
284asmlinkage void __init sysinit(void)
285{
5ff2ba85
GU
286 clock_pll(0, 0);
287
3196cf83
GU
288 wtm_init();
289 scm_init();
290 gpio_init();
291 fbcs_init();
292 sdramc_init();
293}
294
295void wtm_init(void)
296{
297 /* Disable watchdog timer */
6d8a1393 298 writew(0, MCF_WTM_WCR);
3196cf83
GU
299}
300
301#define MCF_SCM_BCR_GBW (0x00000100)
302#define MCF_SCM_BCR_GBR (0x00000200)
303
304void scm_init(void)
305{
306 /* All masters are trusted */
6d8a1393 307 writel(0x77777777, MCF_SCM_MPR);
3196cf83
GU
308
309 /* Allow supervisor/user, read/write, and trusted/untrusted
310 access to all slaves */
6d8a1393
GU
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);
3196cf83
GU
317
318 /* Enable bursts */
6d8a1393 319 writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
3196cf83
GU
320}
321
322
323void fbcs_init(void)
324{
e4c2b9be 325 writeb(0x3E, MCFGPIO_PAR_CS);
3196cf83
GU
326
327 /* Latch chip select */
6d8a1393 328 writel(0x10080000, MCF_FBCS1_CSAR);
3196cf83 329
6d8a1393
GU
330 writel(0x002A3780, MCF_FBCS1_CSCR);
331 writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
3196cf83
GU
332
333 /* Initialize latch to drive signals to inactive states */
6d8a1393 334 writew(0xffff, 0x10080000);
3196cf83
GU
335
336 /* External SRAM */
6d8a1393
GU
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);
3196cf83
GU
344
345 /* Boot Flash connected to FBCS0 */
6d8a1393
GU
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);
3196cf83
GU
354}
355
356void sdramc_init(void)
357{
358 /*
359 * Check to see if the SDRAM has already been initialized
360 * by a run control tool
361 */
6d8a1393 362 if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
3196cf83
GU
363 /* SDRAM chip select initialization */
364
365 /* Initialize SDRAM chip select */
6d8a1393
GU
366 writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
367 MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
368 MCF_SDRAMC_SDCS0);
3196cf83
GU
369
370 /*
371 * Basic configuration and initialization
372 */
6d8a1393
GU
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);
3196cf83
GU
386
387
388 /*
389 * Precharge and enable write to SDMR
390 */
6d8a1393
GU
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);
3196cf83
GU
399
400 /*
401 * Write extended mode register
402 */
6d8a1393
GU
403 writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
404 MCF_SDRAMC_SDMR_AD(0x0) |
405 MCF_SDRAMC_SDMR_CMD,
406 MCF_SDRAMC_SDMR);
3196cf83
GU
407
408 /*
409 * Write mode register and reset DLL
410 */
6d8a1393
GU
411 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
412 MCF_SDRAMC_SDMR_AD(0x163) |
413 MCF_SDRAMC_SDMR_CMD,
414 MCF_SDRAMC_SDMR);
3196cf83
GU
415
416 /*
417 * Execute a PALL command
418 */
6d8a1393 419 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
3196cf83
GU
420
421 /*
422 * Perform two REF cycles
423 */
6d8a1393
GU
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);
3196cf83
GU
426
427 /*
428 * Write mode register and clear reset DLL
429 */
6d8a1393
GU
430 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
431 MCF_SDRAMC_SDMR_AD(0x063) |
432 MCF_SDRAMC_SDMR_CMD,
433 MCF_SDRAMC_SDMR);
3196cf83
GU
434
435 /*
436 * Enable auto refresh and lock SDMR
437 */
6d8a1393
GU
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);
3196cf83
GU
442 }
443}
444
445void gpio_init(void)
446{
447 /* Enable UART0 pins */
e4c2b9be
GU
448 writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
449 MCFGPIO_PAR_UART);
3196cf83 450
e4c2b9be
GU
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);
3196cf83
GU
458}
459
460int 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 */
6d8a1393 469 mfd = readb(MCF_PLL_PFDR);
3196cf83
GU
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 */
6d8a1393 495 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
3196cf83 496 /* Put SDRAM into self refresh mode */
6d8a1393
GU
497 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
498 MCF_SDRAMC_SDCR);
3196cf83
GU
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 */
6d8a1393
GU
509 writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
510 MCF_PLL_PODR);
3196cf83 511
6d8a1393 512 writeb(mfd, MCF_PLL_PFDR);
3196cf83
GU
513
514 /* Exit LIMP mode */
515 clock_exit_limp();
516
517 /*
518 * Return the SDRAM to normal operation if it is in use.
519 */
6d8a1393 520 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
3196cf83 521 /* Exit self refresh mode */
6d8a1393
GU
522 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
523 MCF_SDRAMC_SDCR);
3196cf83
GU
524
525 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
6d8a1393 526 writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
3196cf83
GU
527
528 /* wait for DQS logic to relock */
529 for (i = 0; i < 0x200; i++)
530 ;
531
532 return fout;
533}
534
535int 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*/
6d8a1393 547 temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
3196cf83
GU
548
549 /* Apply the divider to the system clock */
6d8a1393 550 writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
3196cf83 551
6d8a1393 552 writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
3196cf83
GU
553
554 return (FREF/(3*(1 << div)));
555}
556
557int clock_exit_limp(void)
558{
559 int fout;
560
561 /* Exit LIMP mode */
6d8a1393 562 writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
3196cf83
GU
563
564 /* Wait for PLL to lock */
6d8a1393 565 while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
3196cf83
GU
566 ;
567
568 fout = get_sys_clock();
569
570 return fout;
571}
572
573int get_sys_clock(void)
574{
575 int divider;
576
577 /* Test to see if device is in LIMP mode */
6d8a1393
GU
578 if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
579 divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
3196cf83
GU
580 return (FREF/(2 << divider));
581 }
582 else
6d8a1393 583 return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
3196cf83 584}
This page took 0.728819 seconds and 5 git commands to generate.