linux/arch/m68knommu/platform/532x/config.c
<<
>>
Prefs
   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        /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
 588        MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
 589
 590        /* wait for DQS logic to relock */
 591        for (i = 0; i < 0x200; i++)
 592                ;
 593
 594        return fout;
 595}
 596
 597int clock_limp(int div)
 598{
 599        u32 temp;
 600
 601        /* Check bounds of divider */
 602        if (div < MIN_LPD)
 603                div = MIN_LPD;
 604        if (div > MAX_LPD)
 605                div = MAX_LPD;
 606    
 607        /* Save of the current value of the SSIDIV so we don't
 608           overwrite the value*/
 609        temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
 610      
 611        /* Apply the divider to the system clock */
 612        MCF_CCM_CDR = ( 0
 613                | MCF_CCM_CDR_LPDIV(div)
 614                | MCF_CCM_CDR_SSIDIV(temp));
 615    
 616        MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
 617    
 618        return (FREF/(3*(1 << div)));
 619}
 620
 621int clock_exit_limp(void)
 622{
 623        int fout;
 624        
 625        /* Exit LIMP mode */
 626        MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
 627
 628        /* Wait for PLL to lock */
 629        while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
 630                ;
 631        
 632        fout = get_sys_clock();
 633
 634        return fout;
 635}
 636
 637int get_sys_clock(void)
 638{
 639        int divider;
 640        
 641        /* Test to see if device is in LIMP mode */
 642        if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
 643                divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
 644                return (FREF/(2 << divider));
 645        }
 646        else
 647                return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
 648}
 649