blob: 2502f63960bcda5b94cfb5b2426dd1d5648fc980 [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);
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 */
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 */
136 &__clk_0_22, /* mcfi2c.0 */
137 &__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
Greg Ungerere73cbe22012-11-05 15:05:53 +1000179static void __init m53xx_uarts_init(void)
Greg Ungererb2e18102008-02-01 17:34:58 +1000180{
Greg Ungerera75bc612011-12-24 01:04:22 +1000181 /* UART GPIO initialization */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000182 writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
Greg Ungererb2e18102008-02-01 17:34:58 +1000183}
Greg Ungerera75bc612011-12-24 01:04:22 +1000184
Greg Ungererffba3f42009-02-26 22:40:38 -0800185/***************************************************************************/
186
Greg Ungerere73cbe22012-11-05 15:05:53 +1000187static void __init m53xx_fec_init(void)
Greg Ungererffba3f42009-02-26 22:40:38 -0800188{
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000189 u8 v;
190
Greg Ungererffba3f42009-02-26 22:40:38 -0800191 /* Set multi-function pins to ethernet mode for fec0 */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000192 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);
Greg Ungererffba3f42009-02-26 22:40:38 -0800200}
Greg Ungerer3196cf82006-06-26 10:33:10 +1000201
202/***************************************************************************/
203
Greg Ungererb2e18102008-02-01 17:34:58 +1000204void __init config_BSP(char *commandp, int size)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000205{
Greg Ungererbc724502007-07-25 22:07:20 +1000206#if !defined(CONFIG_BOOTPARAM)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000207 /* 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
Greg Ungerer35aefb22012-01-23 15:34:58 +1000216 mach_sched_init = hw_timer_init;
Greg Ungerere73cbe22012-11-05 15:05:53 +1000217 m53xx_clk_init();
218 m53xx_uarts_init();
219 m53xx_fec_init();
Greg Ungerere73cbe22012-11-05 15:05:53 +1000220 m53xx_qspi_init();
Greg Ungerer35aefb22012-01-23 15:34:58 +1000221
Greg Ungererb2e18102008-02-01 17:34:58 +1000222#ifdef CONFIG_BDM_DISABLE
Greg Ungerer3196cf82006-06-26 10:33:10 +1000223 /*
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
232/***************************************************************************/
Greg Ungererb2e18102008-02-01 17:34:58 +1000233/* Board initialization */
234/***************************************************************************/
Greg Ungerer3196cf82006-06-26 10:33:10 +1000235/*
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
Greg Ungerer3196cf82006-06-26 10:33:10 +1000274void 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{
Greg Ungererbc065e42016-08-23 16:29:43 +1000286 clock_pll(0, 0);
287
Greg Ungerer3196cf82006-06-26 10:33:10 +1000288 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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000298 writew(0, MCF_WTM_WCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000299}
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000307 writel(0x77777777, MCF_SCM_MPR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000308
309 /* Allow supervisor/user, read/write, and trusted/untrusted
310 access to all slaves */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000311 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000317
318 /* Enable bursts */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000319 writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000320}
321
322
323void fbcs_init(void)
324{
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000325 writeb(0x3E, MCFGPIO_PAR_CS);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000326
327 /* Latch chip select */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000328 writel(0x10080000, MCF_FBCS1_CSAR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000329
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000330 writel(0x002A3780, MCF_FBCS1_CSCR);
331 writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000332
333 /* Initialize latch to drive signals to inactive states */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000334 writew(0xffff, 0x10080000);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000335
336 /* External SRAM */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000337 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000344
345 /* Boot Flash connected to FBCS0 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000346 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000354}
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000362 if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
Greg Ungerer3196cf82006-06-26 10:33:10 +1000363 /* SDRAM chip select initialization */
364
365 /* Initialize SDRAM chip select */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000366 writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
367 MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
368 MCF_SDRAMC_SDCS0);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000369
370 /*
371 * Basic configuration and initialization
372 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000373 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000386
387
388 /*
389 * Precharge and enable write to SDMR
390 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000391 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000399
400 /*
401 * Write extended mode register
402 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000403 writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
404 MCF_SDRAMC_SDMR_AD(0x0) |
405 MCF_SDRAMC_SDMR_CMD,
406 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000407
408 /*
409 * Write mode register and reset DLL
410 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000411 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
412 MCF_SDRAMC_SDMR_AD(0x163) |
413 MCF_SDRAMC_SDMR_CMD,
414 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000415
416 /*
417 * Execute a PALL command
418 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000419 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000420
421 /*
422 * Perform two REF cycles
423 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000424 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000426
427 /*
428 * Write mode register and clear reset DLL
429 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000430 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
431 MCF_SDRAMC_SDMR_AD(0x063) |
432 MCF_SDRAMC_SDMR_CMD,
433 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000434
435 /*
436 * Enable auto refresh and lock SDMR
437 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000438 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000442 }
443}
444
445void gpio_init(void)
446{
447 /* Enable UART0 pins */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000448 writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
449 MCFGPIO_PAR_UART);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000450
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000451 /*
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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000458}
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000469 mfd = readb(MCF_PLL_PFDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000470
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000495 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000496 /* Put SDRAM into self refresh mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000497 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
498 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000499
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000509 writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
510 MCF_PLL_PODR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000511
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000512 writeb(mfd, MCF_PLL_PFDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000513
514 /* Exit LIMP mode */
515 clock_exit_limp();
516
517 /*
518 * Return the SDRAM to normal operation if it is in use.
519 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000520 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000521 /* Exit self refresh mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000522 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
523 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000524
525 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000526 writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000527
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*/
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000547 temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000548
549 /* Apply the divider to the system clock */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000550 writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000551
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000552 writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000553
554 return (FREF/(3*(1 << div)));
555}
556
557int clock_exit_limp(void)
558{
559 int fout;
560
561 /* Exit LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000562 writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000563
564 /* Wait for PLL to lock */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000565 while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
Greg Ungerer3196cf82006-06-26 10:33:10 +1000566 ;
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000578 if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
579 divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000580 return (FREF/(2 << divider));
581 }
582 else
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000583 return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000584}