]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/m68knommu/platform/532x/config.c
m68knommu: platform setup for 532x ColdFire parts
[linux-2.6-omap-h63xx.git] / arch / m68knommu / platform / 532x / config.c
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        = MCF_MBAR + MCFUART_BASE1,
45                 .irq            = MCFINT_VECBASE + MCFINT_UART0,
46         },
47         {
48                 .mapbase        = MCF_MBAR + MCFUART_BASE2,
49                 .irq            = MCFINT_VECBASE + MCFINT_UART1,
50         },
51         {
52                 .mapbase        = MCF_MBAR + 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
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
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
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 *) (MCF_MBAR + icr);
112                 *icrp = level;
113                 mcf_enable_irq0(irq);
114         }
115 }
116
117 /***************************************************************************/
118
119 int mcf_timerirqpending(int timer)
120 {
121         unsigned int imr = 0;
122
123         switch (timer) {
124         case 1:  imr = 0x1; break;
125         case 2:  imr = 0x2; break;
126         default: break;
127         }
128         return (mcf_getiprh() & imr);
129 }
130
131 /***************************************************************************/
132
133 void __init config_BSP(char *commandp, int size)
134 {
135         mcf_setimr(MCFSIM_IMR_MASKALL);
136
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);
145         }
146 #endif
147
148         mcf_timervector = 64+32;
149         mcf_profilevector = 64+33;
150         mach_reset = coldfire_reset;
151
152 #ifdef CONFIG_BDM_DISABLE
153         /*
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.
157          */
158         wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
159 #endif
160 }
161
162 /***************************************************************************/
163
164 static int __init init_BSP(void)
165 {
166         m532x_uarts_init();
167         platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
168         return 0;
169 }
170
171 arch_initcall(init_BSP);
172
173 /***************************************************************************/
174 /* Board initialization */
175 /***************************************************************************/
176 /* 
177  * PLL min/max specifications
178  */
179 #define MAX_FVCO        500000  /* KHz */
180 #define MAX_FSYS        80000   /* KHz */
181 #define MIN_FSYS        58333   /* KHz */
182 #define FREF            16000   /* KHz */
183
184
185 #define MAX_MFD         135     /* Multiplier */
186 #define MIN_MFD         88      /* Multiplier */
187 #define BUSDIV          6       /* Divider */
188
189 /*
190  * Low Power Divider specifications
191  */
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) */
195
196 #define SYS_CLK_KHZ     80000
197 #define SYSTEM_PERIOD   12.5
198 /*
199  *  SDRAM Timing Parameters
200  */  
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 */
208
209 #define EXT_SRAM_ADDRESS        (0xC0000000)
210 #define FLASH_ADDRESS           (0x00000000)
211 #define SDRAM_ADDRESS           (0x40000000)
212
213 #define NAND_FLASH_ADDRESS      (0xD0000000)
214
215 int sys_clk_khz = 0;
216 int sys_clk_mhz = 0;
217
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);
227
228 asmlinkage void __init sysinit(void)
229 {
230         sys_clk_khz = clock_pll(0, 0);
231         sys_clk_mhz = sys_clk_khz/1000;
232         
233         wtm_init();
234         scm_init();
235         gpio_init();
236         fbcs_init();
237         sdramc_init();
238 }
239
240 void wtm_init(void)
241 {
242         /* Disable watchdog timer */
243         MCF_WTM_WCR = 0;
244 }
245
246 #define MCF_SCM_BCR_GBW         (0x00000100)
247 #define MCF_SCM_BCR_GBR         (0x00000200)
248
249 void scm_init(void)
250 {
251         /* All masters are trusted */
252         MCF_SCM_MPR = 0x77777777;
253     
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;
262
263         /* Enable bursts */
264         MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
265 }
266
267
268 void fbcs_init(void)
269 {
270         MCF_GPIO_PAR_CS = 0x0000003E;
271
272         /* Latch chip select */
273         MCF_FBCS1_CSAR = 0x10080000;
274
275         MCF_FBCS1_CSCR = 0x002A3780;
276         MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
277
278         /* Initialize latch to drive signals to inactive states */
279         *((u16 *)(0x10080000)) = 0xFFFF;
280
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);
289
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);
299 }
300
301 void sdramc_init(void)
302 {
303         /*
304          * Check to see if the SDRAM has already been initialized
305          * by a run control tool
306          */
307         if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
308                 /* SDRAM chip select initialization */
309                 
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));
314
315         /*
316          * Basic configuration and initialization
317          */
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));
331
332             
333         /*
334          * Precharge and enable write to SDMR
335          */
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);            
344
345         /*
346          * Write extended mode register
347          */
348         MCF_SDRAMC_SDMR = (0
349                 | MCF_SDRAMC_SDMR_BNKAD_LEMR
350                 | MCF_SDRAMC_SDMR_AD(0x0)
351                 | MCF_SDRAMC_SDMR_CMD);
352
353         /*
354          * Write mode register and reset DLL
355          */
356         MCF_SDRAMC_SDMR = (0
357                 | MCF_SDRAMC_SDMR_BNKAD_LMR
358                 | MCF_SDRAMC_SDMR_AD(0x163)
359                 | MCF_SDRAMC_SDMR_CMD);
360
361         /*
362          * Execute a PALL command
363          */
364         MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
365
366         /*
367          * Perform two REF cycles
368          */
369         MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
370         MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
371
372         /*
373          * Write mode register and clear reset DLL
374          */
375         MCF_SDRAMC_SDMR = (0
376                 | MCF_SDRAMC_SDMR_BNKAD_LMR
377                 | MCF_SDRAMC_SDMR_AD(0x063)
378                 | MCF_SDRAMC_SDMR_CMD);
379                                 
380         /*
381          * Enable auto refresh and lock SDMR
382          */
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));
387         }
388 }
389
390 void gpio_init(void)
391 {
392         /* Enable UART0 pins */
393         MCF_GPIO_PAR_UART = ( 0
394                 | MCF_GPIO_PAR_UART_PAR_URXD0
395                 | MCF_GPIO_PAR_UART_PAR_UTXD0);
396
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;
402
403 }
404
405 int clock_pll(int fsys, int flags)
406 {
407         int fref, temp, fout, mfd;
408         u32 i;
409
410         fref = FREF;
411         
412         if (fsys == 0) {
413                 /* Return current PLL output */
414                 mfd = MCF_PLL_PFDR;
415
416                 return (fref * mfd / (BUSDIV * 4));
417         }
418
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;
424
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;
431                         
432         /* Determine the output frequency for selected values */
433         fout = (fref * mfd / (BUSDIV * 4));
434
435         /*
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.
439          */
440         if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
441                 /* Put SDRAM into self refresh mode */
442                 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
443
444         /*
445          * Initialize the PLL to generate the new system clock frequency.
446          * The device must be put into LIMP mode to reprogram the PLL.
447          */
448
449         /* Enter LIMP mode */
450         clock_limp(DEFAULT_LPD);
451                                         
452         /* Reprogram PLL for desired fsys */
453         MCF_PLL_PODR = (0
454                 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
455                 | MCF_PLL_PODR_BUSDIV(BUSDIV));
456                                                 
457         MCF_PLL_PFDR = mfd;
458                 
459         /* Exit LIMP mode */
460         clock_exit_limp();
461         
462         /*
463          * Return the SDRAM to normal operation if it is in use.
464          */
465         if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
466                 /* Exit self refresh mode */
467                 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
468
469         /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
470         MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
471
472         /* wait for DQS logic to relock */
473         for (i = 0; i < 0x200; i++)
474                 ;
475
476         return fout;
477 }
478
479 int clock_limp(int div)
480 {
481         u32 temp;
482
483         /* Check bounds of divider */
484         if (div < MIN_LPD)
485                 div = MIN_LPD;
486         if (div > MAX_LPD)
487                 div = MAX_LPD;
488     
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));
492       
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));
497     
498         MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
499     
500         return (FREF/(3*(1 << div)));
501 }
502
503 int clock_exit_limp(void)
504 {
505         int fout;
506         
507         /* Exit LIMP mode */
508         MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
509
510         /* Wait for PLL to lock */
511         while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
512                 ;
513         
514         fout = get_sys_clock();
515
516         return fout;
517 }
518
519 int get_sys_clock(void)
520 {
521         int divider;
522         
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));
527         }
528         else
529                 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
530 }