allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / arch / m68knommu / platform / 532x / config.c
blob664c3a12b0c128a6f927c82fc2ab2731add26f8d
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/sched.h>
22 #include <linux/param.h>
23 #include <linux/init.h>
24 #include <linux/interrupt.h>
25 #include <asm/irq.h>
26 #include <asm/dma.h>
27 #include <asm/traps.h>
28 #include <asm/machdep.h>
29 #include <asm/coldfire.h>
30 #include <asm/mcftimer.h>
31 #include <asm/mcfsim.h>
32 #include <asm/mcfdma.h>
33 #include <asm/mcfwdebug.h>
35 /***************************************************************************/
37 void coldfire_tick(void);
38 void coldfire_timer_init(irq_handler_t handler);
39 unsigned long coldfire_timer_offset(void);
40 void coldfire_trap_init(void);
41 void coldfire_reset(void);
43 extern unsigned int mcf_timervector;
44 extern unsigned int mcf_profilevector;
45 extern unsigned int mcf_timerlevel;
47 /***************************************************************************/
50 * DMA channel base address table.
52 unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { };
53 unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
55 /***************************************************************************/
57 void mcf_settimericr(unsigned int timer, unsigned int level)
59 volatile unsigned char *icrp;
60 unsigned int icr;
61 unsigned char irq;
63 if (timer <= 2) {
64 switch (timer) {
65 case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break;
66 default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
69 icrp = (volatile unsigned char *) (MCF_MBAR + icr);
70 *icrp = level;
71 mcf_enable_irq0(irq);
75 /***************************************************************************/
77 int mcf_timerirqpending(int timer)
79 unsigned int imr = 0;
81 switch (timer) {
82 case 1: imr = 0x1; break;
83 case 2: imr = 0x2; break;
84 default: break;
86 return (mcf_getiprh() & imr);
89 /***************************************************************************/
91 void config_BSP(char *commandp, int size)
93 mcf_setimr(MCFSIM_IMR_MASKALL);
95 #if defined(CONFIG_BOOTPARAM)
96 strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
97 commandp[size-1] = 0;
98 #else
99 /* Copy command line from FLASH to local buffer... */
100 memcpy(commandp, (char *) 0x4000, 4);
101 if(strncmp(commandp, "kcl ", 4) == 0){
102 memcpy(commandp, (char *) 0x4004, size);
103 commandp[size-1] = 0;
104 } else {
105 memset(commandp, 0, size);
107 #endif
109 mcf_timervector = 64+32;
110 mcf_profilevector = 64+33;
111 mach_sched_init = coldfire_timer_init;
112 mach_tick = coldfire_tick;
113 mach_gettimeoffset = coldfire_timer_offset;
114 mach_trap_init = coldfire_trap_init;
115 mach_reset = coldfire_reset;
117 #ifdef MCF_BDM_DISABLE
119 * Disable the BDM clocking. This also turns off most of the rest of
120 * the BDM device. This is good for EMC reasons. This option is not
121 * incompatible with the memory protection option.
123 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
124 #endif
127 /***************************************************************************/
128 /* Board initialization */
130 /********************************************************************/
132 * PLL min/max specifications
134 #define MAX_FVCO 500000 /* KHz */
135 #define MAX_FSYS 80000 /* KHz */
136 #define MIN_FSYS 58333 /* KHz */
137 #define FREF 16000 /* KHz */
140 #define MAX_MFD 135 /* Multiplier */
141 #define MIN_MFD 88 /* Multiplier */
142 #define BUSDIV 6 /* Divider */
145 * Low Power Divider specifications
147 #define MIN_LPD (1 << 0) /* Divider (not encoded) */
148 #define MAX_LPD (1 << 15) /* Divider (not encoded) */
149 #define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
151 #define SYS_CLK_KHZ 80000
152 #define SYSTEM_PERIOD 12.5
154 * SDRAM Timing Parameters
156 #define SDRAM_BL 8 /* # of beats in a burst */
157 #define SDRAM_TWR 2 /* in clocks */
158 #define SDRAM_CASL 2.5 /* CASL in clocks */
159 #define SDRAM_TRCD 2 /* in clocks */
160 #define SDRAM_TRP 2 /* in clocks */
161 #define SDRAM_TRFC 7 /* in clocks */
162 #define SDRAM_TREFI 7800 /* in ns */
164 #define EXT_SRAM_ADDRESS (0xC0000000)
165 #define FLASH_ADDRESS (0x00000000)
166 #define SDRAM_ADDRESS (0x40000000)
168 #define NAND_FLASH_ADDRESS (0xD0000000)
170 int sys_clk_khz = 0;
171 int sys_clk_mhz = 0;
173 void wtm_init(void);
174 void scm_init(void);
175 void gpio_init(void);
176 void fbcs_init(void);
177 void sdramc_init(void);
178 int clock_pll (int fsys, int flags);
179 int clock_limp (int);
180 int clock_exit_limp (void);
181 int get_sys_clock (void);
183 asmlinkage void __init sysinit(void)
185 sys_clk_khz = clock_pll(0, 0);
186 sys_clk_mhz = sys_clk_khz/1000;
188 wtm_init();
189 scm_init();
190 gpio_init();
191 fbcs_init();
192 sdramc_init();
195 void wtm_init(void)
197 /* Disable watchdog timer */
198 MCF_WTM_WCR = 0;
201 #define MCF_SCM_BCR_GBW (0x00000100)
202 #define MCF_SCM_BCR_GBR (0x00000200)
204 void scm_init(void)
206 /* All masters are trusted */
207 MCF_SCM_MPR = 0x77777777;
209 /* Allow supervisor/user, read/write, and trusted/untrusted
210 access to all slaves */
211 MCF_SCM_PACRA = 0;
212 MCF_SCM_PACRB = 0;
213 MCF_SCM_PACRC = 0;
214 MCF_SCM_PACRD = 0;
215 MCF_SCM_PACRE = 0;
216 MCF_SCM_PACRF = 0;
218 /* Enable bursts */
219 MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
223 void fbcs_init(void)
225 MCF_GPIO_PAR_CS = 0x0000003E;
227 /* Latch chip select */
228 MCF_FBCS1_CSAR = 0x10080000;
230 MCF_FBCS1_CSCR = 0x002A3780;
231 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
233 /* Initialize latch to drive signals to inactive states */
234 *((u16 *)(0x10080000)) = 0xFFFF;
236 /* External SRAM */
237 MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
238 MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
239 | MCF_FBCS_CSCR_AA
240 | MCF_FBCS_CSCR_SBM
241 | MCF_FBCS_CSCR_WS(1));
242 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
243 | MCF_FBCS_CSMR_V);
245 /* Boot Flash connected to FBCS0 */
246 MCF_FBCS0_CSAR = FLASH_ADDRESS;
247 MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
248 | MCF_FBCS_CSCR_BEM
249 | MCF_FBCS_CSCR_AA
250 | MCF_FBCS_CSCR_SBM
251 | MCF_FBCS_CSCR_WS(7));
252 MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
253 | MCF_FBCS_CSMR_V);
256 void sdramc_init(void)
259 * Check to see if the SDRAM has already been initialized
260 * by a run control tool
262 if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
263 /* SDRAM chip select initialization */
265 /* Initialize SDRAM chip select */
266 MCF_SDRAMC_SDCS0 = (0
267 | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
268 | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
271 * Basic configuration and initialization
273 MCF_SDRAMC_SDCFG1 = (0
274 | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
275 | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
276 | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
277 | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
278 | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
279 | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
280 | MCF_SDRAMC_SDCFG1_WTLAT(3));
281 MCF_SDRAMC_SDCFG2 = (0
282 | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
283 | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
284 | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
285 | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
289 * Precharge and enable write to SDMR
291 MCF_SDRAMC_SDCR = (0
292 | MCF_SDRAMC_SDCR_MODE_EN
293 | MCF_SDRAMC_SDCR_CKE
294 | MCF_SDRAMC_SDCR_DDR
295 | MCF_SDRAMC_SDCR_MUX(1)
296 | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
297 | MCF_SDRAMC_SDCR_PS_16
298 | MCF_SDRAMC_SDCR_IPALL);
301 * Write extended mode register
303 MCF_SDRAMC_SDMR = (0
304 | MCF_SDRAMC_SDMR_BNKAD_LEMR
305 | MCF_SDRAMC_SDMR_AD(0x0)
306 | MCF_SDRAMC_SDMR_CMD);
309 * Write mode register and reset DLL
311 MCF_SDRAMC_SDMR = (0
312 | MCF_SDRAMC_SDMR_BNKAD_LMR
313 | MCF_SDRAMC_SDMR_AD(0x163)
314 | MCF_SDRAMC_SDMR_CMD);
317 * Execute a PALL command
319 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
322 * Perform two REF cycles
324 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
325 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
328 * Write mode register and clear reset DLL
330 MCF_SDRAMC_SDMR = (0
331 | MCF_SDRAMC_SDMR_BNKAD_LMR
332 | MCF_SDRAMC_SDMR_AD(0x063)
333 | MCF_SDRAMC_SDMR_CMD);
336 * Enable auto refresh and lock SDMR
338 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
339 MCF_SDRAMC_SDCR |= (0
340 | MCF_SDRAMC_SDCR_REF
341 | MCF_SDRAMC_SDCR_DQS_OE(0xC));
345 void gpio_init(void)
347 /* Enable UART0 pins */
348 MCF_GPIO_PAR_UART = ( 0
349 | MCF_GPIO_PAR_UART_PAR_URXD0
350 | MCF_GPIO_PAR_UART_PAR_UTXD0);
352 /* Initialize TIN3 as a GPIO output to enable the write
353 half of the latch */
354 MCF_GPIO_PAR_TIMER = 0x00;
355 MCF_GPIO_PDDR_TIMER = 0x08;
356 MCF_GPIO_PCLRR_TIMER = 0x0;
360 int clock_pll(int fsys, int flags)
362 int fref, temp, fout, mfd;
363 u32 i;
365 fref = FREF;
367 if (fsys == 0) {
368 /* Return current PLL output */
369 mfd = MCF_PLL_PFDR;
371 return (fref * mfd / (BUSDIV * 4));
374 /* Check bounds of requested system clock */
375 if (fsys > MAX_FSYS)
376 fsys = MAX_FSYS;
377 if (fsys < MIN_FSYS)
378 fsys = MIN_FSYS;
380 /* Multiplying by 100 when calculating the temp value,
381 and then dividing by 100 to calculate the mfd allows
382 for exact values without needing to include floating
383 point libraries. */
384 temp = 100 * fsys / fref;
385 mfd = 4 * BUSDIV * temp / 100;
387 /* Determine the output frequency for selected values */
388 fout = (fref * mfd / (BUSDIV * 4));
391 * Check to see if the SDRAM has already been initialized.
392 * If it has then the SDRAM needs to be put into self refresh
393 * mode before reprogramming the PLL.
395 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
396 /* Put SDRAM into self refresh mode */
397 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
400 * Initialize the PLL to generate the new system clock frequency.
401 * The device must be put into LIMP mode to reprogram the PLL.
404 /* Enter LIMP mode */
405 clock_limp(DEFAULT_LPD);
407 /* Reprogram PLL for desired fsys */
408 MCF_PLL_PODR = (0
409 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
410 | MCF_PLL_PODR_BUSDIV(BUSDIV));
412 MCF_PLL_PFDR = mfd;
414 /* Exit LIMP mode */
415 clock_exit_limp();
418 * Return the SDRAM to normal operation if it is in use.
420 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
421 /* Exit self refresh mode */
422 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
424 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
425 MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
427 /* wait for DQS logic to relock */
428 for (i = 0; i < 0x200; i++)
431 return fout;
434 int clock_limp(int div)
436 u32 temp;
438 /* Check bounds of divider */
439 if (div < MIN_LPD)
440 div = MIN_LPD;
441 if (div > MAX_LPD)
442 div = MAX_LPD;
444 /* Save of the current value of the SSIDIV so we don't
445 overwrite the value*/
446 temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
448 /* Apply the divider to the system clock */
449 MCF_CCM_CDR = ( 0
450 | MCF_CCM_CDR_LPDIV(div)
451 | MCF_CCM_CDR_SSIDIV(temp));
453 MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
455 return (FREF/(3*(1 << div)));
458 int clock_exit_limp(void)
460 int fout;
462 /* Exit LIMP mode */
463 MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
465 /* Wait for PLL to lock */
466 while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
469 fout = get_sys_clock();
471 return fout;
474 int get_sys_clock(void)
476 int divider;
478 /* Test to see if device is in LIMP mode */
479 if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
480 divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
481 return (FREF/(2 << divider));
483 else
484 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));