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