linux/arch/m68k/coldfire/m53xx.c
<<
>>
Prefs
   1/***************************************************************************/
   2
   3/*
   4 *      m53xx.c -- platform support for ColdFire 53xx based boards
   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 <shess@hessware.de>
  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 <asm/machdep.h>
  25#include <asm/coldfire.h>
  26#include <asm/mcfsim.h>
  27#include <asm/mcfuart.h>
  28#include <asm/mcfdma.h>
  29#include <asm/mcfwdebug.h>
  30#include <asm/mcfclk.h>
  31
  32/***************************************************************************/
  33
  34DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
  35DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
  36DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
  37DEFINE_CLK(0, "edma", 17, MCF_CLK);
  38DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
  39DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
  40DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
  41DEFINE_CLK(0, "imx1-i2c.0", 22, MCF_CLK);
  42DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
  43DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
  44DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
  45DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
  46DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
  47DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
  48DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
  49DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
  50
  51DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
  52DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
  53DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
  54DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
  55DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK);
  56DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
  57DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK);
  58DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
  59DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
  60DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
  61DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK);
  62DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
  63DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
  64DEFINE_CLK(0, "sdram.0", 46, MCF_CLK);
  65DEFINE_CLK(0, "ssi.0", 47, MCF_CLK);
  66DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
  67
  68DEFINE_CLK(1, "mdha.0", 32, MCF_CLK);
  69DEFINE_CLK(1, "skha.0", 33, MCF_CLK);
  70DEFINE_CLK(1, "rng.0", 34, MCF_CLK);
  71
  72struct clk *mcf_clks[] = {
  73        &__clk_0_2,     /* flexbus */
  74        &__clk_0_8,     /* mcfcan.0 */
  75        &__clk_0_12,    /* fec.0 */
  76        &__clk_0_17,    /* edma */
  77        &__clk_0_18,    /* intc.0 */
  78        &__clk_0_19,    /* intc.1 */
  79        &__clk_0_21,    /* iack.0 */
  80        &__clk_0_22,    /* imx1-i2c.0 */
  81        &__clk_0_23,    /* mcfqspi.0 */
  82        &__clk_0_24,    /* mcfuart.0 */
  83        &__clk_0_25,    /* mcfuart.1 */
  84        &__clk_0_26,    /* mcfuart.2 */
  85        &__clk_0_28,    /* mcftmr.0 */
  86        &__clk_0_29,    /* mcftmr.1 */
  87        &__clk_0_30,    /* mcftmr.2 */
  88        &__clk_0_31,    /* mcftmr.3 */
  89
  90        &__clk_0_32,    /* mcfpit.0 */
  91        &__clk_0_33,    /* mcfpit.1 */
  92        &__clk_0_34,    /* mcfpit.2 */
  93        &__clk_0_35,    /* mcfpit.3 */
  94        &__clk_0_36,    /* mcfpwm.0 */
  95        &__clk_0_37,    /* mcfeport.0 */
  96        &__clk_0_38,    /* mcfwdt.0 */
  97        &__clk_0_40,    /* sys.0 */
  98        &__clk_0_41,    /* gpio.0 */
  99        &__clk_0_42,    /* mcfrtc.0 */
 100        &__clk_0_43,    /* mcflcd.0 */
 101        &__clk_0_44,    /* mcfusb-otg.0 */
 102        &__clk_0_45,    /* mcfusb-host.0 */
 103        &__clk_0_46,    /* sdram.0 */
 104        &__clk_0_47,    /* ssi.0 */
 105        &__clk_0_48,    /* pll.0 */
 106
 107        &__clk_1_32,    /* mdha.0 */
 108        &__clk_1_33,    /* skha.0 */
 109        &__clk_1_34,    /* rng.0 */
 110        NULL,
 111};
 112
 113static struct clk * const enable_clks[] __initconst = {
 114        &__clk_0_2,     /* flexbus */
 115        &__clk_0_18,    /* intc.0 */
 116        &__clk_0_19,    /* intc.1 */
 117        &__clk_0_21,    /* iack.0 */
 118        &__clk_0_24,    /* mcfuart.0 */
 119        &__clk_0_25,    /* mcfuart.1 */
 120        &__clk_0_26,    /* mcfuart.2 */
 121        &__clk_0_28,    /* mcftmr.0 */
 122        &__clk_0_29,    /* mcftmr.1 */
 123        &__clk_0_32,    /* mcfpit.0 */
 124        &__clk_0_33,    /* mcfpit.1 */
 125        &__clk_0_37,    /* mcfeport.0 */
 126        &__clk_0_40,    /* sys.0 */
 127        &__clk_0_41,    /* gpio.0 */
 128        &__clk_0_46,    /* sdram.0 */
 129        &__clk_0_48,    /* pll.0 */
 130};
 131
 132static struct clk * const disable_clks[] __initconst = {
 133        &__clk_0_8,     /* mcfcan.0 */
 134        &__clk_0_12,    /* fec.0 */
 135        &__clk_0_17,    /* edma */
 136        &__clk_0_22,    /* imx1-i2c.0 */
 137        &__clk_0_23,    /* mcfqspi.0 */
 138        &__clk_0_30,    /* mcftmr.2 */
 139        &__clk_0_31,    /* mcftmr.3 */
 140        &__clk_0_34,    /* mcfpit.2 */
 141        &__clk_0_35,    /* mcfpit.3 */
 142        &__clk_0_36,    /* mcfpwm.0 */
 143        &__clk_0_38,    /* mcfwdt.0 */
 144        &__clk_0_42,    /* mcfrtc.0 */
 145        &__clk_0_43,    /* mcflcd.0 */
 146        &__clk_0_44,    /* mcfusb-otg.0 */
 147        &__clk_0_45,    /* mcfusb-host.0 */
 148        &__clk_0_47,    /* ssi.0 */
 149        &__clk_1_32,    /* mdha.0 */
 150        &__clk_1_33,    /* skha.0 */
 151        &__clk_1_34,    /* rng.0 */
 152};
 153
 154
 155static void __init m53xx_clk_init(void)
 156{
 157        unsigned i;
 158
 159        /* make sure these clocks are enabled */
 160        for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
 161                __clk_init_enabled(enable_clks[i]);
 162        /* make sure these clocks are disabled */
 163        for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
 164                __clk_init_disabled(disable_clks[i]);
 165}
 166
 167/***************************************************************************/
 168
 169static void __init m53xx_qspi_init(void)
 170{
 171#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
 172        /* setup QSPS pins for QSPI with gpio CS control */
 173        writew(0x01f0, MCFGPIO_PAR_QSPI);
 174#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
 175}
 176
 177/***************************************************************************/
 178
 179static void __init m53xx_i2c_init(void)
 180{
 181#if IS_ENABLED(CONFIG_I2C_IMX)
 182        /* setup Port AS Pin Assignment Register for I2C */
 183        /*  set PASPA0 to SCL and PASPA1 to SDA */
 184        u8 r = readb(MCFGPIO_PAR_FECI2C);
 185        r |= 0x0f;
 186        writeb(r, MCFGPIO_PAR_FECI2C);
 187#endif /* IS_ENABLED(CONFIG_I2C_IMX) */
 188}
 189
 190/***************************************************************************/
 191
 192static void __init m53xx_uarts_init(void)
 193{
 194        /* UART GPIO initialization */
 195        writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
 196}
 197
 198/***************************************************************************/
 199
 200static void __init m53xx_fec_init(void)
 201{
 202        u8 v;
 203
 204        /* Set multi-function pins to ethernet mode for fec0 */
 205        v = readb(MCFGPIO_PAR_FECI2C);
 206        v |= MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
 207                MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO;
 208        writeb(v, MCFGPIO_PAR_FECI2C);
 209
 210        v = readb(MCFGPIO_PAR_FEC);
 211        v = MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC;
 212        writeb(v, MCFGPIO_PAR_FEC);
 213}
 214
 215/***************************************************************************/
 216
 217void __init config_BSP(char *commandp, int size)
 218{
 219#if !defined(CONFIG_BOOTPARAM)
 220        /* Copy command line from FLASH to local buffer... */
 221        memcpy(commandp, (char *) 0x4000, 4);
 222        if(strncmp(commandp, "kcl ", 4) == 0){
 223                memcpy(commandp, (char *) 0x4004, size);
 224                commandp[size-1] = 0;
 225        } else {
 226                memset(commandp, 0, size);
 227        }
 228#endif
 229        mach_sched_init = hw_timer_init;
 230        m53xx_clk_init();
 231        m53xx_uarts_init();
 232        m53xx_fec_init();
 233        m53xx_qspi_init();
 234        m53xx_i2c_init();
 235
 236#ifdef CONFIG_BDM_DISABLE
 237        /*
 238         * Disable the BDM clocking.  This also turns off most of the rest of
 239         * the BDM device.  This is good for EMC reasons. This option is not
 240         * incompatible with the memory protection option.
 241         */
 242        wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
 243#endif
 244}
 245
 246/***************************************************************************/
 247/* Board initialization */
 248/***************************************************************************/
 249/* 
 250 * PLL min/max specifications
 251 */
 252#define MAX_FVCO        500000  /* KHz */
 253#define MAX_FSYS        80000   /* KHz */
 254#define MIN_FSYS        58333   /* KHz */
 255#define FREF            16000   /* KHz */
 256
 257
 258#define MAX_MFD         135     /* Multiplier */
 259#define MIN_MFD         88      /* Multiplier */
 260#define BUSDIV          6       /* Divider */
 261
 262/*
 263 * Low Power Divider specifications
 264 */
 265#define MIN_LPD         (1 << 0)    /* Divider (not encoded) */
 266#define MAX_LPD         (1 << 15)   /* Divider (not encoded) */
 267#define DEFAULT_LPD     (1 << 1)        /* Divider (not encoded) */
 268
 269#define SYS_CLK_KHZ     80000
 270#define SYSTEM_PERIOD   12.5
 271/*
 272 *  SDRAM Timing Parameters
 273 */  
 274#define SDRAM_BL        8       /* # of beats in a burst */
 275#define SDRAM_TWR       2       /* in clocks */
 276#define SDRAM_CASL      2.5     /* CASL in clocks */
 277#define SDRAM_TRCD      2       /* in clocks */
 278#define SDRAM_TRP       2       /* in clocks */
 279#define SDRAM_TRFC      7       /* in clocks */
 280#define SDRAM_TREFI     7800    /* in ns */
 281
 282#define EXT_SRAM_ADDRESS        (0xC0000000)
 283#define FLASH_ADDRESS           (0x00000000)
 284#define SDRAM_ADDRESS           (0x40000000)
 285
 286#define NAND_FLASH_ADDRESS      (0xD0000000)
 287
 288void wtm_init(void);
 289void scm_init(void);
 290void gpio_init(void);
 291void fbcs_init(void);
 292void sdramc_init(void);
 293int  clock_pll (int fsys, int flags);
 294int  clock_limp (int);
 295int  clock_exit_limp (void);
 296int  get_sys_clock (void);
 297
 298asmlinkage void __init sysinit(void)
 299{
 300        clock_pll(0, 0);
 301
 302        wtm_init();
 303        scm_init();
 304        gpio_init();
 305        fbcs_init();
 306        sdramc_init();
 307}
 308
 309void wtm_init(void)
 310{
 311        /* Disable watchdog timer */
 312        writew(0, MCF_WTM_WCR);
 313}
 314
 315#define MCF_SCM_BCR_GBW         (0x00000100)
 316#define MCF_SCM_BCR_GBR         (0x00000200)
 317
 318void scm_init(void)
 319{
 320        /* All masters are trusted */
 321        writel(0x77777777, MCF_SCM_MPR);
 322    
 323        /* Allow supervisor/user, read/write, and trusted/untrusted
 324           access to all slaves */
 325        writel(0, MCF_SCM_PACRA);
 326        writel(0, MCF_SCM_PACRB);
 327        writel(0, MCF_SCM_PACRC);
 328        writel(0, MCF_SCM_PACRD);
 329        writel(0, MCF_SCM_PACRE);
 330        writel(0, MCF_SCM_PACRF);
 331
 332        /* Enable bursts */
 333        writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
 334}
 335
 336
 337void fbcs_init(void)
 338{
 339        writeb(0x3E, MCFGPIO_PAR_CS);
 340
 341        /* Latch chip select */
 342        writel(0x10080000, MCF_FBCS1_CSAR);
 343
 344        writel(0x002A3780, MCF_FBCS1_CSCR);
 345        writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
 346
 347        /* Initialize latch to drive signals to inactive states */
 348        writew(0xffff, 0x10080000);
 349
 350        /* External SRAM */
 351        writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
 352        writel(MCF_FBCS_CSCR_PS_16 |
 353                MCF_FBCS_CSCR_AA |
 354                MCF_FBCS_CSCR_SBM |
 355                MCF_FBCS_CSCR_WS(1),
 356                MCF_FBCS1_CSCR);
 357        writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
 358
 359        /* Boot Flash connected to FBCS0 */
 360        writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
 361        writel(MCF_FBCS_CSCR_PS_16 |
 362                MCF_FBCS_CSCR_BEM |
 363                MCF_FBCS_CSCR_AA |
 364                MCF_FBCS_CSCR_SBM |
 365                MCF_FBCS_CSCR_WS(7),
 366                MCF_FBCS0_CSCR);
 367        writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
 368}
 369
 370void sdramc_init(void)
 371{
 372        /*
 373         * Check to see if the SDRAM has already been initialized
 374         * by a run control tool
 375         */
 376        if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
 377                /* SDRAM chip select initialization */
 378                
 379                /* Initialize SDRAM chip select */
 380                writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
 381                        MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
 382                        MCF_SDRAMC_SDCS0);
 383
 384        /*
 385         * Basic configuration and initialization
 386         */
 387        writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
 388                MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
 389                MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
 390                MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
 391                MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
 392                MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
 393                MCF_SDRAMC_SDCFG1_WTLAT(3),
 394                MCF_SDRAMC_SDCFG1);
 395        writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
 396                MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
 397                MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
 398                MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
 399                MCF_SDRAMC_SDCFG2);
 400
 401            
 402        /*
 403         * Precharge and enable write to SDMR
 404         */
 405        writel(MCF_SDRAMC_SDCR_MODE_EN |
 406                MCF_SDRAMC_SDCR_CKE |
 407                MCF_SDRAMC_SDCR_DDR |
 408                MCF_SDRAMC_SDCR_MUX(1) |
 409                MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
 410                MCF_SDRAMC_SDCR_PS_16 |
 411                MCF_SDRAMC_SDCR_IPALL,
 412                MCF_SDRAMC_SDCR);
 413
 414        /*
 415         * Write extended mode register
 416         */
 417        writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
 418                MCF_SDRAMC_SDMR_AD(0x0) |
 419                MCF_SDRAMC_SDMR_CMD,
 420                MCF_SDRAMC_SDMR);
 421
 422        /*
 423         * Write mode register and reset DLL
 424         */
 425        writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
 426                MCF_SDRAMC_SDMR_AD(0x163) |
 427                MCF_SDRAMC_SDMR_CMD,
 428                MCF_SDRAMC_SDMR);
 429
 430        /*
 431         * Execute a PALL command
 432         */
 433        writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
 434
 435        /*
 436         * Perform two REF cycles
 437         */
 438        writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
 439        writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
 440
 441        /*
 442         * Write mode register and clear reset DLL
 443         */
 444        writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
 445                MCF_SDRAMC_SDMR_AD(0x063) |
 446                MCF_SDRAMC_SDMR_CMD,
 447                MCF_SDRAMC_SDMR);
 448                                
 449        /*
 450         * Enable auto refresh and lock SDMR
 451         */
 452        writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
 453                MCF_SDRAMC_SDCR);
 454        writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
 455                MCF_SDRAMC_SDCR);
 456        }
 457}
 458
 459void gpio_init(void)
 460{
 461        /* Enable UART0 pins */
 462        writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
 463                MCFGPIO_PAR_UART);
 464
 465        /*
 466         * Initialize TIN3 as a GPIO output to enable the write
 467         * half of the latch.
 468         */
 469        writeb(0x00, MCFGPIO_PAR_TIMER);
 470        writeb(0x08, MCFGPIO_PDDR_TIMER);
 471        writeb(0x00, MCFGPIO_PCLRR_TIMER);
 472}
 473
 474int clock_pll(int fsys, int flags)
 475{
 476        int fref, temp, fout, mfd;
 477        u32 i;
 478
 479        fref = FREF;
 480        
 481        if (fsys == 0) {
 482                /* Return current PLL output */
 483                mfd = readb(MCF_PLL_PFDR);
 484
 485                return (fref * mfd / (BUSDIV * 4));
 486        }
 487
 488        /* Check bounds of requested system clock */
 489        if (fsys > MAX_FSYS)
 490                fsys = MAX_FSYS;
 491        if (fsys < MIN_FSYS)
 492                fsys = MIN_FSYS;
 493
 494        /* Multiplying by 100 when calculating the temp value,
 495           and then dividing by 100 to calculate the mfd allows
 496           for exact values without needing to include floating
 497           point libraries. */
 498        temp = 100 * fsys / fref;
 499        mfd = 4 * BUSDIV * temp / 100;
 500                        
 501        /* Determine the output frequency for selected values */
 502        fout = (fref * mfd / (BUSDIV * 4));
 503
 504        /*
 505         * Check to see if the SDRAM has already been initialized.
 506         * If it has then the SDRAM needs to be put into self refresh
 507         * mode before reprogramming the PLL.
 508         */
 509        if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
 510                /* Put SDRAM into self refresh mode */
 511                writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
 512                        MCF_SDRAMC_SDCR);
 513
 514        /*
 515         * Initialize the PLL to generate the new system clock frequency.
 516         * The device must be put into LIMP mode to reprogram the PLL.
 517         */
 518
 519        /* Enter LIMP mode */
 520        clock_limp(DEFAULT_LPD);
 521                                        
 522        /* Reprogram PLL for desired fsys */
 523        writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
 524                MCF_PLL_PODR);
 525                                                
 526        writeb(mfd, MCF_PLL_PFDR);
 527                
 528        /* Exit LIMP mode */
 529        clock_exit_limp();
 530        
 531        /*
 532         * Return the SDRAM to normal operation if it is in use.
 533         */
 534        if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
 535                /* Exit self refresh mode */
 536                writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
 537                        MCF_SDRAMC_SDCR);
 538
 539        /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
 540        writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
 541
 542        /* wait for DQS logic to relock */
 543        for (i = 0; i < 0x200; i++)
 544                ;
 545
 546        return fout;
 547}
 548
 549int clock_limp(int div)
 550{
 551        u32 temp;
 552
 553        /* Check bounds of divider */
 554        if (div < MIN_LPD)
 555                div = MIN_LPD;
 556        if (div > MAX_LPD)
 557                div = MAX_LPD;
 558    
 559        /* Save of the current value of the SSIDIV so we don't
 560           overwrite the value*/
 561        temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
 562      
 563        /* Apply the divider to the system clock */
 564        writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
 565    
 566        writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
 567    
 568        return (FREF/(3*(1 << div)));
 569}
 570
 571int clock_exit_limp(void)
 572{
 573        int fout;
 574        
 575        /* Exit LIMP mode */
 576        writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
 577
 578        /* Wait for PLL to lock */
 579        while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
 580                ;
 581        
 582        fout = get_sys_clock();
 583
 584        return fout;
 585}
 586
 587int get_sys_clock(void)
 588{
 589        int divider;
 590        
 591        /* Test to see if device is in LIMP mode */
 592        if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
 593                divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
 594                return (FREF/(2 << divider));
 595        }
 596        else
 597                return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
 598}
 599