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