blob: 5286f98fbed075cbe73298c02bd6b568beb332c2 [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
Steven King83ca6002012-05-06 12:22:53 -0700169#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
Steven King91d60412010-01-22 12:43:03 -0800170
Greg Ungerere73cbe22012-11-05 15:05:53 +1000171static void __init m53xx_qspi_init(void)
Steven King91d60412010-01-22 12:43:03 -0800172{
173 /* setup QSPS pins for QSPI with gpio CS control */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000174 writew(0x01f0, MCFGPIO_PAR_QSPI);
Steven King91d60412010-01-22 12:43:03 -0800175}
Steven King91d60412010-01-22 12:43:03 -0800176
Steven King83ca6002012-05-06 12:22:53 -0700177#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
Greg Ungererb2e18102008-02-01 17:34:58 +1000178
179/***************************************************************************/
180
Greg Ungerere73cbe22012-11-05 15:05:53 +1000181static void __init m53xx_uarts_init(void)
Greg Ungererb2e18102008-02-01 17:34:58 +1000182{
Greg Ungerera75bc612011-12-24 01:04:22 +1000183 /* UART GPIO initialization */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000184 writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
Greg Ungererb2e18102008-02-01 17:34:58 +1000185}
Greg Ungerera75bc612011-12-24 01:04:22 +1000186
Greg Ungererffba3f42009-02-26 22:40:38 -0800187/***************************************************************************/
188
Greg Ungerere73cbe22012-11-05 15:05:53 +1000189static void __init m53xx_fec_init(void)
Greg Ungererffba3f42009-02-26 22:40:38 -0800190{
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000191 u8 v;
192
Greg Ungererffba3f42009-02-26 22:40:38 -0800193 /* Set multi-function pins to ethernet mode for fec0 */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000194 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);
Greg Ungererffba3f42009-02-26 22:40:38 -0800202}
Greg Ungerer3196cf82006-06-26 10:33:10 +1000203
204/***************************************************************************/
205
Greg Ungererb2e18102008-02-01 17:34:58 +1000206void __init config_BSP(char *commandp, int size)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000207{
Greg Ungererbc724502007-07-25 22:07:20 +1000208#if !defined(CONFIG_BOOTPARAM)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000209 /* 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
Greg Ungerer35aefb22012-01-23 15:34:58 +1000218 mach_sched_init = hw_timer_init;
Greg Ungerere73cbe22012-11-05 15:05:53 +1000219 m53xx_clk_init();
220 m53xx_uarts_init();
221 m53xx_fec_init();
Steven King83ca6002012-05-06 12:22:53 -0700222#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
Greg Ungerere73cbe22012-11-05 15:05:53 +1000223 m53xx_qspi_init();
Greg Ungererc05793c2011-12-24 13:06:33 +1000224#endif
Greg Ungerer35aefb22012-01-23 15:34:58 +1000225
Greg Ungererb2e18102008-02-01 17:34:58 +1000226#ifdef CONFIG_BDM_DISABLE
Greg Ungerer3196cf82006-06-26 10:33:10 +1000227 /*
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/***************************************************************************/
Greg Ungererb2e18102008-02-01 17:34:58 +1000237/* Board initialization */
238/***************************************************************************/
Greg Ungerer3196cf82006-06-26 10:33:10 +1000239/*
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
278int sys_clk_khz = 0;
279int sys_clk_mhz = 0;
280
281void wtm_init(void);
282void scm_init(void);
283void gpio_init(void);
284void fbcs_init(void);
285void sdramc_init(void);
286int clock_pll (int fsys, int flags);
287int clock_limp (int);
288int clock_exit_limp (void);
289int get_sys_clock (void);
290
291asmlinkage 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
303void wtm_init(void)
304{
305 /* Disable watchdog timer */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000306 writew(0, MCF_WTM_WCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000307}
308
309#define MCF_SCM_BCR_GBW (0x00000100)
310#define MCF_SCM_BCR_GBR (0x00000200)
311
312void scm_init(void)
313{
314 /* All masters are trusted */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000315 writel(0x77777777, MCF_SCM_MPR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000316
317 /* Allow supervisor/user, read/write, and trusted/untrusted
318 access to all slaves */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000319 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000325
326 /* Enable bursts */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000327 writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000328}
329
330
331void fbcs_init(void)
332{
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000333 writeb(0x3E, MCFGPIO_PAR_CS);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000334
335 /* Latch chip select */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000336 writel(0x10080000, MCF_FBCS1_CSAR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000337
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000338 writel(0x002A3780, MCF_FBCS1_CSCR);
339 writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000340
341 /* Initialize latch to drive signals to inactive states */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000342 writew(0xffff, 0x10080000);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000343
344 /* External SRAM */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000345 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000352
353 /* Boot Flash connected to FBCS0 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000354 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000362}
363
364void sdramc_init(void)
365{
366 /*
367 * Check to see if the SDRAM has already been initialized
368 * by a run control tool
369 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000370 if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
Greg Ungerer3196cf82006-06-26 10:33:10 +1000371 /* SDRAM chip select initialization */
372
373 /* Initialize SDRAM chip select */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000374 writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
375 MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
376 MCF_SDRAMC_SDCS0);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000377
378 /*
379 * Basic configuration and initialization
380 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000381 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000394
395
396 /*
397 * Precharge and enable write to SDMR
398 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000399 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000407
408 /*
409 * Write extended mode register
410 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000411 writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
412 MCF_SDRAMC_SDMR_AD(0x0) |
413 MCF_SDRAMC_SDMR_CMD,
414 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000415
416 /*
417 * Write mode register and reset DLL
418 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000419 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
420 MCF_SDRAMC_SDMR_AD(0x163) |
421 MCF_SDRAMC_SDMR_CMD,
422 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000423
424 /*
425 * Execute a PALL command
426 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000427 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000428
429 /*
430 * Perform two REF cycles
431 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000432 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000434
435 /*
436 * Write mode register and clear reset DLL
437 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000438 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
439 MCF_SDRAMC_SDMR_AD(0x063) |
440 MCF_SDRAMC_SDMR_CMD,
441 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000442
443 /*
444 * Enable auto refresh and lock SDMR
445 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000446 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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000450 }
451}
452
453void gpio_init(void)
454{
455 /* Enable UART0 pins */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000456 writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
457 MCFGPIO_PAR_UART);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000458
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000459 /*
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);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000466}
467
468int 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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000477 mfd = readb(MCF_PLL_PFDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000478
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000503 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000504 /* Put SDRAM into self refresh mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000505 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
506 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000507
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 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000517 writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
518 MCF_PLL_PODR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000519
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000520 writeb(mfd, MCF_PLL_PFDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000521
522 /* Exit LIMP mode */
523 clock_exit_limp();
524
525 /*
526 * Return the SDRAM to normal operation if it is in use.
527 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000528 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000529 /* Exit self refresh mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000530 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
531 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000532
533 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000534 writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000535
536 /* wait for DQS logic to relock */
537 for (i = 0; i < 0x200; i++)
538 ;
539
540 return fout;
541}
542
543int 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*/
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000555 temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000556
557 /* Apply the divider to the system clock */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000558 writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000559
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000560 writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000561
562 return (FREF/(3*(1 << div)));
563}
564
565int clock_exit_limp(void)
566{
567 int fout;
568
569 /* Exit LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000570 writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000571
572 /* Wait for PLL to lock */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000573 while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
Greg Ungerer3196cf82006-06-26 10:33:10 +1000574 ;
575
576 fout = get_sys_clock();
577
578 return fout;
579}
580
581int get_sys_clock(void)
582{
583 int divider;
584
585 /* Test to see if device is in LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000586 if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
587 divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000588 return (FREF/(2 << divider));
589 }
590 else
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000591 return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000592}