1 /* 2 * (C) Copyright 2000-2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. 6 * 7 * See file CREDITS for list of people who contributed to this 8 * project. 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of 13 * the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 * MA 02111-1307 USA 24 */ 25 26 #include <common.h> 27 #include <mpc83xx.h> 28 #include <command.h> 29 #include <asm/processor.h> 30 31 DECLARE_GLOBAL_DATA_PTR; 32 33 /* ----------------------------------------------------------------- */ 34 35 typedef enum { 36 _unk, 37 _off, 38 _byp, 39 _x8, 40 _x4, 41 _x2, 42 _x1, 43 _1x, 44 _1_5x, 45 _2x, 46 _2_5x, 47 _3x 48 } mult_t; 49 50 typedef struct { 51 mult_t core_csb_ratio; 52 mult_t vco_divider; 53 } corecnf_t; 54 55 corecnf_t corecnf_tab[] = { 56 {_byp, _byp}, /* 0x00 */ 57 {_byp, _byp}, /* 0x01 */ 58 {_byp, _byp}, /* 0x02 */ 59 {_byp, _byp}, /* 0x03 */ 60 {_byp, _byp}, /* 0x04 */ 61 {_byp, _byp}, /* 0x05 */ 62 {_byp, _byp}, /* 0x06 */ 63 {_byp, _byp}, /* 0x07 */ 64 {_1x, _x2}, /* 0x08 */ 65 {_1x, _x4}, /* 0x09 */ 66 {_1x, _x8}, /* 0x0A */ 67 {_1x, _x8}, /* 0x0B */ 68 {_1_5x, _x2}, /* 0x0C */ 69 {_1_5x, _x4}, /* 0x0D */ 70 {_1_5x, _x8}, /* 0x0E */ 71 {_1_5x, _x8}, /* 0x0F */ 72 {_2x, _x2}, /* 0x10 */ 73 {_2x, _x4}, /* 0x11 */ 74 {_2x, _x8}, /* 0x12 */ 75 {_2x, _x8}, /* 0x13 */ 76 {_2_5x, _x2}, /* 0x14 */ 77 {_2_5x, _x4}, /* 0x15 */ 78 {_2_5x, _x8}, /* 0x16 */ 79 {_2_5x, _x8}, /* 0x17 */ 80 {_3x, _x2}, /* 0x18 */ 81 {_3x, _x4}, /* 0x19 */ 82 {_3x, _x8}, /* 0x1A */ 83 {_3x, _x8}, /* 0x1B */ 84 }; 85 86 /* ----------------------------------------------------------------- */ 87 88 /* 89 * 90 */ 91 int get_clocks(void) 92 { 93 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; 94 u32 pci_sync_in; 95 u8 spmf; 96 u8 clkin_div; 97 u32 sccr; 98 u32 corecnf_tab_index; 99 u8 corepll; 100 u32 lcrr; 101 102 u32 csb_clk; 103 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ 104 defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) 105 u32 tsec1_clk; 106 u32 tsec2_clk; 107 u32 usbdr_clk; 108 #elif defined(CONFIG_MPC8309) 109 u32 usbdr_clk; 110 #endif 111 #ifdef CONFIG_MPC834x 112 u32 usbmph_clk; 113 #endif 114 u32 core_clk; 115 u32 i2c1_clk; 116 #if !defined(CONFIG_MPC832x) 117 u32 i2c2_clk; 118 #endif 119 #if defined(CONFIG_MPC8315) 120 u32 tdm_clk; 121 #endif 122 #if defined(CONFIG_FSL_ESDHC) 123 u32 sdhc_clk; 124 #endif 125 #if !defined(CONFIG_MPC8309) 126 u32 enc_clk; 127 #endif 128 u32 lbiu_clk; 129 u32 lclk_clk; 130 u32 mem_clk; 131 #if defined(CONFIG_MPC8360) 132 u32 mem_sec_clk; 133 #endif 134 #if defined(CONFIG_QE) 135 u32 qepmf; 136 u32 qepdf; 137 u32 qe_clk; 138 u32 brg_clk; 139 #endif 140 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ 141 defined(CONFIG_MPC837x) 142 u32 pciexp1_clk; 143 u32 pciexp2_clk; 144 #endif 145 #if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) 146 u32 sata_clk; 147 #endif 148 149 if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im) 150 return -1; 151 152 clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT); 153 154 if (im->reset.rcwh & HRCWH_PCI_HOST) { 155 #if defined(CONFIG_83XX_CLKIN) 156 pci_sync_in = CONFIG_83XX_CLKIN / (1 + clkin_div); 157 #else 158 pci_sync_in = 0xDEADBEEF; 159 #endif 160 } else { 161 #if defined(CONFIG_83XX_PCICLK) 162 pci_sync_in = CONFIG_83XX_PCICLK; 163 #else 164 pci_sync_in = 0xDEADBEEF; 165 #endif 166 } 167 168 spmf = (im->clk.spmr & SPMR_SPMF) >> SPMR_SPMF_SHIFT; 169 csb_clk = pci_sync_in * (1 + clkin_div) * spmf; 170 171 sccr = im->clk.sccr; 172 173 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ 174 defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) 175 switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) { 176 case 0: 177 tsec1_clk = 0; 178 break; 179 case 1: 180 tsec1_clk = csb_clk; 181 break; 182 case 2: 183 tsec1_clk = csb_clk / 2; 184 break; 185 case 3: 186 tsec1_clk = csb_clk / 3; 187 break; 188 default: 189 /* unkown SCCR_TSEC1CM value */ 190 return -2; 191 } 192 #endif 193 194 #if defined(CONFIG_MPC830x) || defined(CONFIG_MPC831x) || \ 195 defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) 196 switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) { 197 case 0: 198 usbdr_clk = 0; 199 break; 200 case 1: 201 usbdr_clk = csb_clk; 202 break; 203 case 2: 204 usbdr_clk = csb_clk / 2; 205 break; 206 case 3: 207 usbdr_clk = csb_clk / 3; 208 break; 209 default: 210 /* unkown SCCR_USBDRCM value */ 211 return -3; 212 } 213 #endif 214 215 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC8315) || \ 216 defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) 217 switch ((sccr & SCCR_TSEC2CM) >> SCCR_TSEC2CM_SHIFT) { 218 case 0: 219 tsec2_clk = 0; 220 break; 221 case 1: 222 tsec2_clk = csb_clk; 223 break; 224 case 2: 225 tsec2_clk = csb_clk / 2; 226 break; 227 case 3: 228 tsec2_clk = csb_clk / 3; 229 break; 230 default: 231 /* unkown SCCR_TSEC2CM value */ 232 return -4; 233 } 234 #elif defined(CONFIG_MPC8313) 235 tsec2_clk = tsec1_clk; 236 237 if (!(sccr & SCCR_TSEC1ON)) 238 tsec1_clk = 0; 239 if (!(sccr & SCCR_TSEC2ON)) 240 tsec2_clk = 0; 241 #endif 242 243 #if defined(CONFIG_MPC834x) 244 switch ((sccr & SCCR_USBMPHCM) >> SCCR_USBMPHCM_SHIFT) { 245 case 0: 246 usbmph_clk = 0; 247 break; 248 case 1: 249 usbmph_clk = csb_clk; 250 break; 251 case 2: 252 usbmph_clk = csb_clk / 2; 253 break; 254 case 3: 255 usbmph_clk = csb_clk / 3; 256 break; 257 default: 258 /* unkown SCCR_USBMPHCM value */ 259 return -5; 260 } 261 262 if (usbmph_clk != 0 && usbdr_clk != 0 && usbmph_clk != usbdr_clk) { 263 /* if USB MPH clock is not disabled and 264 * USB DR clock is not disabled then 265 * USB MPH & USB DR must have the same rate 266 */ 267 return -6; 268 } 269 #endif 270 #if !defined(CONFIG_MPC8309) 271 switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) { 272 case 0: 273 enc_clk = 0; 274 break; 275 case 1: 276 enc_clk = csb_clk; 277 break; 278 case 2: 279 enc_clk = csb_clk / 2; 280 break; 281 case 3: 282 enc_clk = csb_clk / 3; 283 break; 284 default: 285 /* unkown SCCR_ENCCM value */ 286 return -7; 287 } 288 #endif 289 290 #if defined(CONFIG_FSL_ESDHC) 291 switch ((sccr & SCCR_SDHCCM) >> SCCR_SDHCCM_SHIFT) { 292 case 0: 293 sdhc_clk = 0; 294 break; 295 case 1: 296 sdhc_clk = csb_clk; 297 break; 298 case 2: 299 sdhc_clk = csb_clk / 2; 300 break; 301 case 3: 302 sdhc_clk = csb_clk / 3; 303 break; 304 default: 305 /* unkown SCCR_SDHCCM value */ 306 return -8; 307 } 308 #endif 309 #if defined(CONFIG_MPC8315) 310 switch ((sccr & SCCR_TDMCM) >> SCCR_TDMCM_SHIFT) { 311 case 0: 312 tdm_clk = 0; 313 break; 314 case 1: 315 tdm_clk = csb_clk; 316 break; 317 case 2: 318 tdm_clk = csb_clk / 2; 319 break; 320 case 3: 321 tdm_clk = csb_clk / 3; 322 break; 323 default: 324 /* unkown SCCR_TDMCM value */ 325 return -8; 326 } 327 #endif 328 329 #if defined(CONFIG_MPC834x) 330 i2c1_clk = tsec2_clk; 331 #elif defined(CONFIG_MPC8360) 332 i2c1_clk = csb_clk; 333 #elif defined(CONFIG_MPC832x) 334 i2c1_clk = enc_clk; 335 #elif defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) 336 i2c1_clk = enc_clk; 337 #elif defined(CONFIG_FSL_ESDHC) 338 i2c1_clk = sdhc_clk; 339 #elif defined(CONFIG_MPC837x) 340 i2c1_clk = enc_clk; 341 #elif defined(CONFIG_MPC8309) 342 i2c1_clk = csb_clk; 343 #endif 344 #if !defined(CONFIG_MPC832x) 345 i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */ 346 #endif 347 348 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ 349 defined(CONFIG_MPC837x) 350 switch ((sccr & SCCR_PCIEXP1CM) >> SCCR_PCIEXP1CM_SHIFT) { 351 case 0: 352 pciexp1_clk = 0; 353 break; 354 case 1: 355 pciexp1_clk = csb_clk; 356 break; 357 case 2: 358 pciexp1_clk = csb_clk / 2; 359 break; 360 case 3: 361 pciexp1_clk = csb_clk / 3; 362 break; 363 default: 364 /* unkown SCCR_PCIEXP1CM value */ 365 return -9; 366 } 367 368 switch ((sccr & SCCR_PCIEXP2CM) >> SCCR_PCIEXP2CM_SHIFT) { 369 case 0: 370 pciexp2_clk = 0; 371 break; 372 case 1: 373 pciexp2_clk = csb_clk; 374 break; 375 case 2: 376 pciexp2_clk = csb_clk / 2; 377 break; 378 case 3: 379 pciexp2_clk = csb_clk / 3; 380 break; 381 default: 382 /* unkown SCCR_PCIEXP2CM value */ 383 return -10; 384 } 385 #endif 386 387 #if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) 388 switch ((sccr & SCCR_SATA1CM) >> SCCR_SATA1CM_SHIFT) { 389 case 0: 390 sata_clk = 0; 391 break; 392 case 1: 393 sata_clk = csb_clk; 394 break; 395 case 2: 396 sata_clk = csb_clk / 2; 397 break; 398 case 3: 399 sata_clk = csb_clk / 3; 400 break; 401 default: 402 /* unkown SCCR_SATACM value */ 403 return -11; 404 } 405 #endif 406 407 lbiu_clk = csb_clk * 408 (1 + ((im->clk.spmr & SPMR_LBIUCM) >> SPMR_LBIUCM_SHIFT)); 409 lcrr = (im->im_lbc.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT; 410 switch (lcrr) { 411 case 2: 412 case 4: 413 case 8: 414 lclk_clk = lbiu_clk / lcrr; 415 break; 416 default: 417 /* unknown lcrr */ 418 return -12; 419 } 420 421 mem_clk = csb_clk * 422 (1 + ((im->clk.spmr & SPMR_DDRCM) >> SPMR_DDRCM_SHIFT)); 423 corepll = (im->clk.spmr & SPMR_COREPLL) >> SPMR_COREPLL_SHIFT; 424 425 #if defined(CONFIG_MPC8360) 426 mem_sec_clk = csb_clk * (1 + 427 ((im->clk.spmr & SPMR_LBIUCM) >> SPMR_LBIUCM_SHIFT)); 428 #endif 429 430 corecnf_tab_index = ((corepll & 0x1F) << 2) | ((corepll & 0x60) >> 5); 431 if (corecnf_tab_index > (sizeof(corecnf_tab) / sizeof(corecnf_t))) { 432 /* corecnf_tab_index is too high, possibly worng value */ 433 return -11; 434 } 435 switch (corecnf_tab[corecnf_tab_index].core_csb_ratio) { 436 case _byp: 437 case _x1: 438 case _1x: 439 core_clk = csb_clk; 440 break; 441 case _1_5x: 442 core_clk = (3 * csb_clk) / 2; 443 break; 444 case _2x: 445 core_clk = 2 * csb_clk; 446 break; 447 case _2_5x: 448 core_clk = (5 * csb_clk) / 2; 449 break; 450 case _3x: 451 core_clk = 3 * csb_clk; 452 break; 453 default: 454 /* unkown core to csb ratio */ 455 return -13; 456 } 457 458 #if defined(CONFIG_QE) 459 qepmf = (im->clk.spmr & SPMR_CEPMF) >> SPMR_CEPMF_SHIFT; 460 qepdf = (im->clk.spmr & SPMR_CEPDF) >> SPMR_CEPDF_SHIFT; 461 qe_clk = (pci_sync_in * qepmf) / (1 + qepdf); 462 brg_clk = qe_clk / 2; 463 #endif 464 465 gd->csb_clk = csb_clk; 466 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ 467 defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) 468 gd->tsec1_clk = tsec1_clk; 469 gd->tsec2_clk = tsec2_clk; 470 gd->usbdr_clk = usbdr_clk; 471 #elif defined(CONFIG_MPC8309) 472 gd->usbdr_clk = usbdr_clk; 473 #endif 474 #if defined(CONFIG_MPC834x) 475 gd->usbmph_clk = usbmph_clk; 476 #endif 477 #if defined(CONFIG_MPC8315) 478 gd->tdm_clk = tdm_clk; 479 #endif 480 #if defined(CONFIG_FSL_ESDHC) 481 gd->sdhc_clk = sdhc_clk; 482 #endif 483 gd->core_clk = core_clk; 484 gd->i2c1_clk = i2c1_clk; 485 #if !defined(CONFIG_MPC832x) 486 gd->i2c2_clk = i2c2_clk; 487 #endif 488 #if !defined(CONFIG_MPC8309) 489 gd->enc_clk = enc_clk; 490 #endif 491 gd->lbiu_clk = lbiu_clk; 492 gd->lclk_clk = lclk_clk; 493 gd->mem_clk = mem_clk; 494 #if defined(CONFIG_MPC8360) 495 gd->mem_sec_clk = mem_sec_clk; 496 #endif 497 #if defined(CONFIG_QE) 498 gd->qe_clk = qe_clk; 499 gd->brg_clk = brg_clk; 500 #endif 501 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ 502 defined(CONFIG_MPC837x) 503 gd->pciexp1_clk = pciexp1_clk; 504 gd->pciexp2_clk = pciexp2_clk; 505 #endif 506 #if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) 507 gd->sata_clk = sata_clk; 508 #endif 509 gd->pci_clk = pci_sync_in; 510 gd->cpu_clk = gd->core_clk; 511 gd->bus_clk = gd->csb_clk; 512 return 0; 513 514 } 515 516 /******************************************** 517 * get_bus_freq 518 * return system bus freq in Hz 519 *********************************************/ 520 ulong get_bus_freq(ulong dummy) 521 { 522 return gd->csb_clk; 523 } 524 525 /******************************************** 526 * get_ddr_freq 527 * return ddr bus freq in Hz 528 *********************************************/ 529 ulong get_ddr_freq(ulong dummy) 530 { 531 return gd->mem_clk; 532 } 533 534 int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 535 { 536 char buf[32]; 537 538 printf("Clock configuration:\n"); 539 printf(" Core: %-4s MHz\n", strmhz(buf, gd->core_clk)); 540 printf(" Coherent System Bus: %-4s MHz\n", strmhz(buf, gd->csb_clk)); 541 #if defined(CONFIG_QE) 542 printf(" QE: %-4s MHz\n", strmhz(buf, gd->qe_clk)); 543 printf(" BRG: %-4s MHz\n", strmhz(buf, gd->brg_clk)); 544 #endif 545 printf(" Local Bus Controller:%-4s MHz\n", strmhz(buf, gd->lbiu_clk)); 546 printf(" Local Bus: %-4s MHz\n", strmhz(buf, gd->lclk_clk)); 547 printf(" DDR: %-4s MHz\n", strmhz(buf, gd->mem_clk)); 548 #if defined(CONFIG_MPC8360) 549 printf(" DDR Secondary: %-4s MHz\n", strmhz(buf, gd->mem_sec_clk)); 550 #endif 551 #if !defined(CONFIG_MPC8309) 552 printf(" SEC: %-4s MHz\n", strmhz(buf, gd->enc_clk)); 553 #endif 554 printf(" I2C1: %-4s MHz\n", strmhz(buf, gd->i2c1_clk)); 555 #if !defined(CONFIG_MPC832x) 556 printf(" I2C2: %-4s MHz\n", strmhz(buf, gd->i2c2_clk)); 557 #endif 558 #if defined(CONFIG_MPC8315) 559 printf(" TDM: %-4s MHz\n", strmhz(buf, gd->tdm_clk)); 560 #endif 561 #if defined(CONFIG_FSL_ESDHC) 562 printf(" SDHC: %-4s MHz\n", strmhz(buf, gd->sdhc_clk)); 563 #endif 564 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ 565 defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) 566 printf(" TSEC1: %-4s MHz\n", strmhz(buf, gd->tsec1_clk)); 567 printf(" TSEC2: %-4s MHz\n", strmhz(buf, gd->tsec2_clk)); 568 printf(" USB DR: %-4s MHz\n", strmhz(buf, gd->usbdr_clk)); 569 #elif defined(CONFIG_MPC8309) 570 printf(" USB DR: %-4s MHz\n", strmhz(buf, gd->usbdr_clk)); 571 #endif 572 #if defined(CONFIG_MPC834x) 573 printf(" USB MPH: %-4s MHz\n", strmhz(buf, gd->usbmph_clk)); 574 #endif 575 #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ 576 defined(CONFIG_MPC837x) 577 printf(" PCIEXP1: %-4s MHz\n", strmhz(buf, gd->pciexp1_clk)); 578 printf(" PCIEXP2: %-4s MHz\n", strmhz(buf, gd->pciexp2_clk)); 579 #endif 580 #if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) 581 printf(" SATA: %-4s MHz\n", strmhz(buf, gd->sata_clk)); 582 #endif 583 return 0; 584 } 585 586 U_BOOT_CMD(clocks, 1, 0, do_clocks, 587 "print clock configuration", 588 " clocks" 589 ); 590