blob: 80879a7fe3d511f7b8d54e12e2206a0ed0e2c3c3 [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
274int sys_clk_khz = 0;
275int sys_clk_mhz = 0;
276
277void wtm_init(void);
278void scm_init(void);
279void gpio_init(void);
280void fbcs_init(void);
281void sdramc_init(void);
282int clock_pll (int fsys, int flags);
283int clock_limp (int);
284int clock_exit_limp (void);
285int get_sys_clock (void);
286
287asmlinkage void __init sysinit(void)
288{
289 sys_clk_khz = clock_pll(0, 0);
290 sys_clk_mhz = sys_clk_khz/1000;
291
292 wtm_init();
293 scm_init();
294 gpio_init();
295 fbcs_init();
296 sdramc_init();
297}
298
299void wtm_init(void)
300{
301 /* Disable watchdog timer */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000302 writew(0, MCF_WTM_WCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000303}
304
305#define MCF_SCM_BCR_GBW (0x00000100)
306#define MCF_SCM_BCR_GBR (0x00000200)
307
308void scm_init(void)
309{
310 /* All masters are trusted */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000311 writel(0x77777777, MCF_SCM_MPR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000312
313 /* Allow supervisor/user, read/write, and trusted/untrusted
314 access to all slaves */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000315 writel(0, MCF_SCM_PACRA);
316 writel(0, MCF_SCM_PACRB);
317 writel(0, MCF_SCM_PACRC);
318 writel(0, MCF_SCM_PACRD);
319 writel(0, MCF_SCM_PACRE);
320 writel(0, MCF_SCM_PACRF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000321
322 /* Enable bursts */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000323 writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000324}
325
326
327void fbcs_init(void)
328{
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000329 writeb(0x3E, MCFGPIO_PAR_CS);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000330
331 /* Latch chip select */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000332 writel(0x10080000, MCF_FBCS1_CSAR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000333
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000334 writel(0x002A3780, MCF_FBCS1_CSCR);
335 writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000336
337 /* Initialize latch to drive signals to inactive states */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000338 writew(0xffff, 0x10080000);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000339
340 /* External SRAM */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000341 writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
342 writel(MCF_FBCS_CSCR_PS_16 |
343 MCF_FBCS_CSCR_AA |
344 MCF_FBCS_CSCR_SBM |
345 MCF_FBCS_CSCR_WS(1),
346 MCF_FBCS1_CSCR);
347 writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000348
349 /* Boot Flash connected to FBCS0 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000350 writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
351 writel(MCF_FBCS_CSCR_PS_16 |
352 MCF_FBCS_CSCR_BEM |
353 MCF_FBCS_CSCR_AA |
354 MCF_FBCS_CSCR_SBM |
355 MCF_FBCS_CSCR_WS(7),
356 MCF_FBCS0_CSCR);
357 writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000358}
359
360void sdramc_init(void)
361{
362 /*
363 * Check to see if the SDRAM has already been initialized
364 * by a run control tool
365 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000366 if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
Greg Ungerer3196cf82006-06-26 10:33:10 +1000367 /* SDRAM chip select initialization */
368
369 /* Initialize SDRAM chip select */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000370 writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
371 MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
372 MCF_SDRAMC_SDCS0);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000373
374 /*
375 * Basic configuration and initialization
376 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000377 writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
378 MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
379 MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
380 MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
381 MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
382 MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
383 MCF_SDRAMC_SDCFG1_WTLAT(3),
384 MCF_SDRAMC_SDCFG1);
385 writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
386 MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
387 MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
388 MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
389 MCF_SDRAMC_SDCFG2);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000390
391
392 /*
393 * Precharge and enable write to SDMR
394 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000395 writel(MCF_SDRAMC_SDCR_MODE_EN |
396 MCF_SDRAMC_SDCR_CKE |
397 MCF_SDRAMC_SDCR_DDR |
398 MCF_SDRAMC_SDCR_MUX(1) |
399 MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
400 MCF_SDRAMC_SDCR_PS_16 |
401 MCF_SDRAMC_SDCR_IPALL,
402 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000403
404 /*
405 * Write extended mode register
406 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000407 writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
408 MCF_SDRAMC_SDMR_AD(0x0) |
409 MCF_SDRAMC_SDMR_CMD,
410 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000411
412 /*
413 * Write mode register and reset DLL
414 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000415 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
416 MCF_SDRAMC_SDMR_AD(0x163) |
417 MCF_SDRAMC_SDMR_CMD,
418 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000419
420 /*
421 * Execute a PALL command
422 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000423 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000424
425 /*
426 * Perform two REF cycles
427 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000428 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
429 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000430
431 /*
432 * Write mode register and clear reset DLL
433 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000434 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
435 MCF_SDRAMC_SDMR_AD(0x063) |
436 MCF_SDRAMC_SDMR_CMD,
437 MCF_SDRAMC_SDMR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000438
439 /*
440 * Enable auto refresh and lock SDMR
441 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000442 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
443 MCF_SDRAMC_SDCR);
444 writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
445 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000446 }
447}
448
449void gpio_init(void)
450{
451 /* Enable UART0 pins */
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000452 writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
453 MCFGPIO_PAR_UART);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000454
Greg Ungerere4c2b9b2012-09-17 15:26:25 +1000455 /*
456 * Initialize TIN3 as a GPIO output to enable the write
457 * half of the latch.
458 */
459 writeb(0x00, MCFGPIO_PAR_TIMER);
460 writeb(0x08, MCFGPIO_PDDR_TIMER);
461 writeb(0x00, MCFGPIO_PCLRR_TIMER);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000462}
463
464int clock_pll(int fsys, int flags)
465{
466 int fref, temp, fout, mfd;
467 u32 i;
468
469 fref = FREF;
470
471 if (fsys == 0) {
472 /* Return current PLL output */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000473 mfd = readb(MCF_PLL_PFDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000474
475 return (fref * mfd / (BUSDIV * 4));
476 }
477
478 /* Check bounds of requested system clock */
479 if (fsys > MAX_FSYS)
480 fsys = MAX_FSYS;
481 if (fsys < MIN_FSYS)
482 fsys = MIN_FSYS;
483
484 /* Multiplying by 100 when calculating the temp value,
485 and then dividing by 100 to calculate the mfd allows
486 for exact values without needing to include floating
487 point libraries. */
488 temp = 100 * fsys / fref;
489 mfd = 4 * BUSDIV * temp / 100;
490
491 /* Determine the output frequency for selected values */
492 fout = (fref * mfd / (BUSDIV * 4));
493
494 /*
495 * Check to see if the SDRAM has already been initialized.
496 * If it has then the SDRAM needs to be put into self refresh
497 * mode before reprogramming the PLL.
498 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000499 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000500 /* Put SDRAM into self refresh mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000501 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
502 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000503
504 /*
505 * Initialize the PLL to generate the new system clock frequency.
506 * The device must be put into LIMP mode to reprogram the PLL.
507 */
508
509 /* Enter LIMP mode */
510 clock_limp(DEFAULT_LPD);
511
512 /* Reprogram PLL for desired fsys */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000513 writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
514 MCF_PLL_PODR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000515
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000516 writeb(mfd, MCF_PLL_PFDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000517
518 /* Exit LIMP mode */
519 clock_exit_limp();
520
521 /*
522 * Return the SDRAM to normal operation if it is in use.
523 */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000524 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
Greg Ungerer3196cf82006-06-26 10:33:10 +1000525 /* Exit self refresh mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000526 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
527 MCF_SDRAMC_SDCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000528
529 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000530 writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000531
532 /* wait for DQS logic to relock */
533 for (i = 0; i < 0x200; i++)
534 ;
535
536 return fout;
537}
538
539int clock_limp(int div)
540{
541 u32 temp;
542
543 /* Check bounds of divider */
544 if (div < MIN_LPD)
545 div = MIN_LPD;
546 if (div > MAX_LPD)
547 div = MAX_LPD;
548
549 /* Save of the current value of the SSIDIV so we don't
550 overwrite the value*/
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000551 temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000552
553 /* Apply the divider to the system clock */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000554 writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000555
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000556 writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000557
558 return (FREF/(3*(1 << div)));
559}
560
561int clock_exit_limp(void)
562{
563 int fout;
564
565 /* Exit LIMP mode */
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 /* Wait for PLL to lock */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000569 while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
Greg Ungerer3196cf82006-06-26 10:33:10 +1000570 ;
571
572 fout = get_sys_clock();
573
574 return fout;
575}
576
577int get_sys_clock(void)
578{
579 int divider;
580
581 /* Test to see if device is in LIMP mode */
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000582 if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
583 divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000584 return (FREF/(2 << divider));
585 }
586 else
Greg Ungerer6d8a1392012-09-17 16:16:19 +1000587 return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000588}