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