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 int sys_clk_khz = 0; 275 int sys_clk_mhz = 0; 276 277 void wtm_init(void); 278 void scm_init(void); 279 void gpio_init(void); 280 void fbcs_init(void); 281 void sdramc_init(void); 282 int clock_pll (int fsys, int flags); 283 int clock_limp (int); 284 int clock_exit_limp (void); 285 int get_sys_clock (void); 286 287 asmlinkage void __init sysinit(void) 288 { 289 sys_clk_khz = clock_pll(0, 0); 290 sys_clk_mhz = sys_clk_khz/1000; 291 292 wtm_init(); 293 scm_init(); 294 gpio_init(); 295 fbcs_init(); 296 sdramc_init(); 297 } 298 299 void wtm_init(void) 300 { 301 /* Disable watchdog timer */ 302 writew(0, MCF_WTM_WCR); 303 } 304 305 #define MCF_SCM_BCR_GBW (0x00000100) 306 #define MCF_SCM_BCR_GBR (0x00000200) 307 308 void scm_init(void) 309 { 310 /* All masters are trusted */ 311 writel(0x77777777, MCF_SCM_MPR); 312 313 /* Allow supervisor/user, read/write, and trusted/untrusted 314 access to all slaves */ 315 writel(0, MCF_SCM_PACRA); 316 writel(0, MCF_SCM_PACRB); 317 writel(0, MCF_SCM_PACRC); 318 writel(0, MCF_SCM_PACRD); 319 writel(0, MCF_SCM_PACRE); 320 writel(0, MCF_SCM_PACRF); 321 322 /* Enable bursts */ 323 writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR); 324 } 325 326 327 void fbcs_init(void) 328 { 329 writeb(0x3E, MCFGPIO_PAR_CS); 330 331 /* Latch chip select */ 332 writel(0x10080000, MCF_FBCS1_CSAR); 333 334 writel(0x002A3780, MCF_FBCS1_CSCR); 335 writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR); 336 337 /* Initialize latch to drive signals to inactive states */ 338 writew(0xffff, 0x10080000); 339 340 /* External SRAM */ 341 writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR); 342 writel(MCF_FBCS_CSCR_PS_16 | 343 MCF_FBCS_CSCR_AA | 344 MCF_FBCS_CSCR_SBM | 345 MCF_FBCS_CSCR_WS(1), 346 MCF_FBCS1_CSCR); 347 writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR); 348 349 /* Boot Flash connected to FBCS0 */ 350 writel(FLASH_ADDRESS, MCF_FBCS0_CSAR); 351 writel(MCF_FBCS_CSCR_PS_16 | 352 MCF_FBCS_CSCR_BEM | 353 MCF_FBCS_CSCR_AA | 354 MCF_FBCS_CSCR_SBM | 355 MCF_FBCS_CSCR_WS(7), 356 MCF_FBCS0_CSCR); 357 writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR); 358 } 359 360 void sdramc_init(void) 361 { 362 /* 363 * Check to see if the SDRAM has already been initialized 364 * by a run control tool 365 */ 366 if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) { 367 /* SDRAM chip select initialization */ 368 369 /* Initialize SDRAM chip select */ 370 writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) | 371 MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE), 372 MCF_SDRAMC_SDCS0); 373 374 /* 375 * Basic configuration and initialization 376 */ 377 writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) | 378 MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) | 379 MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) | 380 MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) | 381 MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) | 382 MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) | 383 MCF_SDRAMC_SDCFG1_WTLAT(3), 384 MCF_SDRAMC_SDCFG1); 385 writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) | 386 MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) | 387 MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) | 388 MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1), 389 MCF_SDRAMC_SDCFG2); 390 391 392 /* 393 * Precharge and enable write to SDMR 394 */ 395 writel(MCF_SDRAMC_SDCR_MODE_EN | 396 MCF_SDRAMC_SDCR_CKE | 397 MCF_SDRAMC_SDCR_DDR | 398 MCF_SDRAMC_SDCR_MUX(1) | 399 MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) | 400 MCF_SDRAMC_SDCR_PS_16 | 401 MCF_SDRAMC_SDCR_IPALL, 402 MCF_SDRAMC_SDCR); 403 404 /* 405 * Write extended mode register 406 */ 407 writel(MCF_SDRAMC_SDMR_BNKAD_LEMR | 408 MCF_SDRAMC_SDMR_AD(0x0) | 409 MCF_SDRAMC_SDMR_CMD, 410 MCF_SDRAMC_SDMR); 411 412 /* 413 * Write mode register and reset DLL 414 */ 415 writel(MCF_SDRAMC_SDMR_BNKAD_LMR | 416 MCF_SDRAMC_SDMR_AD(0x163) | 417 MCF_SDRAMC_SDMR_CMD, 418 MCF_SDRAMC_SDMR); 419 420 /* 421 * Execute a PALL command 422 */ 423 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR); 424 425 /* 426 * Perform two REF cycles 427 */ 428 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR); 429 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR); 430 431 /* 432 * Write mode register and clear reset DLL 433 */ 434 writel(MCF_SDRAMC_SDMR_BNKAD_LMR | 435 MCF_SDRAMC_SDMR_AD(0x063) | 436 MCF_SDRAMC_SDMR_CMD, 437 MCF_SDRAMC_SDMR); 438 439 /* 440 * Enable auto refresh and lock SDMR 441 */ 442 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN, 443 MCF_SDRAMC_SDCR); 444 writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC), 445 MCF_SDRAMC_SDCR); 446 } 447 } 448 449 void gpio_init(void) 450 { 451 /* Enable UART0 pins */ 452 writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0, 453 MCFGPIO_PAR_UART); 454 455 /* 456 * Initialize TIN3 as a GPIO output to enable the write 457 * half of the latch. 458 */ 459 writeb(0x00, MCFGPIO_PAR_TIMER); 460 writeb(0x08, MCFGPIO_PDDR_TIMER); 461 writeb(0x00, MCFGPIO_PCLRR_TIMER); 462 } 463 464 int clock_pll(int fsys, int flags) 465 { 466 int fref, temp, fout, mfd; 467 u32 i; 468 469 fref = FREF; 470 471 if (fsys == 0) { 472 /* Return current PLL output */ 473 mfd = readb(MCF_PLL_PFDR); 474 475 return (fref * mfd / (BUSDIV * 4)); 476 } 477 478 /* Check bounds of requested system clock */ 479 if (fsys > MAX_FSYS) 480 fsys = MAX_FSYS; 481 if (fsys < MIN_FSYS) 482 fsys = MIN_FSYS; 483 484 /* Multiplying by 100 when calculating the temp value, 485 and then dividing by 100 to calculate the mfd allows 486 for exact values without needing to include floating 487 point libraries. */ 488 temp = 100 * fsys / fref; 489 mfd = 4 * BUSDIV * temp / 100; 490 491 /* Determine the output frequency for selected values */ 492 fout = (fref * mfd / (BUSDIV * 4)); 493 494 /* 495 * Check to see if the SDRAM has already been initialized. 496 * If it has then the SDRAM needs to be put into self refresh 497 * mode before reprogramming the PLL. 498 */ 499 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF) 500 /* Put SDRAM into self refresh mode */ 501 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE, 502 MCF_SDRAMC_SDCR); 503 504 /* 505 * Initialize the PLL to generate the new system clock frequency. 506 * The device must be put into LIMP mode to reprogram the PLL. 507 */ 508 509 /* Enter LIMP mode */ 510 clock_limp(DEFAULT_LPD); 511 512 /* Reprogram PLL for desired fsys */ 513 writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV), 514 MCF_PLL_PODR); 515 516 writeb(mfd, MCF_PLL_PFDR); 517 518 /* Exit LIMP mode */ 519 clock_exit_limp(); 520 521 /* 522 * Return the SDRAM to normal operation if it is in use. 523 */ 524 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF) 525 /* Exit self refresh mode */ 526 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE, 527 MCF_SDRAMC_SDCR); 528 529 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */ 530 writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX); 531 532 /* wait for DQS logic to relock */ 533 for (i = 0; i < 0x200; i++) 534 ; 535 536 return fout; 537 } 538 539 int clock_limp(int div) 540 { 541 u32 temp; 542 543 /* Check bounds of divider */ 544 if (div < MIN_LPD) 545 div = MIN_LPD; 546 if (div > MAX_LPD) 547 div = MAX_LPD; 548 549 /* Save of the current value of the SSIDIV so we don't 550 overwrite the value*/ 551 temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF); 552 553 /* Apply the divider to the system clock */ 554 writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR); 555 556 writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR); 557 558 return (FREF/(3*(1 << div))); 559 } 560 561 int clock_exit_limp(void) 562 { 563 int fout; 564 565 /* Exit LIMP mode */ 566 writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR); 567 568 /* Wait for PLL to lock */ 569 while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK)) 570 ; 571 572 fout = get_sys_clock(); 573 574 return fout; 575 } 576 577 int get_sys_clock(void) 578 { 579 int divider; 580 581 /* Test to see if device is in LIMP mode */ 582 if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) { 583 divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF); 584 return (FREF/(2 << divider)); 585 } 586 else 587 return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4); 588 } 589