blob: 8c0dd5caae9799b19527fee8dc4bd866077884e0 [file] [log] [blame]
Greg Ungerer3196cf82006-06-26 10:33:10 +10001/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/532x/config.c
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
10 * Copyright (c) 2006, emlix, Sebastian Hess <sh@emlix.com>
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
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>
30
31/***************************************************************************/
32
Greg Ungererfa1fc242011-12-24 12:56:10 +100033#ifdef CONFIG_SPI_COLDFIRE_QSPI
Steven King91d60412010-01-22 12:43:03 -080034
35static void __init m532x_qspi_init(void)
36{
37 /* setup QSPS pins for QSPI with gpio CS control */
38 writew(0x01f0, MCF_GPIO_PAR_QSPI);
39}
Steven King91d60412010-01-22 12:43:03 -080040
Greg Ungererfa1fc242011-12-24 12:56:10 +100041#endif /* CONFIG_SPI_COLDFIRE_QSPI */
Greg Ungererb2e18102008-02-01 17:34:58 +100042
43/***************************************************************************/
44
Greg Ungererb2e18102008-02-01 17:34:58 +100045static void __init m532x_uarts_init(void)
46{
Greg Ungerera75bc612011-12-24 01:04:22 +100047 /* UART GPIO initialization */
48 MCF_GPIO_PAR_UART |= 0x0FFF;
Greg Ungererb2e18102008-02-01 17:34:58 +100049}
Greg Ungerera75bc612011-12-24 01:04:22 +100050
Greg Ungererffba3f42009-02-26 22:40:38 -080051/***************************************************************************/
52
53static void __init m532x_fec_init(void)
54{
Greg Ungererffba3f42009-02-26 22:40:38 -080055 /* Set multi-function pins to ethernet mode for fec0 */
56 MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
57 MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
58 MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
59 MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
60}
Greg Ungerer3196cf82006-06-26 10:33:10 +100061
62/***************************************************************************/
63
Greg Ungerer384feb92009-04-30 22:03:43 +100064static void m532x_cpu_reset(void)
65{
66 local_irq_disable();
67 __raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
68}
69
70/***************************************************************************/
71
Greg Ungererb2e18102008-02-01 17:34:58 +100072void __init config_BSP(char *commandp, int size)
Greg Ungerer3196cf82006-06-26 10:33:10 +100073{
Greg Ungererbc724502007-07-25 22:07:20 +100074#if !defined(CONFIG_BOOTPARAM)
Greg Ungerer3196cf82006-06-26 10:33:10 +100075 /* Copy command line from FLASH to local buffer... */
76 memcpy(commandp, (char *) 0x4000, 4);
77 if(strncmp(commandp, "kcl ", 4) == 0){
78 memcpy(commandp, (char *) 0x4004, size);
79 commandp[size-1] = 0;
80 } else {
81 memset(commandp, 0, size);
82 }
83#endif
84
Greg Ungerer35aefb22012-01-23 15:34:58 +100085 mach_sched_init = hw_timer_init;
86
Greg Ungererb2e18102008-02-01 17:34:58 +100087#ifdef CONFIG_BDM_DISABLE
Greg Ungerer3196cf82006-06-26 10:33:10 +100088 /*
89 * Disable the BDM clocking. This also turns off most of the rest of
90 * the BDM device. This is good for EMC reasons. This option is not
91 * incompatible with the memory protection option.
92 */
93 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
94#endif
95}
96
97/***************************************************************************/
Greg Ungerer3196cf82006-06-26 10:33:10 +100098
Greg Ungererb2e18102008-02-01 17:34:58 +100099static int __init init_BSP(void)
100{
101 m532x_uarts_init();
Greg Ungererffba3f42009-02-26 22:40:38 -0800102 m532x_fec_init();
Greg Ungererfa1fc242011-12-24 12:56:10 +1000103#ifdef CONFIG_SPI_COLDFIRE_QSPI
Steven King91d60412010-01-22 12:43:03 -0800104 m532x_qspi_init();
105#endif
Greg Ungererb2e18102008-02-01 17:34:58 +1000106 return 0;
107}
108
109arch_initcall(init_BSP);
110
111/***************************************************************************/
112/* Board initialization */
113/***************************************************************************/
Greg Ungerer3196cf82006-06-26 10:33:10 +1000114/*
115 * PLL min/max specifications
116 */
117#define MAX_FVCO 500000 /* KHz */
118#define MAX_FSYS 80000 /* KHz */
119#define MIN_FSYS 58333 /* KHz */
120#define FREF 16000 /* KHz */
121
122
123#define MAX_MFD 135 /* Multiplier */
124#define MIN_MFD 88 /* Multiplier */
125#define BUSDIV 6 /* Divider */
126
127/*
128 * Low Power Divider specifications
129 */
130#define MIN_LPD (1 << 0) /* Divider (not encoded) */
131#define MAX_LPD (1 << 15) /* Divider (not encoded) */
132#define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
133
134#define SYS_CLK_KHZ 80000
135#define SYSTEM_PERIOD 12.5
136/*
137 * SDRAM Timing Parameters
138 */
139#define SDRAM_BL 8 /* # of beats in a burst */
140#define SDRAM_TWR 2 /* in clocks */
141#define SDRAM_CASL 2.5 /* CASL in clocks */
142#define SDRAM_TRCD 2 /* in clocks */
143#define SDRAM_TRP 2 /* in clocks */
144#define SDRAM_TRFC 7 /* in clocks */
145#define SDRAM_TREFI 7800 /* in ns */
146
147#define EXT_SRAM_ADDRESS (0xC0000000)
148#define FLASH_ADDRESS (0x00000000)
149#define SDRAM_ADDRESS (0x40000000)
150
151#define NAND_FLASH_ADDRESS (0xD0000000)
152
153int sys_clk_khz = 0;
154int sys_clk_mhz = 0;
155
156void wtm_init(void);
157void scm_init(void);
158void gpio_init(void);
159void fbcs_init(void);
160void sdramc_init(void);
161int clock_pll (int fsys, int flags);
162int clock_limp (int);
163int clock_exit_limp (void);
164int get_sys_clock (void);
165
166asmlinkage void __init sysinit(void)
167{
168 sys_clk_khz = clock_pll(0, 0);
169 sys_clk_mhz = sys_clk_khz/1000;
170
171 wtm_init();
172 scm_init();
173 gpio_init();
174 fbcs_init();
175 sdramc_init();
176}
177
178void wtm_init(void)
179{
180 /* Disable watchdog timer */
181 MCF_WTM_WCR = 0;
182}
183
184#define MCF_SCM_BCR_GBW (0x00000100)
185#define MCF_SCM_BCR_GBR (0x00000200)
186
187void scm_init(void)
188{
189 /* All masters are trusted */
190 MCF_SCM_MPR = 0x77777777;
191
192 /* Allow supervisor/user, read/write, and trusted/untrusted
193 access to all slaves */
194 MCF_SCM_PACRA = 0;
195 MCF_SCM_PACRB = 0;
196 MCF_SCM_PACRC = 0;
197 MCF_SCM_PACRD = 0;
198 MCF_SCM_PACRE = 0;
199 MCF_SCM_PACRF = 0;
200
201 /* Enable bursts */
202 MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
203}
204
205
206void fbcs_init(void)
207{
208 MCF_GPIO_PAR_CS = 0x0000003E;
209
210 /* Latch chip select */
211 MCF_FBCS1_CSAR = 0x10080000;
212
213 MCF_FBCS1_CSCR = 0x002A3780;
214 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
215
216 /* Initialize latch to drive signals to inactive states */
217 *((u16 *)(0x10080000)) = 0xFFFF;
218
219 /* External SRAM */
220 MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
221 MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
222 | MCF_FBCS_CSCR_AA
223 | MCF_FBCS_CSCR_SBM
224 | MCF_FBCS_CSCR_WS(1));
225 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
226 | MCF_FBCS_CSMR_V);
227
228 /* Boot Flash connected to FBCS0 */
229 MCF_FBCS0_CSAR = FLASH_ADDRESS;
230 MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
231 | MCF_FBCS_CSCR_BEM
232 | MCF_FBCS_CSCR_AA
233 | MCF_FBCS_CSCR_SBM
234 | MCF_FBCS_CSCR_WS(7));
235 MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
236 | MCF_FBCS_CSMR_V);
237}
238
239void sdramc_init(void)
240{
241 /*
242 * Check to see if the SDRAM has already been initialized
243 * by a run control tool
244 */
245 if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
246 /* SDRAM chip select initialization */
247
248 /* Initialize SDRAM chip select */
249 MCF_SDRAMC_SDCS0 = (0
250 | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
251 | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
252
253 /*
254 * Basic configuration and initialization
255 */
256 MCF_SDRAMC_SDCFG1 = (0
257 | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
258 | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
259 | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
260 | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
261 | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
262 | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
263 | MCF_SDRAMC_SDCFG1_WTLAT(3));
264 MCF_SDRAMC_SDCFG2 = (0
265 | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
266 | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
267 | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
268 | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
269
270
271 /*
272 * Precharge and enable write to SDMR
273 */
274 MCF_SDRAMC_SDCR = (0
275 | MCF_SDRAMC_SDCR_MODE_EN
276 | MCF_SDRAMC_SDCR_CKE
277 | MCF_SDRAMC_SDCR_DDR
278 | MCF_SDRAMC_SDCR_MUX(1)
279 | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
280 | MCF_SDRAMC_SDCR_PS_16
281 | MCF_SDRAMC_SDCR_IPALL);
282
283 /*
284 * Write extended mode register
285 */
286 MCF_SDRAMC_SDMR = (0
287 | MCF_SDRAMC_SDMR_BNKAD_LEMR
288 | MCF_SDRAMC_SDMR_AD(0x0)
289 | MCF_SDRAMC_SDMR_CMD);
290
291 /*
292 * Write mode register and reset DLL
293 */
294 MCF_SDRAMC_SDMR = (0
295 | MCF_SDRAMC_SDMR_BNKAD_LMR
296 | MCF_SDRAMC_SDMR_AD(0x163)
297 | MCF_SDRAMC_SDMR_CMD);
298
299 /*
300 * Execute a PALL command
301 */
302 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
303
304 /*
305 * Perform two REF cycles
306 */
307 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
308 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
309
310 /*
311 * Write mode register and clear reset DLL
312 */
313 MCF_SDRAMC_SDMR = (0
314 | MCF_SDRAMC_SDMR_BNKAD_LMR
315 | MCF_SDRAMC_SDMR_AD(0x063)
316 | MCF_SDRAMC_SDMR_CMD);
317
318 /*
319 * Enable auto refresh and lock SDMR
320 */
321 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
322 MCF_SDRAMC_SDCR |= (0
323 | MCF_SDRAMC_SDCR_REF
324 | MCF_SDRAMC_SDCR_DQS_OE(0xC));
325 }
326}
327
328void gpio_init(void)
329{
330 /* Enable UART0 pins */
331 MCF_GPIO_PAR_UART = ( 0
332 | MCF_GPIO_PAR_UART_PAR_URXD0
333 | MCF_GPIO_PAR_UART_PAR_UTXD0);
334
335 /* Initialize TIN3 as a GPIO output to enable the write
336 half of the latch */
337 MCF_GPIO_PAR_TIMER = 0x00;
sfking@fdwdc.com7846fe82009-06-19 18:11:10 -0700338 __raw_writeb(0x08, MCFGPIO_PDDR_TIMER);
339 __raw_writeb(0x00, MCFGPIO_PCLRR_TIMER);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000340
341}
342
343int clock_pll(int fsys, int flags)
344{
345 int fref, temp, fout, mfd;
346 u32 i;
347
348 fref = FREF;
349
350 if (fsys == 0) {
351 /* Return current PLL output */
352 mfd = MCF_PLL_PFDR;
353
354 return (fref * mfd / (BUSDIV * 4));
355 }
356
357 /* Check bounds of requested system clock */
358 if (fsys > MAX_FSYS)
359 fsys = MAX_FSYS;
360 if (fsys < MIN_FSYS)
361 fsys = MIN_FSYS;
362
363 /* Multiplying by 100 when calculating the temp value,
364 and then dividing by 100 to calculate the mfd allows
365 for exact values without needing to include floating
366 point libraries. */
367 temp = 100 * fsys / fref;
368 mfd = 4 * BUSDIV * temp / 100;
369
370 /* Determine the output frequency for selected values */
371 fout = (fref * mfd / (BUSDIV * 4));
372
373 /*
374 * Check to see if the SDRAM has already been initialized.
375 * If it has then the SDRAM needs to be put into self refresh
376 * mode before reprogramming the PLL.
377 */
378 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
379 /* Put SDRAM into self refresh mode */
380 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
381
382 /*
383 * Initialize the PLL to generate the new system clock frequency.
384 * The device must be put into LIMP mode to reprogram the PLL.
385 */
386
387 /* Enter LIMP mode */
388 clock_limp(DEFAULT_LPD);
389
390 /* Reprogram PLL for desired fsys */
391 MCF_PLL_PODR = (0
392 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
393 | MCF_PLL_PODR_BUSDIV(BUSDIV));
394
395 MCF_PLL_PFDR = mfd;
396
397 /* Exit LIMP mode */
398 clock_exit_limp();
399
400 /*
401 * Return the SDRAM to normal operation if it is in use.
402 */
403 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
404 /* Exit self refresh mode */
405 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
406
407 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
408 MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
409
410 /* wait for DQS logic to relock */
411 for (i = 0; i < 0x200; i++)
412 ;
413
414 return fout;
415}
416
417int clock_limp(int div)
418{
419 u32 temp;
420
421 /* Check bounds of divider */
422 if (div < MIN_LPD)
423 div = MIN_LPD;
424 if (div > MAX_LPD)
425 div = MAX_LPD;
426
427 /* Save of the current value of the SSIDIV so we don't
428 overwrite the value*/
429 temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
430
431 /* Apply the divider to the system clock */
432 MCF_CCM_CDR = ( 0
433 | MCF_CCM_CDR_LPDIV(div)
434 | MCF_CCM_CDR_SSIDIV(temp));
435
436 MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
437
438 return (FREF/(3*(1 << div)));
439}
440
441int clock_exit_limp(void)
442{
443 int fout;
444
445 /* Exit LIMP mode */
446 MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
447
448 /* Wait for PLL to lock */
449 while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
450 ;
451
452 fout = get_sys_clock();
453
454 return fout;
455}
456
457int get_sys_clock(void)
458{
459 int divider;
460
461 /* Test to see if device is in LIMP mode */
462 if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
463 divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
464 return (FREF/(2 << divider));
465 }
466 else
467 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
468}