ACPI: video: DMI workaround broken eMachines E510 BIOS enabling display brightness
[linux-2.6/linux-acpi-2.6.git] / arch / m68knommu / platform / 532x / config.c
blob591f2f801134b495f1dfbf9f49a4868e20319c7b
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 void coldfire_reset(void);
36 extern unsigned int mcf_timervector;
37 extern unsigned int mcf_profilevector;
38 extern unsigned int mcf_timerlevel;
40 /***************************************************************************/
42 static struct mcf_platform_uart m532x_uart_platform[] = {
44 .mapbase = MCFUART_BASE1,
45 .irq = MCFINT_VECBASE + MCFINT_UART0,
48 .mapbase = MCFUART_BASE2,
49 .irq = MCFINT_VECBASE + MCFINT_UART1,
52 .mapbase = MCFUART_BASE3,
53 .irq = MCFINT_VECBASE + MCFINT_UART2,
55 { },
58 static struct platform_device m532x_uart = {
59 .name = "mcfuart",
60 .id = 0,
61 .dev.platform_data = m532x_uart_platform,
64 static struct resource m532x_fec_resources[] = {
66 .start = 0xfc030000,
67 .end = 0xfc0307ff,
68 .flags = IORESOURCE_MEM,
71 .start = 64 + 36,
72 .end = 64 + 36,
73 .flags = IORESOURCE_IRQ,
76 .start = 64 + 40,
77 .end = 64 + 40,
78 .flags = IORESOURCE_IRQ,
81 .start = 64 + 42,
82 .end = 64 + 42,
83 .flags = IORESOURCE_IRQ,
87 static struct platform_device m532x_fec = {
88 .name = "fec",
89 .id = 0,
90 .num_resources = ARRAY_SIZE(m532x_fec_resources),
91 .resource = m532x_fec_resources,
93 static struct platform_device *m532x_devices[] __initdata = {
94 &m532x_uart,
95 &m532x_fec,
98 /***************************************************************************/
100 static void __init m532x_uart_init_line(int line, int irq)
102 if (line == 0) {
103 MCF_INTC0_ICR26 = 0x3;
104 MCF_INTC0_CIMR = 26;
105 /* GPIO initialization */
106 MCF_GPIO_PAR_UART |= 0x000F;
107 } else if (line == 1) {
108 MCF_INTC0_ICR27 = 0x3;
109 MCF_INTC0_CIMR = 27;
110 /* GPIO initialization */
111 MCF_GPIO_PAR_UART |= 0x0FF0;
112 } else if (line == 2) {
113 MCF_INTC0_ICR28 = 0x3;
114 MCF_INTC0_CIMR = 28;
118 static void __init m532x_uarts_init(void)
120 const int nrlines = ARRAY_SIZE(m532x_uart_platform);
121 int line;
123 for (line = 0; (line < nrlines); line++)
124 m532x_uart_init_line(line, m532x_uart_platform[line].irq);
126 /***************************************************************************/
128 static void __init m532x_fec_init(void)
130 /* Unmask FEC interrupts at ColdFire interrupt controller */
131 MCF_INTC0_ICR36 = 0x2;
132 MCF_INTC0_ICR40 = 0x2;
133 MCF_INTC0_ICR42 = 0x2;
135 MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
136 MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
138 /* Set multi-function pins to ethernet mode for fec0 */
139 MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
140 MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
141 MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
142 MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
145 /***************************************************************************/
147 void mcf_settimericr(unsigned int timer, unsigned int level)
149 volatile unsigned char *icrp;
150 unsigned int icr;
151 unsigned char irq;
153 if (timer <= 2) {
154 switch (timer) {
155 case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break;
156 default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
159 icrp = (volatile unsigned char *) (icr);
160 *icrp = level;
161 mcf_enable_irq0(irq);
165 /***************************************************************************/
167 void __init config_BSP(char *commandp, int size)
169 mcf_setimr(MCFSIM_IMR_MASKALL);
171 #if !defined(CONFIG_BOOTPARAM)
172 /* Copy command line from FLASH to local buffer... */
173 memcpy(commandp, (char *) 0x4000, 4);
174 if(strncmp(commandp, "kcl ", 4) == 0){
175 memcpy(commandp, (char *) 0x4004, size);
176 commandp[size-1] = 0;
177 } else {
178 memset(commandp, 0, size);
180 #endif
182 mcf_timervector = 64+32;
183 mcf_profilevector = 64+33;
184 mach_reset = coldfire_reset;
186 #ifdef CONFIG_BDM_DISABLE
188 * Disable the BDM clocking. This also turns off most of the rest of
189 * the BDM device. This is good for EMC reasons. This option is not
190 * incompatible with the memory protection option.
192 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
193 #endif
196 /***************************************************************************/
198 static int __init init_BSP(void)
200 m532x_uarts_init();
201 m532x_fec_init();
202 platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
203 return 0;
206 arch_initcall(init_BSP);
208 /***************************************************************************/
209 /* Board initialization */
210 /***************************************************************************/
212 * PLL min/max specifications
214 #define MAX_FVCO 500000 /* KHz */
215 #define MAX_FSYS 80000 /* KHz */
216 #define MIN_FSYS 58333 /* KHz */
217 #define FREF 16000 /* KHz */
220 #define MAX_MFD 135 /* Multiplier */
221 #define MIN_MFD 88 /* Multiplier */
222 #define BUSDIV 6 /* Divider */
225 * Low Power Divider specifications
227 #define MIN_LPD (1 << 0) /* Divider (not encoded) */
228 #define MAX_LPD (1 << 15) /* Divider (not encoded) */
229 #define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
231 #define SYS_CLK_KHZ 80000
232 #define SYSTEM_PERIOD 12.5
234 * SDRAM Timing Parameters
236 #define SDRAM_BL 8 /* # of beats in a burst */
237 #define SDRAM_TWR 2 /* in clocks */
238 #define SDRAM_CASL 2.5 /* CASL in clocks */
239 #define SDRAM_TRCD 2 /* in clocks */
240 #define SDRAM_TRP 2 /* in clocks */
241 #define SDRAM_TRFC 7 /* in clocks */
242 #define SDRAM_TREFI 7800 /* in ns */
244 #define EXT_SRAM_ADDRESS (0xC0000000)
245 #define FLASH_ADDRESS (0x00000000)
246 #define SDRAM_ADDRESS (0x40000000)
248 #define NAND_FLASH_ADDRESS (0xD0000000)
250 int sys_clk_khz = 0;
251 int sys_clk_mhz = 0;
253 void wtm_init(void);
254 void scm_init(void);
255 void gpio_init(void);
256 void fbcs_init(void);
257 void sdramc_init(void);
258 int clock_pll (int fsys, int flags);
259 int clock_limp (int);
260 int clock_exit_limp (void);
261 int get_sys_clock (void);
263 asmlinkage void __init sysinit(void)
265 sys_clk_khz = clock_pll(0, 0);
266 sys_clk_mhz = sys_clk_khz/1000;
268 wtm_init();
269 scm_init();
270 gpio_init();
271 fbcs_init();
272 sdramc_init();
275 void wtm_init(void)
277 /* Disable watchdog timer */
278 MCF_WTM_WCR = 0;
281 #define MCF_SCM_BCR_GBW (0x00000100)
282 #define MCF_SCM_BCR_GBR (0x00000200)
284 void scm_init(void)
286 /* All masters are trusted */
287 MCF_SCM_MPR = 0x77777777;
289 /* Allow supervisor/user, read/write, and trusted/untrusted
290 access to all slaves */
291 MCF_SCM_PACRA = 0;
292 MCF_SCM_PACRB = 0;
293 MCF_SCM_PACRC = 0;
294 MCF_SCM_PACRD = 0;
295 MCF_SCM_PACRE = 0;
296 MCF_SCM_PACRF = 0;
298 /* Enable bursts */
299 MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
303 void fbcs_init(void)
305 MCF_GPIO_PAR_CS = 0x0000003E;
307 /* Latch chip select */
308 MCF_FBCS1_CSAR = 0x10080000;
310 MCF_FBCS1_CSCR = 0x002A3780;
311 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
313 /* Initialize latch to drive signals to inactive states */
314 *((u16 *)(0x10080000)) = 0xFFFF;
316 /* External SRAM */
317 MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
318 MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
319 | MCF_FBCS_CSCR_AA
320 | MCF_FBCS_CSCR_SBM
321 | MCF_FBCS_CSCR_WS(1));
322 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
323 | MCF_FBCS_CSMR_V);
325 /* Boot Flash connected to FBCS0 */
326 MCF_FBCS0_CSAR = FLASH_ADDRESS;
327 MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
328 | MCF_FBCS_CSCR_BEM
329 | MCF_FBCS_CSCR_AA
330 | MCF_FBCS_CSCR_SBM
331 | MCF_FBCS_CSCR_WS(7));
332 MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
333 | MCF_FBCS_CSMR_V);
336 void sdramc_init(void)
339 * Check to see if the SDRAM has already been initialized
340 * by a run control tool
342 if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
343 /* SDRAM chip select initialization */
345 /* Initialize SDRAM chip select */
346 MCF_SDRAMC_SDCS0 = (0
347 | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
348 | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
351 * Basic configuration and initialization
353 MCF_SDRAMC_SDCFG1 = (0
354 | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
355 | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
356 | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
357 | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
358 | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
359 | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
360 | MCF_SDRAMC_SDCFG1_WTLAT(3));
361 MCF_SDRAMC_SDCFG2 = (0
362 | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
363 | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
364 | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
365 | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
369 * Precharge and enable write to SDMR
371 MCF_SDRAMC_SDCR = (0
372 | MCF_SDRAMC_SDCR_MODE_EN
373 | MCF_SDRAMC_SDCR_CKE
374 | MCF_SDRAMC_SDCR_DDR
375 | MCF_SDRAMC_SDCR_MUX(1)
376 | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
377 | MCF_SDRAMC_SDCR_PS_16
378 | MCF_SDRAMC_SDCR_IPALL);
381 * Write extended mode register
383 MCF_SDRAMC_SDMR = (0
384 | MCF_SDRAMC_SDMR_BNKAD_LEMR
385 | MCF_SDRAMC_SDMR_AD(0x0)
386 | MCF_SDRAMC_SDMR_CMD);
389 * Write mode register and reset DLL
391 MCF_SDRAMC_SDMR = (0
392 | MCF_SDRAMC_SDMR_BNKAD_LMR
393 | MCF_SDRAMC_SDMR_AD(0x163)
394 | MCF_SDRAMC_SDMR_CMD);
397 * Execute a PALL command
399 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
402 * Perform two REF cycles
404 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
405 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
408 * Write mode register and clear reset DLL
410 MCF_SDRAMC_SDMR = (0
411 | MCF_SDRAMC_SDMR_BNKAD_LMR
412 | MCF_SDRAMC_SDMR_AD(0x063)
413 | MCF_SDRAMC_SDMR_CMD);
416 * Enable auto refresh and lock SDMR
418 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
419 MCF_SDRAMC_SDCR |= (0
420 | MCF_SDRAMC_SDCR_REF
421 | MCF_SDRAMC_SDCR_DQS_OE(0xC));
425 void gpio_init(void)
427 /* Enable UART0 pins */
428 MCF_GPIO_PAR_UART = ( 0
429 | MCF_GPIO_PAR_UART_PAR_URXD0
430 | MCF_GPIO_PAR_UART_PAR_UTXD0);
432 /* Initialize TIN3 as a GPIO output to enable the write
433 half of the latch */
434 MCF_GPIO_PAR_TIMER = 0x00;
435 MCF_GPIO_PDDR_TIMER = 0x08;
436 MCF_GPIO_PCLRR_TIMER = 0x0;
440 int clock_pll(int fsys, int flags)
442 int fref, temp, fout, mfd;
443 u32 i;
445 fref = FREF;
447 if (fsys == 0) {
448 /* Return current PLL output */
449 mfd = MCF_PLL_PFDR;
451 return (fref * mfd / (BUSDIV * 4));
454 /* Check bounds of requested system clock */
455 if (fsys > MAX_FSYS)
456 fsys = MAX_FSYS;
457 if (fsys < MIN_FSYS)
458 fsys = MIN_FSYS;
460 /* Multiplying by 100 when calculating the temp value,
461 and then dividing by 100 to calculate the mfd allows
462 for exact values without needing to include floating
463 point libraries. */
464 temp = 100 * fsys / fref;
465 mfd = 4 * BUSDIV * temp / 100;
467 /* Determine the output frequency for selected values */
468 fout = (fref * mfd / (BUSDIV * 4));
471 * Check to see if the SDRAM has already been initialized.
472 * If it has then the SDRAM needs to be put into self refresh
473 * mode before reprogramming the PLL.
475 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
476 /* Put SDRAM into self refresh mode */
477 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
480 * Initialize the PLL to generate the new system clock frequency.
481 * The device must be put into LIMP mode to reprogram the PLL.
484 /* Enter LIMP mode */
485 clock_limp(DEFAULT_LPD);
487 /* Reprogram PLL for desired fsys */
488 MCF_PLL_PODR = (0
489 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
490 | MCF_PLL_PODR_BUSDIV(BUSDIV));
492 MCF_PLL_PFDR = mfd;
494 /* Exit LIMP mode */
495 clock_exit_limp();
498 * Return the SDRAM to normal operation if it is in use.
500 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
501 /* Exit self refresh mode */
502 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
504 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
505 MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
507 /* wait for DQS logic to relock */
508 for (i = 0; i < 0x200; i++)
511 return fout;
514 int clock_limp(int div)
516 u32 temp;
518 /* Check bounds of divider */
519 if (div < MIN_LPD)
520 div = MIN_LPD;
521 if (div > MAX_LPD)
522 div = MAX_LPD;
524 /* Save of the current value of the SSIDIV so we don't
525 overwrite the value*/
526 temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
528 /* Apply the divider to the system clock */
529 MCF_CCM_CDR = ( 0
530 | MCF_CCM_CDR_LPDIV(div)
531 | MCF_CCM_CDR_SSIDIV(temp));
533 MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
535 return (FREF/(3*(1 << div)));
538 int clock_exit_limp(void)
540 int fout;
542 /* Exit LIMP mode */
543 MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
545 /* Wait for PLL to lock */
546 while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
549 fout = get_sys_clock();
551 return fout;
554 int get_sys_clock(void)
556 int divider;
558 /* Test to see if device is in LIMP mode */
559 if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
560 divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
561 return (FREF/(2 << divider));
563 else
564 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));