m68knommu: move ColdFire timers.c to its own coldfire directory
[wrt350n-kernel.git] / arch / m68knommu / platform / 532x / config.c
blob758bc7a9af966362d03b9c8d93278feb71e1a564
1 /***************************************************************************/
3 /*
4 * linux/arch/m68knommu/platform/532x/config.c
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>
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.
18 /***************************************************************************/
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>
32 /***************************************************************************/
34 void coldfire_reset(void);
36 extern unsigned int mcf_timervector;
37 extern unsigned int mcf_profilevector;
38 extern unsigned int mcf_timerlevel;
40 /***************************************************************************/
42 static struct mcf_platform_uart m532x_uart_platform[] = {
44 .mapbase = MCF_MBAR + MCFUART_BASE1,
45 .irq = MCFINT_VECBASE + MCFINT_UART0,
48 .mapbase = MCF_MBAR + MCFUART_BASE2,
49 .irq = MCFINT_VECBASE + MCFINT_UART1,
52 .mapbase = MCF_MBAR + MCFUART_BASE3,
53 .irq = MCFINT_VECBASE + MCFINT_UART2,
55 { },
58 static struct platform_device m532x_uart = {
59 .name = "mcfuart",
60 .id = 0,
61 .dev.platform_data = m532x_uart_platform,
64 static struct platform_device *m532x_devices[] __initdata = {
65 &m532x_uart,
68 /***************************************************************************/
70 static void __init m532x_uart_init_line(int line, int irq)
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;
88 static void __init m532x_uarts_init(void)
90 const int nrlines = ARRAY_SIZE(m532x_uart_platform);
91 int line;
93 for (line = 0; (line < nrlines); line++)
94 m532x_uart_init_line(line, m532x_uart_platform[line].irq);
97 /***************************************************************************/
99 void mcf_settimericr(unsigned int timer, unsigned int level)
101 volatile unsigned char *icrp;
102 unsigned int icr;
103 unsigned char irq;
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;
111 icrp = (volatile unsigned char *) (MCF_MBAR + icr);
112 *icrp = level;
113 mcf_enable_irq0(irq);
117 /***************************************************************************/
119 int mcf_timerirqpending(int timer)
121 unsigned int imr = 0;
123 switch (timer) {
124 case 1: imr = 0x1; break;
125 case 2: imr = 0x2; break;
126 default: break;
128 return (mcf_getiprh() & imr);
131 /***************************************************************************/
133 void __init config_BSP(char *commandp, int size)
135 mcf_setimr(MCFSIM_IMR_MASKALL);
137 #if !defined(CONFIG_BOOTPARAM)
138 /* Copy command line from FLASH to local buffer... */
139 memcpy(commandp, (char *) 0x4000, 4);
140 if(strncmp(commandp, "kcl ", 4) == 0){
141 memcpy(commandp, (char *) 0x4004, size);
142 commandp[size-1] = 0;
143 } else {
144 memset(commandp, 0, size);
146 #endif
148 mcf_timervector = 64+32;
149 mcf_profilevector = 64+33;
150 mach_reset = coldfire_reset;
152 #ifdef CONFIG_BDM_DISABLE
154 * Disable the BDM clocking. This also turns off most of the rest of
155 * the BDM device. This is good for EMC reasons. This option is not
156 * incompatible with the memory protection option.
158 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
159 #endif
162 /***************************************************************************/
164 static int __init init_BSP(void)
166 m532x_uarts_init();
167 platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
168 return 0;
171 arch_initcall(init_BSP);
173 /***************************************************************************/
174 /* Board initialization */
175 /***************************************************************************/
177 * PLL min/max specifications
179 #define MAX_FVCO 500000 /* KHz */
180 #define MAX_FSYS 80000 /* KHz */
181 #define MIN_FSYS 58333 /* KHz */
182 #define FREF 16000 /* KHz */
185 #define MAX_MFD 135 /* Multiplier */
186 #define MIN_MFD 88 /* Multiplier */
187 #define BUSDIV 6 /* Divider */
190 * Low Power Divider specifications
192 #define MIN_LPD (1 << 0) /* Divider (not encoded) */
193 #define MAX_LPD (1 << 15) /* Divider (not encoded) */
194 #define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
196 #define SYS_CLK_KHZ 80000
197 #define SYSTEM_PERIOD 12.5
199 * SDRAM Timing Parameters
201 #define SDRAM_BL 8 /* # of beats in a burst */
202 #define SDRAM_TWR 2 /* in clocks */
203 #define SDRAM_CASL 2.5 /* CASL in clocks */
204 #define SDRAM_TRCD 2 /* in clocks */
205 #define SDRAM_TRP 2 /* in clocks */
206 #define SDRAM_TRFC 7 /* in clocks */
207 #define SDRAM_TREFI 7800 /* in ns */
209 #define EXT_SRAM_ADDRESS (0xC0000000)
210 #define FLASH_ADDRESS (0x00000000)
211 #define SDRAM_ADDRESS (0x40000000)
213 #define NAND_FLASH_ADDRESS (0xD0000000)
215 int sys_clk_khz = 0;
216 int sys_clk_mhz = 0;
218 void wtm_init(void);
219 void scm_init(void);
220 void gpio_init(void);
221 void fbcs_init(void);
222 void sdramc_init(void);
223 int clock_pll (int fsys, int flags);
224 int clock_limp (int);
225 int clock_exit_limp (void);
226 int get_sys_clock (void);
228 asmlinkage void __init sysinit(void)
230 sys_clk_khz = clock_pll(0, 0);
231 sys_clk_mhz = sys_clk_khz/1000;
233 wtm_init();
234 scm_init();
235 gpio_init();
236 fbcs_init();
237 sdramc_init();
240 void wtm_init(void)
242 /* Disable watchdog timer */
243 MCF_WTM_WCR = 0;
246 #define MCF_SCM_BCR_GBW (0x00000100)
247 #define MCF_SCM_BCR_GBR (0x00000200)
249 void scm_init(void)
251 /* All masters are trusted */
252 MCF_SCM_MPR = 0x77777777;
254 /* Allow supervisor/user, read/write, and trusted/untrusted
255 access to all slaves */
256 MCF_SCM_PACRA = 0;
257 MCF_SCM_PACRB = 0;
258 MCF_SCM_PACRC = 0;
259 MCF_SCM_PACRD = 0;
260 MCF_SCM_PACRE = 0;
261 MCF_SCM_PACRF = 0;
263 /* Enable bursts */
264 MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
268 void fbcs_init(void)
270 MCF_GPIO_PAR_CS = 0x0000003E;
272 /* Latch chip select */
273 MCF_FBCS1_CSAR = 0x10080000;
275 MCF_FBCS1_CSCR = 0x002A3780;
276 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
278 /* Initialize latch to drive signals to inactive states */
279 *((u16 *)(0x10080000)) = 0xFFFF;
281 /* External SRAM */
282 MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
283 MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
284 | MCF_FBCS_CSCR_AA
285 | MCF_FBCS_CSCR_SBM
286 | MCF_FBCS_CSCR_WS(1));
287 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
288 | MCF_FBCS_CSMR_V);
290 /* Boot Flash connected to FBCS0 */
291 MCF_FBCS0_CSAR = FLASH_ADDRESS;
292 MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
293 | MCF_FBCS_CSCR_BEM
294 | MCF_FBCS_CSCR_AA
295 | MCF_FBCS_CSCR_SBM
296 | MCF_FBCS_CSCR_WS(7));
297 MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
298 | MCF_FBCS_CSMR_V);
301 void sdramc_init(void)
304 * Check to see if the SDRAM has already been initialized
305 * by a run control tool
307 if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
308 /* SDRAM chip select initialization */
310 /* Initialize SDRAM chip select */
311 MCF_SDRAMC_SDCS0 = (0
312 | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
313 | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
316 * Basic configuration and initialization
318 MCF_SDRAMC_SDCFG1 = (0
319 | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
320 | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
321 | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
322 | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
323 | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
324 | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
325 | MCF_SDRAMC_SDCFG1_WTLAT(3));
326 MCF_SDRAMC_SDCFG2 = (0
327 | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
328 | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
329 | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
330 | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
334 * Precharge and enable write to SDMR
336 MCF_SDRAMC_SDCR = (0
337 | MCF_SDRAMC_SDCR_MODE_EN
338 | MCF_SDRAMC_SDCR_CKE
339 | MCF_SDRAMC_SDCR_DDR
340 | MCF_SDRAMC_SDCR_MUX(1)
341 | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
342 | MCF_SDRAMC_SDCR_PS_16
343 | MCF_SDRAMC_SDCR_IPALL);
346 * Write extended mode register
348 MCF_SDRAMC_SDMR = (0
349 | MCF_SDRAMC_SDMR_BNKAD_LEMR
350 | MCF_SDRAMC_SDMR_AD(0x0)
351 | MCF_SDRAMC_SDMR_CMD);
354 * Write mode register and reset DLL
356 MCF_SDRAMC_SDMR = (0
357 | MCF_SDRAMC_SDMR_BNKAD_LMR
358 | MCF_SDRAMC_SDMR_AD(0x163)
359 | MCF_SDRAMC_SDMR_CMD);
362 * Execute a PALL command
364 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
367 * Perform two REF cycles
369 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
370 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
373 * Write mode register and clear reset DLL
375 MCF_SDRAMC_SDMR = (0
376 | MCF_SDRAMC_SDMR_BNKAD_LMR
377 | MCF_SDRAMC_SDMR_AD(0x063)
378 | MCF_SDRAMC_SDMR_CMD);
381 * Enable auto refresh and lock SDMR
383 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
384 MCF_SDRAMC_SDCR |= (0
385 | MCF_SDRAMC_SDCR_REF
386 | MCF_SDRAMC_SDCR_DQS_OE(0xC));
390 void gpio_init(void)
392 /* Enable UART0 pins */
393 MCF_GPIO_PAR_UART = ( 0
394 | MCF_GPIO_PAR_UART_PAR_URXD0
395 | MCF_GPIO_PAR_UART_PAR_UTXD0);
397 /* Initialize TIN3 as a GPIO output to enable the write
398 half of the latch */
399 MCF_GPIO_PAR_TIMER = 0x00;
400 MCF_GPIO_PDDR_TIMER = 0x08;
401 MCF_GPIO_PCLRR_TIMER = 0x0;
405 int clock_pll(int fsys, int flags)
407 int fref, temp, fout, mfd;
408 u32 i;
410 fref = FREF;
412 if (fsys == 0) {
413 /* Return current PLL output */
414 mfd = MCF_PLL_PFDR;
416 return (fref * mfd / (BUSDIV * 4));
419 /* Check bounds of requested system clock */
420 if (fsys > MAX_FSYS)
421 fsys = MAX_FSYS;
422 if (fsys < MIN_FSYS)
423 fsys = MIN_FSYS;
425 /* Multiplying by 100 when calculating the temp value,
426 and then dividing by 100 to calculate the mfd allows
427 for exact values without needing to include floating
428 point libraries. */
429 temp = 100 * fsys / fref;
430 mfd = 4 * BUSDIV * temp / 100;
432 /* Determine the output frequency for selected values */
433 fout = (fref * mfd / (BUSDIV * 4));
436 * Check to see if the SDRAM has already been initialized.
437 * If it has then the SDRAM needs to be put into self refresh
438 * mode before reprogramming the PLL.
440 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
441 /* Put SDRAM into self refresh mode */
442 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
445 * Initialize the PLL to generate the new system clock frequency.
446 * The device must be put into LIMP mode to reprogram the PLL.
449 /* Enter LIMP mode */
450 clock_limp(DEFAULT_LPD);
452 /* Reprogram PLL for desired fsys */
453 MCF_PLL_PODR = (0
454 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
455 | MCF_PLL_PODR_BUSDIV(BUSDIV));
457 MCF_PLL_PFDR = mfd;
459 /* Exit LIMP mode */
460 clock_exit_limp();
463 * Return the SDRAM to normal operation if it is in use.
465 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
466 /* Exit self refresh mode */
467 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
469 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
470 MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
472 /* wait for DQS logic to relock */
473 for (i = 0; i < 0x200; i++)
476 return fout;
479 int clock_limp(int div)
481 u32 temp;
483 /* Check bounds of divider */
484 if (div < MIN_LPD)
485 div = MIN_LPD;
486 if (div > MAX_LPD)
487 div = MAX_LPD;
489 /* Save of the current value of the SSIDIV so we don't
490 overwrite the value*/
491 temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
493 /* Apply the divider to the system clock */
494 MCF_CCM_CDR = ( 0
495 | MCF_CCM_CDR_LPDIV(div)
496 | MCF_CCM_CDR_SSIDIV(temp));
498 MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
500 return (FREF/(3*(1 << div)));
503 int clock_exit_limp(void)
505 int fout;
507 /* Exit LIMP mode */
508 MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
510 /* Wait for PLL to lock */
511 while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
514 fout = get_sys_clock();
516 return fout;
519 int get_sys_clock(void)
521 int divider;
523 /* Test to see if device is in LIMP mode */
524 if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
525 divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
526 return (FREF/(2 << divider));
528 else
529 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));