wl1251: use wiphy_dev instead of wl->spi->dev
[linux/fpc-iii.git] / arch / m68knommu / platform / 532x / config.c
blobcdb761971f7a7e8ca479766aeb2271d0688c52bf
1 /***************************************************************************/
3 /*
4 * linux/arch/m68knommu/platform/532x/config.c
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>
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.
18 /***************************************************************************/
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>
32 /***************************************************************************/
34 extern unsigned int mcf_timervector;
35 extern unsigned int mcf_profilevector;
36 extern unsigned int mcf_timerlevel;
38 /***************************************************************************/
40 static struct mcf_platform_uart m532x_uart_platform[] = {
42 .mapbase = MCFUART_BASE1,
43 .irq = MCFINT_VECBASE + MCFINT_UART0,
46 .mapbase = MCFUART_BASE2,
47 .irq = MCFINT_VECBASE + MCFINT_UART1,
50 .mapbase = MCFUART_BASE3,
51 .irq = MCFINT_VECBASE + MCFINT_UART2,
53 { },
56 static struct platform_device m532x_uart = {
57 .name = "mcfuart",
58 .id = 0,
59 .dev.platform_data = m532x_uart_platform,
62 static struct resource m532x_fec_resources[] = {
64 .start = 0xfc030000,
65 .end = 0xfc0307ff,
66 .flags = IORESOURCE_MEM,
69 .start = 64 + 36,
70 .end = 64 + 36,
71 .flags = IORESOURCE_IRQ,
74 .start = 64 + 40,
75 .end = 64 + 40,
76 .flags = IORESOURCE_IRQ,
79 .start = 64 + 42,
80 .end = 64 + 42,
81 .flags = IORESOURCE_IRQ,
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,
91 static struct platform_device *m532x_devices[] __initdata = {
92 &m532x_uart,
93 &m532x_fec,
96 /***************************************************************************/
98 static void __init m532x_uart_init_line(int line, int irq)
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;
116 static void __init m532x_uarts_init(void)
118 const int nrlines = ARRAY_SIZE(m532x_uart_platform);
119 int line;
121 for (line = 0; (line < nrlines); line++)
122 m532x_uart_init_line(line, m532x_uart_platform[line].irq);
124 /***************************************************************************/
126 static void __init m532x_fec_init(void)
128 /* Unmask FEC interrupts at ColdFire interrupt controller */
129 MCF_INTC0_ICR36 = 0x2;
130 MCF_INTC0_ICR40 = 0x2;
131 MCF_INTC0_ICR42 = 0x2;
133 MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
134 MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
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);
143 /***************************************************************************/
145 void mcf_settimericr(unsigned int timer, unsigned int level)
147 volatile unsigned char *icrp;
148 unsigned int icr;
149 unsigned char irq;
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;
157 icrp = (volatile unsigned char *) (icr);
158 *icrp = level;
159 mcf_enable_irq0(irq);
163 /***************************************************************************/
165 static void m532x_cpu_reset(void)
167 local_irq_disable();
168 __raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
171 /***************************************************************************/
173 void __init config_BSP(char *commandp, int size)
175 mcf_setimr(MCFSIM_IMR_MASKALL);
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);
186 #endif
188 mcf_timervector = 64+32;
189 mcf_profilevector = 64+33;
190 mach_reset = m532x_cpu_reset;
192 #ifdef CONFIG_BDM_DISABLE
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.
198 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
199 #endif
202 /***************************************************************************/
204 static int __init init_BSP(void)
206 m532x_uarts_init();
207 m532x_fec_init();
208 platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
209 return 0;
212 arch_initcall(init_BSP);
214 /***************************************************************************/
215 /* Board initialization */
216 /***************************************************************************/
218 * PLL min/max specifications
220 #define MAX_FVCO 500000 /* KHz */
221 #define MAX_FSYS 80000 /* KHz */
222 #define MIN_FSYS 58333 /* KHz */
223 #define FREF 16000 /* KHz */
226 #define MAX_MFD 135 /* Multiplier */
227 #define MIN_MFD 88 /* Multiplier */
228 #define BUSDIV 6 /* Divider */
231 * Low Power Divider specifications
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) */
237 #define SYS_CLK_KHZ 80000
238 #define SYSTEM_PERIOD 12.5
240 * SDRAM Timing Parameters
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 */
250 #define EXT_SRAM_ADDRESS (0xC0000000)
251 #define FLASH_ADDRESS (0x00000000)
252 #define SDRAM_ADDRESS (0x40000000)
254 #define NAND_FLASH_ADDRESS (0xD0000000)
256 int sys_clk_khz = 0;
257 int sys_clk_mhz = 0;
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);
269 asmlinkage void __init sysinit(void)
271 sys_clk_khz = clock_pll(0, 0);
272 sys_clk_mhz = sys_clk_khz/1000;
274 wtm_init();
275 scm_init();
276 gpio_init();
277 fbcs_init();
278 sdramc_init();
281 void wtm_init(void)
283 /* Disable watchdog timer */
284 MCF_WTM_WCR = 0;
287 #define MCF_SCM_BCR_GBW (0x00000100)
288 #define MCF_SCM_BCR_GBR (0x00000200)
290 void scm_init(void)
292 /* All masters are trusted */
293 MCF_SCM_MPR = 0x77777777;
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;
304 /* Enable bursts */
305 MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
309 void fbcs_init(void)
311 MCF_GPIO_PAR_CS = 0x0000003E;
313 /* Latch chip select */
314 MCF_FBCS1_CSAR = 0x10080000;
316 MCF_FBCS1_CSCR = 0x002A3780;
317 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
319 /* Initialize latch to drive signals to inactive states */
320 *((u16 *)(0x10080000)) = 0xFFFF;
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);
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);
342 void sdramc_init(void)
345 * Check to see if the SDRAM has already been initialized
346 * by a run control tool
348 if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
349 /* SDRAM chip select initialization */
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));
357 * Basic configuration and initialization
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));
375 * Precharge and enable write to SDMR
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);
387 * Write extended mode register
389 MCF_SDRAMC_SDMR = (0
390 | MCF_SDRAMC_SDMR_BNKAD_LEMR
391 | MCF_SDRAMC_SDMR_AD(0x0)
392 | MCF_SDRAMC_SDMR_CMD);
395 * Write mode register and reset DLL
397 MCF_SDRAMC_SDMR = (0
398 | MCF_SDRAMC_SDMR_BNKAD_LMR
399 | MCF_SDRAMC_SDMR_AD(0x163)
400 | MCF_SDRAMC_SDMR_CMD);
403 * Execute a PALL command
405 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
408 * Perform two REF cycles
410 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
411 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
414 * Write mode register and clear reset DLL
416 MCF_SDRAMC_SDMR = (0
417 | MCF_SDRAMC_SDMR_BNKAD_LMR
418 | MCF_SDRAMC_SDMR_AD(0x063)
419 | MCF_SDRAMC_SDMR_CMD);
422 * Enable auto refresh and lock SDMR
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));
431 void gpio_init(void)
433 /* Enable UART0 pins */
434 MCF_GPIO_PAR_UART = ( 0
435 | MCF_GPIO_PAR_UART_PAR_URXD0
436 | MCF_GPIO_PAR_UART_PAR_UTXD0);
438 /* Initialize TIN3 as a GPIO output to enable the write
439 half of the latch */
440 MCF_GPIO_PAR_TIMER = 0x00;
441 MCF_GPIO_PDDR_TIMER = 0x08;
442 MCF_GPIO_PCLRR_TIMER = 0x0;
446 int clock_pll(int fsys, int flags)
448 int fref, temp, fout, mfd;
449 u32 i;
451 fref = FREF;
453 if (fsys == 0) {
454 /* Return current PLL output */
455 mfd = MCF_PLL_PFDR;
457 return (fref * mfd / (BUSDIV * 4));
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;
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;
473 /* Determine the output frequency for selected values */
474 fout = (fref * mfd / (BUSDIV * 4));
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.
481 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
482 /* Put SDRAM into self refresh mode */
483 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
486 * Initialize the PLL to generate the new system clock frequency.
487 * The device must be put into LIMP mode to reprogram the PLL.
490 /* Enter LIMP mode */
491 clock_limp(DEFAULT_LPD);
493 /* Reprogram PLL for desired fsys */
494 MCF_PLL_PODR = (0
495 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
496 | MCF_PLL_PODR_BUSDIV(BUSDIV));
498 MCF_PLL_PFDR = mfd;
500 /* Exit LIMP mode */
501 clock_exit_limp();
504 * Return the SDRAM to normal operation if it is in use.
506 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
507 /* Exit self refresh mode */
508 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
510 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
511 MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
513 /* wait for DQS logic to relock */
514 for (i = 0; i < 0x200; i++)
517 return fout;
520 int clock_limp(int div)
522 u32 temp;
524 /* Check bounds of divider */
525 if (div < MIN_LPD)
526 div = MIN_LPD;
527 if (div > MAX_LPD)
528 div = MAX_LPD;
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));
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));
539 MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
541 return (FREF/(3*(1 << div)));
544 int clock_exit_limp(void)
546 int fout;
548 /* Exit LIMP mode */
549 MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
551 /* Wait for PLL to lock */
552 while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
555 fout = get_sys_clock();
557 return fout;
560 int get_sys_clock(void)
562 int divider;
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));
569 else
570 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));