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