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