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