blob: cf1917934b8a888335248193aa5ad08859bbef4a [file] [log] [blame]
Greg Ungerer3196cf82006-06-26 10:33:10 +10001/***************************************************************************/
2
3/*
Greg Ungerere73cbe22012-11-05 15:05:53 +10004 * m53xx.c -- platform support for ColdFire 53xx based boards
Greg Ungerer3196cf82006-06-26 10:33:10 +10005 *
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
Linus Torvaldse8650a02012-05-22 19:22:50 -070010 * Copyright (c) 2006, emlix, Sebastian Hess <shess@hessware.de>
Greg Ungerer3196cf82006-06-26 10:33:10 +100011 *
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
Greg Ungerer3196cf82006-06-26 10:33:10 +100020#include <linux/kernel.h>
Greg Ungerer3196cf82006-06-26 10:33:10 +100021#include <linux/param.h>
22#include <linux/init.h>
Greg Ungererb2e18102008-02-01 17:34:58 +100023#include <linux/io.h>
Greg Ungerer3196cf82006-06-26 10:33:10 +100024#include <asm/machdep.h>
25#include <asm/coldfire.h>
Greg Ungerer3196cf82006-06-26 10:33:10 +100026#include <asm/mcfsim.h>
Greg Ungererb2e18102008-02-01 17:34:58 +100027#include <asm/mcfuart.h>
Greg Ungerer3196cf82006-06-26 10:33:10 +100028#include <asm/mcfdma.h>
29#include <asm/mcfwdebug.h>
Steven King12ce4c12012-06-17 00:41:39 -070030#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);
Steven King2d24b532014-06-30 09:53:19 -070041DEFINE_CLK(0, "imx1-i2c.0", 22, MCF_CLK);
Steven King12ce4c12012-06-17 00:41:39 -070042DEFINE_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 */
Steven King2d24b532014-06-30 09:53:19 -070080 &__clk_0_22, /* imx1-i2c.0 */
Steven King12ce4c12012-06-17 00:41:39 -070081 &__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 */
Greg Ungerer2842e5b02013-04-17 00:17:53 +1000121 &__clk_0_28, /* mcftmr.0 */
122 &__clk_0_29, /* mcftmr.1 */
Steven King12ce4c12012-06-17 00:41:39 -0700123 &__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 */
Steven King2d24b532014-06-30 09:53:19 -0700136 &__clk_0_22, /* imx1-i2c.0 */
Steven King12ce4c12012-06-17 00:41:39 -0700137 &__clk_0_23, /* mcfqspi.0 */
Steven King12ce4c12012-06-17 00:41:39 -0700138 &__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
Greg Ungerere73cbe22012-11-05 15:05:53 +1000155static void __init m53xx_clk_init(void)
Steven King12ce4c12012-06-17 00:41:39 -0700156{
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}
Greg Ungerer3196cf82006-06-26 10:33:10 +1000166
167/***************************************************************************/
168
Greg Ungerere73cbe22012-11-05 15:05:53 +1000169static void __init m53xx_qspi_init(void)
Steven King91d60412010-01-22 12:43:03 -0800170{
Steven King151d14f2014-05-14 10:07:55 -0700171#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
Steven King91d60412010-01-22 12:43:03 -0800172 /* setup QSPS pins for QSPI with gpio CS control */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000173 writew(0x01f0, MCFGPIO_PAR_QSPI);
Steven King83ca6002012-05-06 12:22:53 -0700174#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
Steven King151d14f2014-05-14 10:07:55 -0700175}
Greg Ungererb2e18102008-02-01 17:34:58 +1000176
177/***************************************************************************/
178
Steven King2d24b532014-06-30 09:53:19 -0700179static 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
Greg Ungerere73cbe22012-11-05 15:05:53 +1000192static void __init m53xx_uarts_init(void)
Greg Ungererb2e18102008-02-01 17:34:58 +1000193{
Greg Ungerera75bc612011-12-24 01:04:22 +1000194 /* UART GPIO initialization */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000195 writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
Greg Ungererb2e18102008-02-01 17:34:58 +1000196}
Greg Ungerera75bc612011-12-24 01:04:22 +1000197
Greg Ungererffba3f42009-02-26 22:40:38 -0800198/***************************************************************************/
199
Greg Ungerere73cbe22012-11-05 15:05:53 +1000200static void __init m53xx_fec_init(void)
Greg Ungererffba3f42009-02-26 22:40:38 -0800201{
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000202 u8 v;
203
Greg Ungererffba3f42009-02-26 22:40:38 -0800204 /* Set multi-function pins to ethernet mode for fec0 */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000205 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);
Greg Ungererffba3f42009-02-26 22:40:38 -0800213}
Greg Ungerer3196cf82006-06-26 10:33:10 +1000214
215/***************************************************************************/
216
Greg Ungererb2e18102008-02-01 17:34:58 +1000217void __init config_BSP(char *commandp, int size)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000218{
Greg Ungererbc724502007-07-25 22:07:20 +1000219#if !defined(CONFIG_BOOTPARAM)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000220 /* 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
Greg Ungerer35aefb22012-01-23 15:34:58 +1000229 mach_sched_init = hw_timer_init;
Greg Ungerere73cbe22012-11-05 15:05:53 +1000230 m53xx_clk_init();
231 m53xx_uarts_init();
232 m53xx_fec_init();
Greg Ungerere73cbe22012-11-05 15:05:53 +1000233 m53xx_qspi_init();
Steven King2d24b532014-06-30 09:53:19 -0700234 m53xx_i2c_init();
Greg Ungerer35aefb22012-01-23 15:34:58 +1000235
Greg Ungererb2e18102008-02-01 17:34:58 +1000236#ifdef CONFIG_BDM_DISABLE
Greg Ungerer3196cf82006-06-26 10:33:10 +1000237 /*
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/***************************************************************************/
Greg Ungererb2e18102008-02-01 17:34:58 +1000247/* Board initialization */
248/***************************************************************************/
Greg Ungerer3196cf82006-06-26 10:33:10 +1000249/*
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
Greg Ungerer3196cf82006-06-26 10:33:10 +1000288void wtm_init(void);
289void scm_init(void);
290void gpio_init(void);
291void fbcs_init(void);
292void sdramc_init(void);
293int clock_pll (int fsys, int flags);
294int clock_limp (int);
295int clock_exit_limp (void);
296int get_sys_clock (void);
297
298asmlinkage void __init sysinit(void)
299{
Greg Ungererbc065e42016-08-23 16:29:43 +1000300 clock_pll(0, 0);
301
Greg Ungerer3196cf82006-06-26 10:33:10 +1000302 wtm_init();
303 scm_init();
304 gpio_init();
305 fbcs_init();
306 sdramc_init();
307}
308
309void wtm_init(void)
310{
311 /* Disable watchdog timer */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000312 writew(0, MCF_WTM_WCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000313}
314
315#define MCF_SCM_BCR_GBW (0x00000100)
316#define MCF_SCM_BCR_GBR (0x00000200)
317
318void scm_init(void)
319{
320 /* All masters are trusted */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000321 writel(0x77777777, MCF_SCM_MPR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000322
323 /* Allow supervisor/user, read/write, and trusted/untrusted
324 access to all slaves */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000325 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000331
332 /* Enable bursts */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000333 writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000334}
335
336
337void fbcs_init(void)
338{
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000339 writeb(0x3E, MCFGPIO_PAR_CS);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000340
341 /* Latch chip select */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000342 writel(0x10080000, MCF_FBCS1_CSAR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000343
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000344 writel(0x002A3780, MCF_FBCS1_CSCR);
345 writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000346
347 /* Initialize latch to drive signals to inactive states */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000348 writew(0xffff, 0x10080000);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000349
350 /* External SRAM */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000351 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000358
359 /* Boot Flash connected to FBCS0 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000360 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000368}
369
370void sdramc_init(void)
371{
372 /*
373 * Check to see if the SDRAM has already been initialized
374 * by a run control tool
375 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000376 if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
Greg Ungerer3196cf82006-06-26 10:33:10 +1000377 /* SDRAM chip select initialization */
378
379 /* Initialize SDRAM chip select */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000380 writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
381 MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
382 MCF_SDRAMC_SDCS0);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000383
384 /*
385 * Basic configuration and initialization
386 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000387 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000400
401
402 /*
403 * Precharge and enable write to SDMR
404 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000405 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000413
414 /*
415 * Write extended mode register
416 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000417 writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
418 MCF_SDRAMC_SDMR_AD(0x0) |
419 MCF_SDRAMC_SDMR_CMD,
420 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000421
422 /*
423 * Write mode register and reset DLL
424 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000425 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
426 MCF_SDRAMC_SDMR_AD(0x163) |
427 MCF_SDRAMC_SDMR_CMD,
428 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000429
430 /*
431 * Execute a PALL command
432 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000433 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000434
435 /*
436 * Perform two REF cycles
437 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000438 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000440
441 /*
442 * Write mode register and clear reset DLL
443 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000444 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
445 MCF_SDRAMC_SDMR_AD(0x063) |
446 MCF_SDRAMC_SDMR_CMD,
447 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000448
449 /*
450 * Enable auto refresh and lock SDMR
451 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000452 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000456 }
457}
458
459void gpio_init(void)
460{
461 /* Enable UART0 pins */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000462 writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
463 MCFGPIO_PAR_UART);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000464
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000465 /*
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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000472}
473
474int 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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000483 mfd = readb(MCF_PLL_PFDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000484
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000509 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000510 /* Put SDRAM into self refresh mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000511 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
512 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000513
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000523 writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
524 MCF_PLL_PODR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000525
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000526 writeb(mfd, MCF_PLL_PFDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000527
528 /* Exit LIMP mode */
529 clock_exit_limp();
530
531 /*
532 * Return the SDRAM to normal operation if it is in use.
533 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000534 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000535 /* Exit self refresh mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000536 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
537 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000538
539 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000540 writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000541
542 /* wait for DQS logic to relock */
543 for (i = 0; i < 0x200; i++)
544 ;
545
546 return fout;
547}
548
549int 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*/
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000561 temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000562
563 /* Apply the divider to the system clock */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000564 writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000565
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000566 writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000567
568 return (FREF/(3*(1 << div)));
569}
570
571int clock_exit_limp(void)
572{
573 int fout;
574
575 /* Exit LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000576 writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000577
578 /* Wait for PLL to lock */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000579 while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
Greg Ungerer3196cf82006-06-26 10:33:10 +1000580 ;
581
582 fout = get_sys_clock();
583
584 return fout;
585}
586
587int get_sys_clock(void)
588{
589 int divider;
590
591 /* Test to see if device is in LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000592 if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
593 divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000594 return (FREF/(2 << divider));
595 }
596 else
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000597 return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000598}