Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[pandora-kernel.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 <asm/dma.h>
25 #include <asm/machdep.h>
26 #include <asm/coldfire.h>
27 #include <asm/mcfsim.h>
28 #include <asm/mcfdma.h>
29 #include <asm/mcfwdebug.h>
30
31 /***************************************************************************/
32
33 void coldfire_reset(void);
34
35 extern unsigned int mcf_timervector;
36 extern unsigned int mcf_profilevector;
37 extern unsigned int mcf_timerlevel;
38
39 /***************************************************************************/
40
41 /*
42  *      DMA channel base address table.
43  */
44 unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { };
45 unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
46
47 /***************************************************************************/
48
49 void mcf_settimericr(unsigned int timer, unsigned int level)
50 {
51         volatile unsigned char *icrp;
52         unsigned int icr;
53         unsigned char irq;
54
55         if (timer <= 2) {
56                 switch (timer) {
57                 case 2:  irq = 33; icr = MCFSIM_ICR_TIMER2; break;
58                 default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
59                 }
60                 
61                 icrp = (volatile unsigned char *) (MCF_MBAR + icr);
62                 *icrp = level;
63                 mcf_enable_irq0(irq);
64         }
65 }
66
67 /***************************************************************************/
68
69 int mcf_timerirqpending(int timer)
70 {
71         unsigned int imr = 0;
72
73         switch (timer) {
74         case 1:  imr = 0x1; break;
75         case 2:  imr = 0x2; break;
76         default: break;
77         }
78         return (mcf_getiprh() & imr);
79 }
80
81 /***************************************************************************/
82
83 void config_BSP(char *commandp, int size)
84 {
85         mcf_setimr(MCFSIM_IMR_MASKALL);
86
87 #if !defined(CONFIG_BOOTPARAM)
88         /* Copy command line from FLASH to local buffer... */
89         memcpy(commandp, (char *) 0x4000, 4);
90         if(strncmp(commandp, "kcl ", 4) == 0){
91                 memcpy(commandp, (char *) 0x4004, size);
92                 commandp[size-1] = 0;
93         } else {
94                 memset(commandp, 0, size);
95         }
96 #endif
97
98         mcf_timervector = 64+32;
99         mcf_profilevector = 64+33;
100         mach_reset = coldfire_reset;
101
102 #ifdef MCF_BDM_DISABLE
103         /*
104          * Disable the BDM clocking.  This also turns off most of the rest of
105          * the BDM device.  This is good for EMC reasons. This option is not
106          * incompatible with the memory protection option.
107          */
108         wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
109 #endif
110 }
111
112 /***************************************************************************/
113 /* Board initialization */
114
115 /********************************************************************/
116 /* 
117  * PLL min/max specifications
118  */
119 #define MAX_FVCO        500000  /* KHz */
120 #define MAX_FSYS        80000   /* KHz */
121 #define MIN_FSYS        58333   /* KHz */
122 #define FREF            16000   /* KHz */
123
124
125 #define MAX_MFD         135     /* Multiplier */
126 #define MIN_MFD         88      /* Multiplier */
127 #define BUSDIV          6       /* Divider */
128
129 /*
130  * Low Power Divider specifications
131  */
132 #define MIN_LPD         (1 << 0)    /* Divider (not encoded) */
133 #define MAX_LPD         (1 << 15)   /* Divider (not encoded) */
134 #define DEFAULT_LPD     (1 << 1)        /* Divider (not encoded) */
135
136 #define SYS_CLK_KHZ     80000
137 #define SYSTEM_PERIOD   12.5
138 /*
139  *  SDRAM Timing Parameters
140  */  
141 #define SDRAM_BL        8       /* # of beats in a burst */
142 #define SDRAM_TWR       2       /* in clocks */
143 #define SDRAM_CASL      2.5     /* CASL in clocks */
144 #define SDRAM_TRCD      2       /* in clocks */
145 #define SDRAM_TRP       2       /* in clocks */
146 #define SDRAM_TRFC      7       /* in clocks */
147 #define SDRAM_TREFI     7800    /* in ns */
148
149 #define EXT_SRAM_ADDRESS        (0xC0000000)
150 #define FLASH_ADDRESS           (0x00000000)
151 #define SDRAM_ADDRESS           (0x40000000)
152
153 #define NAND_FLASH_ADDRESS      (0xD0000000)
154
155 int sys_clk_khz = 0;
156 int sys_clk_mhz = 0;
157
158 void wtm_init(void);
159 void scm_init(void);
160 void gpio_init(void);
161 void fbcs_init(void);
162 void sdramc_init(void);
163 int  clock_pll (int fsys, int flags);
164 int  clock_limp (int);
165 int  clock_exit_limp (void);
166 int  get_sys_clock (void);
167
168 asmlinkage void __init sysinit(void)
169 {
170         sys_clk_khz = clock_pll(0, 0);
171         sys_clk_mhz = sys_clk_khz/1000;
172         
173         wtm_init();
174         scm_init();
175         gpio_init();
176         fbcs_init();
177         sdramc_init();
178 }
179
180 void wtm_init(void)
181 {
182         /* Disable watchdog timer */
183         MCF_WTM_WCR = 0;
184 }
185
186 #define MCF_SCM_BCR_GBW         (0x00000100)
187 #define MCF_SCM_BCR_GBR         (0x00000200)
188
189 void scm_init(void)
190 {
191         /* All masters are trusted */
192         MCF_SCM_MPR = 0x77777777;
193     
194         /* Allow supervisor/user, read/write, and trusted/untrusted
195            access to all slaves */
196         MCF_SCM_PACRA = 0;
197         MCF_SCM_PACRB = 0;
198         MCF_SCM_PACRC = 0;
199         MCF_SCM_PACRD = 0;
200         MCF_SCM_PACRE = 0;
201         MCF_SCM_PACRF = 0;
202
203         /* Enable bursts */
204         MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
205 }
206
207
208 void fbcs_init(void)
209 {
210         MCF_GPIO_PAR_CS = 0x0000003E;
211
212         /* Latch chip select */
213         MCF_FBCS1_CSAR = 0x10080000;
214
215         MCF_FBCS1_CSCR = 0x002A3780;
216         MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
217
218         /* Initialize latch to drive signals to inactive states */
219         *((u16 *)(0x10080000)) = 0xFFFF;
220
221         /* External SRAM */
222         MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
223         MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
224                         | MCF_FBCS_CSCR_AA
225                         | MCF_FBCS_CSCR_SBM
226                         | MCF_FBCS_CSCR_WS(1));
227         MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
228                         | MCF_FBCS_CSMR_V);
229
230         /* Boot Flash connected to FBCS0 */
231         MCF_FBCS0_CSAR = FLASH_ADDRESS;
232         MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
233                         | MCF_FBCS_CSCR_BEM
234                         | MCF_FBCS_CSCR_AA
235                         | MCF_FBCS_CSCR_SBM
236                         | MCF_FBCS_CSCR_WS(7));
237         MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
238                         | MCF_FBCS_CSMR_V);
239 }
240
241 void sdramc_init(void)
242 {
243         /*
244          * Check to see if the SDRAM has already been initialized
245          * by a run control tool
246          */
247         if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
248                 /* SDRAM chip select initialization */
249                 
250                 /* Initialize SDRAM chip select */
251                 MCF_SDRAMC_SDCS0 = (0
252                         | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
253                         | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
254
255         /*
256          * Basic configuration and initialization
257          */
258         MCF_SDRAMC_SDCFG1 = (0
259                 | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
260                 | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
261                 | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
262                 | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
263                 | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
264                 | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
265                 | MCF_SDRAMC_SDCFG1_WTLAT(3));
266         MCF_SDRAMC_SDCFG2 = (0
267                 | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
268                 | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
269                 | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
270                 | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
271
272             
273         /*
274          * Precharge and enable write to SDMR
275          */
276         MCF_SDRAMC_SDCR = (0
277                 | MCF_SDRAMC_SDCR_MODE_EN
278                 | MCF_SDRAMC_SDCR_CKE
279                 | MCF_SDRAMC_SDCR_DDR
280                 | MCF_SDRAMC_SDCR_MUX(1)
281                 | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
282                 | MCF_SDRAMC_SDCR_PS_16
283                 | MCF_SDRAMC_SDCR_IPALL);            
284
285         /*
286          * Write extended mode register
287          */
288         MCF_SDRAMC_SDMR = (0
289                 | MCF_SDRAMC_SDMR_BNKAD_LEMR
290                 | MCF_SDRAMC_SDMR_AD(0x0)
291                 | MCF_SDRAMC_SDMR_CMD);
292
293         /*
294          * Write mode register and reset DLL
295          */
296         MCF_SDRAMC_SDMR = (0
297                 | MCF_SDRAMC_SDMR_BNKAD_LMR
298                 | MCF_SDRAMC_SDMR_AD(0x163)
299                 | MCF_SDRAMC_SDMR_CMD);
300
301         /*
302          * Execute a PALL command
303          */
304         MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
305
306         /*
307          * Perform two REF cycles
308          */
309         MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
310         MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
311
312         /*
313          * Write mode register and clear reset DLL
314          */
315         MCF_SDRAMC_SDMR = (0
316                 | MCF_SDRAMC_SDMR_BNKAD_LMR
317                 | MCF_SDRAMC_SDMR_AD(0x063)
318                 | MCF_SDRAMC_SDMR_CMD);
319                                 
320         /*
321          * Enable auto refresh and lock SDMR
322          */
323         MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
324         MCF_SDRAMC_SDCR |= (0
325                 | MCF_SDRAMC_SDCR_REF
326                 | MCF_SDRAMC_SDCR_DQS_OE(0xC));
327         }
328 }
329
330 void gpio_init(void)
331 {
332         /* Enable UART0 pins */
333         MCF_GPIO_PAR_UART = ( 0
334                 | MCF_GPIO_PAR_UART_PAR_URXD0
335                 | MCF_GPIO_PAR_UART_PAR_UTXD0);
336
337         /* Initialize TIN3 as a GPIO output to enable the write
338            half of the latch */
339         MCF_GPIO_PAR_TIMER = 0x00;
340         MCF_GPIO_PDDR_TIMER = 0x08;
341         MCF_GPIO_PCLRR_TIMER = 0x0;
342
343 }
344
345 int clock_pll(int fsys, int flags)
346 {
347         int fref, temp, fout, mfd;
348         u32 i;
349
350         fref = FREF;
351         
352         if (fsys == 0) {
353                 /* Return current PLL output */
354                 mfd = MCF_PLL_PFDR;
355
356                 return (fref * mfd / (BUSDIV * 4));
357         }
358
359         /* Check bounds of requested system clock */
360         if (fsys > MAX_FSYS)
361                 fsys = MAX_FSYS;
362         if (fsys < MIN_FSYS)
363                 fsys = MIN_FSYS;
364
365         /* Multiplying by 100 when calculating the temp value,
366            and then dividing by 100 to calculate the mfd allows
367            for exact values without needing to include floating
368            point libraries. */
369         temp = 100 * fsys / fref;
370         mfd = 4 * BUSDIV * temp / 100;
371                         
372         /* Determine the output frequency for selected values */
373         fout = (fref * mfd / (BUSDIV * 4));
374
375         /*
376          * Check to see if the SDRAM has already been initialized.
377          * If it has then the SDRAM needs to be put into self refresh
378          * mode before reprogramming the PLL.
379          */
380         if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
381                 /* Put SDRAM into self refresh mode */
382                 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
383
384         /*
385          * Initialize the PLL to generate the new system clock frequency.
386          * The device must be put into LIMP mode to reprogram the PLL.
387          */
388
389         /* Enter LIMP mode */
390         clock_limp(DEFAULT_LPD);
391                                         
392         /* Reprogram PLL for desired fsys */
393         MCF_PLL_PODR = (0
394                 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
395                 | MCF_PLL_PODR_BUSDIV(BUSDIV));
396                                                 
397         MCF_PLL_PFDR = mfd;
398                 
399         /* Exit LIMP mode */
400         clock_exit_limp();
401         
402         /*
403          * Return the SDRAM to normal operation if it is in use.
404          */
405         if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
406                 /* Exit self refresh mode */
407                 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
408
409         /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
410         MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
411
412         /* wait for DQS logic to relock */
413         for (i = 0; i < 0x200; i++)
414                 ;
415
416         return fout;
417 }
418
419 int clock_limp(int div)
420 {
421         u32 temp;
422
423         /* Check bounds of divider */
424         if (div < MIN_LPD)
425                 div = MIN_LPD;
426         if (div > MAX_LPD)
427                 div = MAX_LPD;
428     
429         /* Save of the current value of the SSIDIV so we don't
430            overwrite the value*/
431         temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
432       
433         /* Apply the divider to the system clock */
434         MCF_CCM_CDR = ( 0
435                 | MCF_CCM_CDR_LPDIV(div)
436                 | MCF_CCM_CDR_SSIDIV(temp));
437     
438         MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
439     
440         return (FREF/(3*(1 << div)));
441 }
442
443 int clock_exit_limp(void)
444 {
445         int fout;
446         
447         /* Exit LIMP mode */
448         MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
449
450         /* Wait for PLL to lock */
451         while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
452                 ;
453         
454         fout = get_sys_clock();
455
456         return fout;
457 }
458
459 int get_sys_clock(void)
460 {
461         int divider;
462         
463         /* Test to see if device is in LIMP mode */
464         if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
465                 divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
466                 return (FREF/(2 << divider));
467         }
468         else
469                 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
470 }