m68knommu: remove use of colfire_trap_init
[linux-2.6.git] / arch / m68knommu / platform / 532x / config.c
blobb32c6425f8219ea0430de1a8ef3f23c506584648
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_reset(void);
42 extern unsigned int mcf_timervector;
43 extern unsigned int mcf_profilevector;
44 extern unsigned int mcf_timerlevel;
46 /***************************************************************************/
49 * DMA channel base address table.
51 unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { };
52 unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
54 /***************************************************************************/
56 void mcf_settimericr(unsigned int timer, unsigned int level)
58 volatile unsigned char *icrp;
59 unsigned int icr;
60 unsigned char irq;
62 if (timer <= 2) {
63 switch (timer) {
64 case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break;
65 default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
68 icrp = (volatile unsigned char *) (MCF_MBAR + icr);
69 *icrp = level;
70 mcf_enable_irq0(irq);
74 /***************************************************************************/
76 int mcf_timerirqpending(int timer)
78 unsigned int imr = 0;
80 switch (timer) {
81 case 1: imr = 0x1; break;
82 case 2: imr = 0x2; break;
83 default: break;
85 return (mcf_getiprh() & imr);
88 /***************************************************************************/
90 void config_BSP(char *commandp, int size)
92 mcf_setimr(MCFSIM_IMR_MASKALL);
94 #if !defined(CONFIG_BOOTPARAM)
95 /* Copy command line from FLASH to local buffer... */
96 memcpy(commandp, (char *) 0x4000, 4);
97 if(strncmp(commandp, "kcl ", 4) == 0){
98 memcpy(commandp, (char *) 0x4004, size);
99 commandp[size-1] = 0;
100 } else {
101 memset(commandp, 0, size);
103 #endif
105 mcf_timervector = 64+32;
106 mcf_profilevector = 64+33;
107 mach_sched_init = coldfire_timer_init;
108 mach_tick = coldfire_tick;
109 mach_gettimeoffset = coldfire_timer_offset;
110 mach_reset = coldfire_reset;
112 #ifdef MCF_BDM_DISABLE
114 * Disable the BDM clocking. This also turns off most of the rest of
115 * the BDM device. This is good for EMC reasons. This option is not
116 * incompatible with the memory protection option.
118 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
119 #endif
122 /***************************************************************************/
123 /* Board initialization */
125 /********************************************************************/
127 * PLL min/max specifications
129 #define MAX_FVCO 500000 /* KHz */
130 #define MAX_FSYS 80000 /* KHz */
131 #define MIN_FSYS 58333 /* KHz */
132 #define FREF 16000 /* KHz */
135 #define MAX_MFD 135 /* Multiplier */
136 #define MIN_MFD 88 /* Multiplier */
137 #define BUSDIV 6 /* Divider */
140 * Low Power Divider specifications
142 #define MIN_LPD (1 << 0) /* Divider (not encoded) */
143 #define MAX_LPD (1 << 15) /* Divider (not encoded) */
144 #define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
146 #define SYS_CLK_KHZ 80000
147 #define SYSTEM_PERIOD 12.5
149 * SDRAM Timing Parameters
151 #define SDRAM_BL 8 /* # of beats in a burst */
152 #define SDRAM_TWR 2 /* in clocks */
153 #define SDRAM_CASL 2.5 /* CASL in clocks */
154 #define SDRAM_TRCD 2 /* in clocks */
155 #define SDRAM_TRP 2 /* in clocks */
156 #define SDRAM_TRFC 7 /* in clocks */
157 #define SDRAM_TREFI 7800 /* in ns */
159 #define EXT_SRAM_ADDRESS (0xC0000000)
160 #define FLASH_ADDRESS (0x00000000)
161 #define SDRAM_ADDRESS (0x40000000)
163 #define NAND_FLASH_ADDRESS (0xD0000000)
165 int sys_clk_khz = 0;
166 int sys_clk_mhz = 0;
168 void wtm_init(void);
169 void scm_init(void);
170 void gpio_init(void);
171 void fbcs_init(void);
172 void sdramc_init(void);
173 int clock_pll (int fsys, int flags);
174 int clock_limp (int);
175 int clock_exit_limp (void);
176 int get_sys_clock (void);
178 asmlinkage void __init sysinit(void)
180 sys_clk_khz = clock_pll(0, 0);
181 sys_clk_mhz = sys_clk_khz/1000;
183 wtm_init();
184 scm_init();
185 gpio_init();
186 fbcs_init();
187 sdramc_init();
190 void wtm_init(void)
192 /* Disable watchdog timer */
193 MCF_WTM_WCR = 0;
196 #define MCF_SCM_BCR_GBW (0x00000100)
197 #define MCF_SCM_BCR_GBR (0x00000200)
199 void scm_init(void)
201 /* All masters are trusted */
202 MCF_SCM_MPR = 0x77777777;
204 /* Allow supervisor/user, read/write, and trusted/untrusted
205 access to all slaves */
206 MCF_SCM_PACRA = 0;
207 MCF_SCM_PACRB = 0;
208 MCF_SCM_PACRC = 0;
209 MCF_SCM_PACRD = 0;
210 MCF_SCM_PACRE = 0;
211 MCF_SCM_PACRF = 0;
213 /* Enable bursts */
214 MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
218 void fbcs_init(void)
220 MCF_GPIO_PAR_CS = 0x0000003E;
222 /* Latch chip select */
223 MCF_FBCS1_CSAR = 0x10080000;
225 MCF_FBCS1_CSCR = 0x002A3780;
226 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
228 /* Initialize latch to drive signals to inactive states */
229 *((u16 *)(0x10080000)) = 0xFFFF;
231 /* External SRAM */
232 MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
233 MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
234 | MCF_FBCS_CSCR_AA
235 | MCF_FBCS_CSCR_SBM
236 | MCF_FBCS_CSCR_WS(1));
237 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
238 | MCF_FBCS_CSMR_V);
240 /* Boot Flash connected to FBCS0 */
241 MCF_FBCS0_CSAR = FLASH_ADDRESS;
242 MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
243 | MCF_FBCS_CSCR_BEM
244 | MCF_FBCS_CSCR_AA
245 | MCF_FBCS_CSCR_SBM
246 | MCF_FBCS_CSCR_WS(7));
247 MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
248 | MCF_FBCS_CSMR_V);
251 void sdramc_init(void)
254 * Check to see if the SDRAM has already been initialized
255 * by a run control tool
257 if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
258 /* SDRAM chip select initialization */
260 /* Initialize SDRAM chip select */
261 MCF_SDRAMC_SDCS0 = (0
262 | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
263 | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
266 * Basic configuration and initialization
268 MCF_SDRAMC_SDCFG1 = (0
269 | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
270 | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
271 | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
272 | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
273 | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
274 | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
275 | MCF_SDRAMC_SDCFG1_WTLAT(3));
276 MCF_SDRAMC_SDCFG2 = (0
277 | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
278 | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
279 | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
280 | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
284 * Precharge and enable write to SDMR
286 MCF_SDRAMC_SDCR = (0
287 | MCF_SDRAMC_SDCR_MODE_EN
288 | MCF_SDRAMC_SDCR_CKE
289 | MCF_SDRAMC_SDCR_DDR
290 | MCF_SDRAMC_SDCR_MUX(1)
291 | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
292 | MCF_SDRAMC_SDCR_PS_16
293 | MCF_SDRAMC_SDCR_IPALL);
296 * Write extended mode register
298 MCF_SDRAMC_SDMR = (0
299 | MCF_SDRAMC_SDMR_BNKAD_LEMR
300 | MCF_SDRAMC_SDMR_AD(0x0)
301 | MCF_SDRAMC_SDMR_CMD);
304 * Write mode register and reset DLL
306 MCF_SDRAMC_SDMR = (0
307 | MCF_SDRAMC_SDMR_BNKAD_LMR
308 | MCF_SDRAMC_SDMR_AD(0x163)
309 | MCF_SDRAMC_SDMR_CMD);
312 * Execute a PALL command
314 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
317 * Perform two REF cycles
319 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
320 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
323 * Write mode register and clear reset DLL
325 MCF_SDRAMC_SDMR = (0
326 | MCF_SDRAMC_SDMR_BNKAD_LMR
327 | MCF_SDRAMC_SDMR_AD(0x063)
328 | MCF_SDRAMC_SDMR_CMD);
331 * Enable auto refresh and lock SDMR
333 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
334 MCF_SDRAMC_SDCR |= (0
335 | MCF_SDRAMC_SDCR_REF
336 | MCF_SDRAMC_SDCR_DQS_OE(0xC));
340 void gpio_init(void)
342 /* Enable UART0 pins */
343 MCF_GPIO_PAR_UART = ( 0
344 | MCF_GPIO_PAR_UART_PAR_URXD0
345 | MCF_GPIO_PAR_UART_PAR_UTXD0);
347 /* Initialize TIN3 as a GPIO output to enable the write
348 half of the latch */
349 MCF_GPIO_PAR_TIMER = 0x00;
350 MCF_GPIO_PDDR_TIMER = 0x08;
351 MCF_GPIO_PCLRR_TIMER = 0x0;
355 int clock_pll(int fsys, int flags)
357 int fref, temp, fout, mfd;
358 u32 i;
360 fref = FREF;
362 if (fsys == 0) {
363 /* Return current PLL output */
364 mfd = MCF_PLL_PFDR;
366 return (fref * mfd / (BUSDIV * 4));
369 /* Check bounds of requested system clock */
370 if (fsys > MAX_FSYS)
371 fsys = MAX_FSYS;
372 if (fsys < MIN_FSYS)
373 fsys = MIN_FSYS;
375 /* Multiplying by 100 when calculating the temp value,
376 and then dividing by 100 to calculate the mfd allows
377 for exact values without needing to include floating
378 point libraries. */
379 temp = 100 * fsys / fref;
380 mfd = 4 * BUSDIV * temp / 100;
382 /* Determine the output frequency for selected values */
383 fout = (fref * mfd / (BUSDIV * 4));
386 * Check to see if the SDRAM has already been initialized.
387 * If it has then the SDRAM needs to be put into self refresh
388 * mode before reprogramming the PLL.
390 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
391 /* Put SDRAM into self refresh mode */
392 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
395 * Initialize the PLL to generate the new system clock frequency.
396 * The device must be put into LIMP mode to reprogram the PLL.
399 /* Enter LIMP mode */
400 clock_limp(DEFAULT_LPD);
402 /* Reprogram PLL for desired fsys */
403 MCF_PLL_PODR = (0
404 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
405 | MCF_PLL_PODR_BUSDIV(BUSDIV));
407 MCF_PLL_PFDR = mfd;
409 /* Exit LIMP mode */
410 clock_exit_limp();
413 * Return the SDRAM to normal operation if it is in use.
415 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
416 /* Exit self refresh mode */
417 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
419 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
420 MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
422 /* wait for DQS logic to relock */
423 for (i = 0; i < 0x200; i++)
426 return fout;
429 int clock_limp(int div)
431 u32 temp;
433 /* Check bounds of divider */
434 if (div < MIN_LPD)
435 div = MIN_LPD;
436 if (div > MAX_LPD)
437 div = MAX_LPD;
439 /* Save of the current value of the SSIDIV so we don't
440 overwrite the value*/
441 temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
443 /* Apply the divider to the system clock */
444 MCF_CCM_CDR = ( 0
445 | MCF_CCM_CDR_LPDIV(div)
446 | MCF_CCM_CDR_SSIDIV(temp));
448 MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
450 return (FREF/(3*(1 << div)));
453 int clock_exit_limp(void)
455 int fout;
457 /* Exit LIMP mode */
458 MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
460 /* Wait for PLL to lock */
461 while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
464 fout = get_sys_clock();
466 return fout;
469 int get_sys_clock(void)
471 int divider;
473 /* Test to see if device is in LIMP mode */
474 if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
475 divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
476 return (FREF/(2 << divider));
478 else
479 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));