• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************/
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 
20 #include <linux/kernel.h>
21 #include <linux/param.h>
22 #include <linux/init.h>
23 #include <linux/interrupt.h>
24 #include <linux/io.h>
25 #include <asm/machdep.h>
26 #include <asm/coldfire.h>
27 #include <asm/mcfsim.h>
28 #include <asm/mcfuart.h>
29 #include <asm/mcfdma.h>
30 #include <asm/mcfwdebug.h>
31 
32 /***************************************************************************/
33 
34 void coldfire_reset(void);
35 
36 extern unsigned int mcf_timervector;
37 extern unsigned int mcf_profilevector;
38 extern unsigned int mcf_timerlevel;
39 
40 /***************************************************************************/
41 
42 static struct mcf_platform_uart m532x_uart_platform[] = {
43 	{
44 		.mapbase	= MCFUART_BASE1,
45 		.irq		= MCFINT_VECBASE + MCFINT_UART0,
46 	},
47 	{
48 		.mapbase 	= MCFUART_BASE2,
49 		.irq		= MCFINT_VECBASE + MCFINT_UART1,
50 	},
51 	{
52 		.mapbase 	= MCFUART_BASE3,
53 		.irq		= MCFINT_VECBASE + MCFINT_UART2,
54 	},
55 	{ },
56 };
57 
58 static struct platform_device m532x_uart = {
59 	.name			= "mcfuart",
60 	.id			= 0,
61 	.dev.platform_data	= m532x_uart_platform,
62 };
63 
64 static struct platform_device *m532x_devices[] __initdata = {
65 	&m532x_uart,
66 };
67 
68 /***************************************************************************/
69 
m532x_uart_init_line(int line,int irq)70 static void __init m532x_uart_init_line(int line, int irq)
71 {
72 	if (line == 0) {
73 		MCF_INTC0_ICR26 = 0x3;
74 		MCF_INTC0_CIMR = 26;
75 		/* GPIO initialization */
76 		MCF_GPIO_PAR_UART |= 0x000F;
77 	} else if (line == 1) {
78 		MCF_INTC0_ICR27 = 0x3;
79 		MCF_INTC0_CIMR = 27;
80 		/* GPIO initialization */
81 		MCF_GPIO_PAR_UART |= 0x0FF0;
82 	} else if (line == 2) {
83 		MCF_INTC0_ICR28 = 0x3;
84 		MCF_INTC0_CIMR = 28;
85 	}
86 }
87 
m532x_uarts_init(void)88 static void __init m532x_uarts_init(void)
89 {
90 	const int nrlines = ARRAY_SIZE(m532x_uart_platform);
91 	int line;
92 
93 	for (line = 0; (line < nrlines); line++)
94 		m532x_uart_init_line(line, m532x_uart_platform[line].irq);
95 }
96 
97 /***************************************************************************/
98 
mcf_settimericr(unsigned int timer,unsigned int level)99 void mcf_settimericr(unsigned int timer, unsigned int level)
100 {
101 	volatile unsigned char *icrp;
102 	unsigned int icr;
103 	unsigned char irq;
104 
105 	if (timer <= 2) {
106 		switch (timer) {
107 		case 2:  irq = 33; icr = MCFSIM_ICR_TIMER2; break;
108 		default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
109 		}
110 
111 		icrp = (volatile unsigned char *) (icr);
112 		*icrp = level;
113 		mcf_enable_irq0(irq);
114 	}
115 }
116 
117 /***************************************************************************/
118 
config_BSP(char * commandp,int size)119 void __init config_BSP(char *commandp, int size)
120 {
121 	mcf_setimr(MCFSIM_IMR_MASKALL);
122 
123 #if !defined(CONFIG_BOOTPARAM)
124 	/* Copy command line from FLASH to local buffer... */
125 	memcpy(commandp, (char *) 0x4000, 4);
126 	if(strncmp(commandp, "kcl ", 4) == 0){
127 		memcpy(commandp, (char *) 0x4004, size);
128 		commandp[size-1] = 0;
129 	} else {
130 		memset(commandp, 0, size);
131 	}
132 #endif
133 
134 	mcf_timervector = 64+32;
135 	mcf_profilevector = 64+33;
136 	mach_reset = coldfire_reset;
137 
138 #ifdef CONFIG_BDM_DISABLE
139 	/*
140 	 * Disable the BDM clocking.  This also turns off most of the rest of
141 	 * the BDM device.  This is good for EMC reasons. This option is not
142 	 * incompatible with the memory protection option.
143 	 */
144 	wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
145 #endif
146 }
147 
148 /***************************************************************************/
149 
init_BSP(void)150 static int __init init_BSP(void)
151 {
152 	m532x_uarts_init();
153 	platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
154 	return 0;
155 }
156 
157 arch_initcall(init_BSP);
158 
159 /***************************************************************************/
160 /* Board initialization */
161 /***************************************************************************/
162 /*
163  * PLL min/max specifications
164  */
165 #define MAX_FVCO	500000	/* KHz */
166 #define MAX_FSYS	80000 	/* KHz */
167 #define MIN_FSYS	58333 	/* KHz */
168 #define FREF		16000   /* KHz */
169 
170 
171 #define MAX_MFD		135     /* Multiplier */
172 #define MIN_MFD		88      /* Multiplier */
173 #define BUSDIV		6       /* Divider */
174 
175 /*
176  * Low Power Divider specifications
177  */
178 #define MIN_LPD		(1 << 0)    /* Divider (not encoded) */
179 #define MAX_LPD		(1 << 15)   /* Divider (not encoded) */
180 #define DEFAULT_LPD	(1 << 1)	/* Divider (not encoded) */
181 
182 #define SYS_CLK_KHZ	80000
183 #define SYSTEM_PERIOD	12.5
184 /*
185  *  SDRAM Timing Parameters
186  */
187 #define SDRAM_BL	8	/* # of beats in a burst */
188 #define SDRAM_TWR	2	/* in clocks */
189 #define SDRAM_CASL	2.5	/* CASL in clocks */
190 #define SDRAM_TRCD	2	/* in clocks */
191 #define SDRAM_TRP	2	/* in clocks */
192 #define SDRAM_TRFC	7	/* in clocks */
193 #define SDRAM_TREFI	7800	/* in ns */
194 
195 #define EXT_SRAM_ADDRESS	(0xC0000000)
196 #define FLASH_ADDRESS		(0x00000000)
197 #define SDRAM_ADDRESS		(0x40000000)
198 
199 #define NAND_FLASH_ADDRESS	(0xD0000000)
200 
201 int sys_clk_khz = 0;
202 int sys_clk_mhz = 0;
203 
204 void wtm_init(void);
205 void scm_init(void);
206 void gpio_init(void);
207 void fbcs_init(void);
208 void sdramc_init(void);
209 int  clock_pll (int fsys, int flags);
210 int  clock_limp (int);
211 int  clock_exit_limp (void);
212 int  get_sys_clock (void);
213 
sysinit(void)214 asmlinkage void __init sysinit(void)
215 {
216 	sys_clk_khz = clock_pll(0, 0);
217 	sys_clk_mhz = sys_clk_khz/1000;
218 
219 	wtm_init();
220 	scm_init();
221 	gpio_init();
222 	fbcs_init();
223 	sdramc_init();
224 }
225 
wtm_init(void)226 void wtm_init(void)
227 {
228 	/* Disable watchdog timer */
229 	MCF_WTM_WCR = 0;
230 }
231 
232 #define MCF_SCM_BCR_GBW		(0x00000100)
233 #define MCF_SCM_BCR_GBR		(0x00000200)
234 
scm_init(void)235 void scm_init(void)
236 {
237 	/* All masters are trusted */
238 	MCF_SCM_MPR = 0x77777777;
239 
240 	/* Allow supervisor/user, read/write, and trusted/untrusted
241 	   access to all slaves */
242 	MCF_SCM_PACRA = 0;
243 	MCF_SCM_PACRB = 0;
244 	MCF_SCM_PACRC = 0;
245 	MCF_SCM_PACRD = 0;
246 	MCF_SCM_PACRE = 0;
247 	MCF_SCM_PACRF = 0;
248 
249 	/* Enable bursts */
250 	MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
251 }
252 
253 
fbcs_init(void)254 void fbcs_init(void)
255 {
256 	MCF_GPIO_PAR_CS = 0x0000003E;
257 
258 	/* Latch chip select */
259 	MCF_FBCS1_CSAR = 0x10080000;
260 
261 	MCF_FBCS1_CSCR = 0x002A3780;
262 	MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
263 
264 	/* Initialize latch to drive signals to inactive states */
265 	*((u16 *)(0x10080000)) = 0xFFFF;
266 
267 	/* External SRAM */
268 	MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
269 	MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
270 			| MCF_FBCS_CSCR_AA
271 			| MCF_FBCS_CSCR_SBM
272 			| MCF_FBCS_CSCR_WS(1));
273 	MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
274 			| MCF_FBCS_CSMR_V);
275 
276 	/* Boot Flash connected to FBCS0 */
277 	MCF_FBCS0_CSAR = FLASH_ADDRESS;
278 	MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
279 			| MCF_FBCS_CSCR_BEM
280 			| MCF_FBCS_CSCR_AA
281 			| MCF_FBCS_CSCR_SBM
282 			| MCF_FBCS_CSCR_WS(7));
283 	MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
284 			| MCF_FBCS_CSMR_V);
285 }
286 
sdramc_init(void)287 void sdramc_init(void)
288 {
289 	/*
290 	 * Check to see if the SDRAM has already been initialized
291 	 * by a run control tool
292 	 */
293 	if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
294 		/* SDRAM chip select initialization */
295 
296 		/* Initialize SDRAM chip select */
297 		MCF_SDRAMC_SDCS0 = (0
298 			| MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
299 			| MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
300 
301 	/*
302 	 * Basic configuration and initialization
303 	 */
304 	MCF_SDRAMC_SDCFG1 = (0
305 		| MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
306 		| MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
307 		| MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
308 		| MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
309 		| MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
310 		| MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
311 		| MCF_SDRAMC_SDCFG1_WTLAT(3));
312 	MCF_SDRAMC_SDCFG2 = (0
313 		| MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
314 		| MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
315 		| MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
316 		| MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
317 
318 
319 	/*
320 	 * Precharge and enable write to SDMR
321 	 */
322         MCF_SDRAMC_SDCR = (0
323 		| MCF_SDRAMC_SDCR_MODE_EN
324 		| MCF_SDRAMC_SDCR_CKE
325 		| MCF_SDRAMC_SDCR_DDR
326 		| MCF_SDRAMC_SDCR_MUX(1)
327 		| MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
328 		| MCF_SDRAMC_SDCR_PS_16
329 		| MCF_SDRAMC_SDCR_IPALL);
330 
331 	/*
332 	 * Write extended mode register
333 	 */
334 	MCF_SDRAMC_SDMR = (0
335 		| MCF_SDRAMC_SDMR_BNKAD_LEMR
336 		| MCF_SDRAMC_SDMR_AD(0x0)
337 		| MCF_SDRAMC_SDMR_CMD);
338 
339 	/*
340 	 * Write mode register and reset DLL
341 	 */
342 	MCF_SDRAMC_SDMR = (0
343 		| MCF_SDRAMC_SDMR_BNKAD_LMR
344 		| MCF_SDRAMC_SDMR_AD(0x163)
345 		| MCF_SDRAMC_SDMR_CMD);
346 
347 	/*
348 	 * Execute a PALL command
349 	 */
350 	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
351 
352 	/*
353 	 * Perform two REF cycles
354 	 */
355 	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
356 	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
357 
358 	/*
359 	 * Write mode register and clear reset DLL
360 	 */
361 	MCF_SDRAMC_SDMR = (0
362 		| MCF_SDRAMC_SDMR_BNKAD_LMR
363 		| MCF_SDRAMC_SDMR_AD(0x063)
364 		| MCF_SDRAMC_SDMR_CMD);
365 
366 	/*
367 	 * Enable auto refresh and lock SDMR
368 	 */
369 	MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
370 	MCF_SDRAMC_SDCR |= (0
371 		| MCF_SDRAMC_SDCR_REF
372 		| MCF_SDRAMC_SDCR_DQS_OE(0xC));
373 	}
374 }
375 
gpio_init(void)376 void gpio_init(void)
377 {
378 	/* Enable UART0 pins */
379 	MCF_GPIO_PAR_UART = ( 0
380 		| MCF_GPIO_PAR_UART_PAR_URXD0
381 		| MCF_GPIO_PAR_UART_PAR_UTXD0);
382 
383 	/* Initialize TIN3 as a GPIO output to enable the write
384 	   half of the latch */
385 	MCF_GPIO_PAR_TIMER = 0x00;
386 	MCF_GPIO_PDDR_TIMER = 0x08;
387 	MCF_GPIO_PCLRR_TIMER = 0x0;
388 
389 }
390 
clock_pll(int fsys,int flags)391 int clock_pll(int fsys, int flags)
392 {
393 	int fref, temp, fout, mfd;
394 	u32 i;
395 
396 	fref = FREF;
397 
398 	if (fsys == 0) {
399 		/* Return current PLL output */
400 		mfd = MCF_PLL_PFDR;
401 
402 		return (fref * mfd / (BUSDIV * 4));
403 	}
404 
405 	/* Check bounds of requested system clock */
406 	if (fsys > MAX_FSYS)
407 		fsys = MAX_FSYS;
408 	if (fsys < MIN_FSYS)
409 		fsys = MIN_FSYS;
410 
411 	/* Multiplying by 100 when calculating the temp value,
412 	   and then dividing by 100 to calculate the mfd allows
413 	   for exact values without needing to include floating
414 	   point libraries. */
415 	temp = 100 * fsys / fref;
416 	mfd = 4 * BUSDIV * temp / 100;
417 
418 	/* Determine the output frequency for selected values */
419 	fout = (fref * mfd / (BUSDIV * 4));
420 
421 	/*
422 	 * Check to see if the SDRAM has already been initialized.
423 	 * If it has then the SDRAM needs to be put into self refresh
424 	 * mode before reprogramming the PLL.
425 	 */
426 	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
427 		/* Put SDRAM into self refresh mode */
428 		MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
429 
430 	/*
431 	 * Initialize the PLL to generate the new system clock frequency.
432 	 * The device must be put into LIMP mode to reprogram the PLL.
433 	 */
434 
435 	/* Enter LIMP mode */
436 	clock_limp(DEFAULT_LPD);
437 
438 	/* Reprogram PLL for desired fsys */
439 	MCF_PLL_PODR = (0
440 		| MCF_PLL_PODR_CPUDIV(BUSDIV/3)
441 		| MCF_PLL_PODR_BUSDIV(BUSDIV));
442 
443 	MCF_PLL_PFDR = mfd;
444 
445 	/* Exit LIMP mode */
446 	clock_exit_limp();
447 
448 	/*
449 	 * Return the SDRAM to normal operation if it is in use.
450 	 */
451 	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
452 		/* Exit self refresh mode */
453 		MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
454 
455 	/* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
456 	MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
457 
458 	/* wait for DQS logic to relock */
459 	for (i = 0; i < 0x200; i++)
460 		;
461 
462 	return fout;
463 }
464 
clock_limp(int div)465 int clock_limp(int div)
466 {
467 	u32 temp;
468 
469 	/* Check bounds of divider */
470 	if (div < MIN_LPD)
471 		div = MIN_LPD;
472 	if (div > MAX_LPD)
473 		div = MAX_LPD;
474 
475 	/* Save of the current value of the SSIDIV so we don't
476 	   overwrite the value*/
477 	temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
478 
479 	/* Apply the divider to the system clock */
480 	MCF_CCM_CDR = ( 0
481 		| MCF_CCM_CDR_LPDIV(div)
482 		| MCF_CCM_CDR_SSIDIV(temp));
483 
484 	MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
485 
486 	return (FREF/(3*(1 << div)));
487 }
488 
clock_exit_limp(void)489 int clock_exit_limp(void)
490 {
491 	int fout;
492 
493 	/* Exit LIMP mode */
494 	MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
495 
496 	/* Wait for PLL to lock */
497 	while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
498 		;
499 
500 	fout = get_sys_clock();
501 
502 	return fout;
503 }
504 
get_sys_clock(void)505 int get_sys_clock(void)
506 {
507 	int divider;
508 
509 	/* Test to see if device is in LIMP mode */
510 	if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
511 		divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
512 		return (FREF/(2 << divider));
513 	}
514 	else
515 		return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
516 }
517