uboot/arch/powerpc/cpu/mpc85xx/speed.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2004, 2007-2011 Freescale Semiconductor, Inc.
   4 *
   5 * (C) Copyright 2003 Motorola Inc.
   6 * Xianghua Xiao, (X.Xiao@motorola.com)
   7 *
   8 * (C) Copyright 2000
   9 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  10 */
  11
  12#include <common.h>
  13#include <ppc_asm.tmpl>
  14#include <linux/compiler.h>
  15#include <asm/processor.h>
  16#include <asm/io.h>
  17
  18DECLARE_GLOBAL_DATA_PTR;
  19
  20
  21#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
  22#define CONFIG_SYS_FSL_NUM_CC_PLLS      6
  23#endif
  24/* --------------------------------------------------------------- */
  25
  26void get_sys_info(sys_info_t *sys_info)
  27{
  28        volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  29#ifdef CONFIG_FSL_CORENET
  30        volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR);
  31        unsigned int cpu;
  32#ifdef CONFIG_HETROGENOUS_CLUSTERS
  33        unsigned int dsp_cpu;
  34        uint rcw_tmp1, rcw_tmp2;
  35#endif
  36#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
  37        int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS;
  38#endif
  39        __maybe_unused u32 svr;
  40
  41        const u8 core_cplx_PLL[16] = {
  42                [ 0] = 0,       /* CC1 PPL / 1 */
  43                [ 1] = 0,       /* CC1 PPL / 2 */
  44                [ 2] = 0,       /* CC1 PPL / 4 */
  45                [ 4] = 1,       /* CC2 PPL / 1 */
  46                [ 5] = 1,       /* CC2 PPL / 2 */
  47                [ 6] = 1,       /* CC2 PPL / 4 */
  48                [ 8] = 2,       /* CC3 PPL / 1 */
  49                [ 9] = 2,       /* CC3 PPL / 2 */
  50                [10] = 2,       /* CC3 PPL / 4 */
  51                [12] = 3,       /* CC4 PPL / 1 */
  52                [13] = 3,       /* CC4 PPL / 2 */
  53                [14] = 3,       /* CC4 PPL / 4 */
  54        };
  55
  56        const u8 core_cplx_pll_div[16] = {
  57                [ 0] = 1,       /* CC1 PPL / 1 */
  58                [ 1] = 2,       /* CC1 PPL / 2 */
  59                [ 2] = 4,       /* CC1 PPL / 4 */
  60                [ 4] = 1,       /* CC2 PPL / 1 */
  61                [ 5] = 2,       /* CC2 PPL / 2 */
  62                [ 6] = 4,       /* CC2 PPL / 4 */
  63                [ 8] = 1,       /* CC3 PPL / 1 */
  64                [ 9] = 2,       /* CC3 PPL / 2 */
  65                [10] = 4,       /* CC3 PPL / 4 */
  66                [12] = 1,       /* CC4 PPL / 1 */
  67                [13] = 2,       /* CC4 PPL / 2 */
  68                [14] = 4,       /* CC4 PPL / 4 */
  69        };
  70        uint i, freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
  71#if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV) || \
  72        defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)
  73        uint rcw_tmp;
  74#endif
  75        uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
  76        unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
  77        uint mem_pll_rat;
  78
  79        sys_info->freq_systembus = sysclk;
  80#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
  81        uint ddr_refclk_sel;
  82        unsigned int porsr1_sys_clk;
  83        porsr1_sys_clk = in_be32(&gur->porsr1) >> FSL_DCFG_PORSR1_SYSCLK_SHIFT
  84                                                & FSL_DCFG_PORSR1_SYSCLK_MASK;
  85        if (porsr1_sys_clk == FSL_DCFG_PORSR1_SYSCLK_DIFF)
  86                sys_info->diff_sysclk = 1;
  87        else
  88                sys_info->diff_sysclk = 0;
  89
  90        /*
  91         * DDR_REFCLK_SEL rcw bit is used to determine if DDR PLLS
  92         * are driven by separate DDR Refclock or single source
  93         * differential clock.
  94         */
  95        ddr_refclk_sel = (in_be32(&gur->rcwsr[5]) >>
  96                      FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT) &
  97                      FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK;
  98        /*
  99         * For single source clocking, both ddrclock and sysclock
 100         * are driven by differential sysclock.
 101         */
 102        if (ddr_refclk_sel == FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK)
 103                sys_info->freq_ddrbus = CONFIG_SYS_CLK_FREQ;
 104        else
 105#endif
 106#ifdef CONFIG_DDR_CLK_FREQ
 107                sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
 108#else
 109                sys_info->freq_ddrbus = sysclk;
 110#endif
 111
 112        sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f;
 113        mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
 114                        FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT)
 115                        & FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
 116#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
 117        if (mem_pll_rat == 0) {
 118                mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
 119                        FSL_CORENET_RCWSR0_MEM_PLL_RAT_RESV_SHIFT) &
 120                        FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
 121        }
 122#endif
 123        /* T4240/T4160 Rev2.0 MEM_PLL_RAT uses a value which is half of
 124         * T4240/T4160 Rev1.0. eg. It's 12 in Rev1.0, however, for Rev2.0
 125         * it uses 6.
 126         * T2080 rev 1.1 and later also use half mem_pll comparing with rev 1.0
 127         */
 128#if defined(CONFIG_ARCH_T4240) || defined(CONFIG_ARCH_T4160) || \
 129        defined(CONFIG_ARCH_T2080) || defined(CONFIG_ARCH_T2081)
 130        svr = get_svr();
 131        switch (SVR_SOC_VER(svr)) {
 132        case SVR_T4240:
 133        case SVR_T4160:
 134        case SVR_T4120:
 135        case SVR_T4080:
 136                if (SVR_MAJ(svr) >= 2)
 137                        mem_pll_rat *= 2;
 138                break;
 139        case SVR_T2080:
 140        case SVR_T2081:
 141                if ((SVR_MAJ(svr) > 1) || (SVR_MIN(svr) >= 1))
 142                        mem_pll_rat *= 2;
 143                break;
 144        default:
 145                break;
 146        }
 147#endif
 148        if (mem_pll_rat > 2)
 149                sys_info->freq_ddrbus *= mem_pll_rat;
 150        else
 151                sys_info->freq_ddrbus = sys_info->freq_systembus * mem_pll_rat;
 152
 153        for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
 154                ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f;
 155                if (ratio[i] > 4)
 156                        freq_c_pll[i] = sysclk * ratio[i];
 157                else
 158                        freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
 159        }
 160
 161#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
 162        /*
 163         * As per CHASSIS2 architeture total 12 clusters are posible and
 164         * Each cluster has up to 4 cores, sharing the same PLL selection.
 165         * The cluster clock assignment is SoC defined.
 166         *
 167         * Total 4 clock groups are possible with 3 PLLs each.
 168         * as per array indices, clock group A has 0, 1, 2 numbered PLLs &
 169         * clock group B has 3, 4, 6 and so on.
 170         *
 171         * Clock group A having PLL1, PLL2, PLL3, feeding cores of any cluster
 172         * depends upon the SoC architeture. Same applies to other
 173         * clock groups and clusters.
 174         *
 175         */
 176        for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
 177                int cluster = fsl_qoriq_core_to_cluster(cpu);
 178                u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
 179                                & 0xf;
 180                u32 cplx_pll = core_cplx_PLL[c_pll_sel];
 181                cplx_pll += cc_group[cluster] - 1;
 182                sys_info->freq_processor[cpu] =
 183                         freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
 184        }
 185
 186#ifdef CONFIG_HETROGENOUS_CLUSTERS
 187        for_each_cpu(i, dsp_cpu, cpu_num_dspcores(), cpu_dsp_mask()) {
 188                int dsp_cluster = fsl_qoriq_dsp_core_to_cluster(dsp_cpu);
 189                u32 c_pll_sel = (in_be32
 190                                (&clk->clkcsr[dsp_cluster].clkcncsr) >> 27)
 191                                & 0xf;
 192                u32 cplx_pll = core_cplx_PLL[c_pll_sel];
 193                cplx_pll += cc_group[dsp_cluster] - 1;
 194                sys_info->freq_processor_dsp[dsp_cpu] =
 195                         freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
 196        }
 197#endif
 198
 199#if defined(CONFIG_ARCH_B4860) || defined(CONFIG_ARCH_B4420) || \
 200        defined(CONFIG_ARCH_T2080) || defined(CONFIG_ARCH_T2081)
 201#define FM1_CLK_SEL     0xe0000000
 202#define FM1_CLK_SHIFT   29
 203#elif defined(CONFIG_ARCH_T1024) || defined(CONFIG_ARCH_T1023)
 204#define FM1_CLK_SEL     0x00000007
 205#define FM1_CLK_SHIFT   0
 206#else
 207#define PME_CLK_SEL     0xe0000000
 208#define PME_CLK_SHIFT   29
 209#define FM1_CLK_SEL     0x1c000000
 210#define FM1_CLK_SHIFT   26
 211#endif
 212#if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV)
 213#if defined(CONFIG_ARCH_T1024) || defined(CONFIG_ARCH_T1023)
 214        rcw_tmp = in_be32(&gur->rcwsr[15]) - 4;
 215#else
 216        rcw_tmp = in_be32(&gur->rcwsr[7]);
 217#endif
 218#endif
 219
 220#ifdef CONFIG_SYS_DPAA_PME
 221#ifndef CONFIG_PME_PLAT_CLK_DIV
 222        switch ((rcw_tmp & PME_CLK_SEL) >> PME_CLK_SHIFT) {
 223        case 1:
 224                sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK];
 225                break;
 226        case 2:
 227                sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 2;
 228                break;
 229        case 3:
 230                sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 3;
 231                break;
 232        case 4:
 233                sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 4;
 234                break;
 235        case 6:
 236                sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK + 1] / 2;
 237                break;
 238        case 7:
 239                sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK + 1] / 3;
 240                break;
 241        default:
 242                printf("Error: Unknown PME clock select!\n");
 243        case 0:
 244                sys_info->freq_pme = sys_info->freq_systembus / 2;
 245                break;
 246
 247        }
 248#else
 249        sys_info->freq_pme = sys_info->freq_systembus / CONFIG_SYS_PME_CLK;
 250
 251#endif
 252#endif
 253
 254#ifdef CONFIG_SYS_DPAA_QBMAN
 255#ifndef CONFIG_QBMAN_CLK_DIV
 256#define CONFIG_QBMAN_CLK_DIV    2
 257#endif
 258        sys_info->freq_qman = sys_info->freq_systembus / CONFIG_QBMAN_CLK_DIV;
 259#endif
 260
 261#if defined(CONFIG_SYS_MAPLE)
 262#define CPRI_CLK_SEL            0x1C000000
 263#define CPRI_CLK_SHIFT          26
 264#define CPRI_ALT_CLK_SEL        0x00007000
 265#define CPRI_ALT_CLK_SHIFT      12
 266
 267        rcw_tmp1 = in_be32(&gur->rcwsr[7]);     /* Reading RCW bits: 224-255*/
 268        rcw_tmp2 = in_be32(&gur->rcwsr[15]);    /* Reading RCW bits: 480-511*/
 269        /* For MAPLE and CPRI frequency */
 270        switch ((rcw_tmp1 & CPRI_CLK_SEL) >> CPRI_CLK_SHIFT) {
 271        case 1:
 272                sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK];
 273                sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK];
 274                break;
 275        case 2:
 276                sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
 277                sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
 278                break;
 279        case 3:
 280                sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
 281                sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
 282                break;
 283        case 4:
 284                sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
 285                sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
 286                break;
 287        case 5:
 288                if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
 289                                        >> CPRI_ALT_CLK_SHIFT) == 6) {
 290                        sys_info->freq_maple =
 291                                freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
 292                        sys_info->freq_cpri =
 293                                freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
 294                }
 295                if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
 296                                        >> CPRI_ALT_CLK_SHIFT) == 7) {
 297                        sys_info->freq_maple =
 298                                freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
 299                        sys_info->freq_cpri =
 300                                freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
 301                }
 302                break;
 303        case 6:
 304                sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
 305                sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
 306                break;
 307        case 7:
 308                sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
 309                sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
 310                break;
 311        default:
 312                printf("Error: Unknown MAPLE/CPRI clock select!\n");
 313        }
 314
 315        /* For MAPLE ULB and eTVPE frequencies */
 316#define ULB_CLK_SEL             0x00000038
 317#define ULB_CLK_SHIFT           3
 318#define ETVPE_CLK_SEL           0x00000007
 319#define ETVPE_CLK_SHIFT         0
 320
 321        switch ((rcw_tmp2 & ULB_CLK_SEL) >> ULB_CLK_SHIFT) {
 322        case 1:
 323                sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK];
 324                break;
 325        case 2:
 326                sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 2;
 327                break;
 328        case 3:
 329                sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 3;
 330                break;
 331        case 4:
 332                sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 4;
 333                break;
 334        case 5:
 335                sys_info->freq_maple_ulb = sys_info->freq_systembus;
 336                break;
 337        case 6:
 338                sys_info->freq_maple_ulb =
 339                        freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 2;
 340                break;
 341        case 7:
 342                sys_info->freq_maple_ulb =
 343                        freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 3;
 344                break;
 345        default:
 346                printf("Error: Unknown MAPLE ULB clock select!\n");
 347        }
 348
 349        switch ((rcw_tmp2 & ETVPE_CLK_SEL) >> ETVPE_CLK_SHIFT) {
 350        case 1:
 351                sys_info->freq_maple_etvpe = freq_c_pll[CONFIG_SYS_ETVPE_CLK];
 352                break;
 353        case 2:
 354                sys_info->freq_maple_etvpe =
 355                        freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 2;
 356                break;
 357        case 3:
 358                sys_info->freq_maple_etvpe =
 359                        freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 3;
 360                break;
 361        case 4:
 362                sys_info->freq_maple_etvpe =
 363                        freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 4;
 364                break;
 365        case 5:
 366                sys_info->freq_maple_etvpe = sys_info->freq_systembus;
 367                break;
 368        case 6:
 369                sys_info->freq_maple_etvpe =
 370                        freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 2;
 371                break;
 372        case 7:
 373                sys_info->freq_maple_etvpe =
 374                        freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 3;
 375                break;
 376        default:
 377                printf("Error: Unknown MAPLE eTVPE clock select!\n");
 378        }
 379
 380#endif
 381
 382#ifdef CONFIG_SYS_DPAA_FMAN
 383#ifndef CONFIG_FM_PLAT_CLK_DIV
 384        switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) {
 385        case 1:
 386                sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK];
 387                break;
 388        case 2:
 389                sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 2;
 390                break;
 391        case 3:
 392                sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 3;
 393                break;
 394        case 4:
 395                sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 4;
 396                break;
 397        case 5:
 398                sys_info->freq_fman[0] = sys_info->freq_systembus;
 399                break;
 400        case 6:
 401                sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK + 1] / 2;
 402                break;
 403        case 7:
 404                sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK + 1] / 3;
 405                break;
 406        default:
 407                printf("Error: Unknown FMan1 clock select!\n");
 408        case 0:
 409                sys_info->freq_fman[0] = sys_info->freq_systembus / 2;
 410                break;
 411        }
 412#if (CONFIG_SYS_NUM_FMAN) == 2
 413#ifdef CONFIG_SYS_FM2_CLK
 414#define FM2_CLK_SEL     0x00000038
 415#define FM2_CLK_SHIFT   3
 416        rcw_tmp = in_be32(&gur->rcwsr[15]);
 417        switch ((rcw_tmp & FM2_CLK_SEL) >> FM2_CLK_SHIFT) {
 418        case 1:
 419                sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1];
 420                break;
 421        case 2:
 422                sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 2;
 423                break;
 424        case 3:
 425                sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 3;
 426                break;
 427        case 4:
 428                sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 4;
 429                break;
 430        case 5:
 431                sys_info->freq_fman[1] = sys_info->freq_systembus;
 432                break;
 433        case 6:
 434                sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 2;
 435                break;
 436        case 7:
 437                sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 3;
 438                break;
 439        default:
 440                printf("Error: Unknown FMan2 clock select!\n");
 441        case 0:
 442                sys_info->freq_fman[1] = sys_info->freq_systembus / 2;
 443                break;
 444        }
 445#endif
 446#endif  /* CONFIG_SYS_NUM_FMAN == 2 */
 447#else
 448        sys_info->freq_fman[0] = sys_info->freq_systembus / CONFIG_SYS_FM1_CLK;
 449#endif
 450#endif
 451
 452#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
 453#if defined(CONFIG_ARCH_T2080)
 454#define ESDHC_CLK_SEL   0x00000007
 455#define ESDHC_CLK_SHIFT 0
 456#define ESDHC_CLK_RCWSR 15
 457#else   /* Support T1040 T1024 by now */
 458#define ESDHC_CLK_SEL   0xe0000000
 459#define ESDHC_CLK_SHIFT 29
 460#define ESDHC_CLK_RCWSR 7
 461#endif
 462        rcw_tmp = in_be32(&gur->rcwsr[ESDHC_CLK_RCWSR]);
 463        switch ((rcw_tmp & ESDHC_CLK_SEL) >> ESDHC_CLK_SHIFT) {
 464        case 1:
 465                sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK];
 466                break;
 467        case 2:
 468                sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 2;
 469                break;
 470        case 3:
 471                sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 3;
 472                break;
 473#if defined(CONFIG_SYS_SDHC_CLK_2_PLL)
 474        case 4:
 475                sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 4;
 476                break;
 477#if defined(CONFIG_ARCH_T2080)
 478        case 5:
 479                sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK];
 480                break;
 481#endif
 482        case 6:
 483                sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK] / 2;
 484                break;
 485        case 7:
 486                sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK] / 3;
 487                break;
 488#endif
 489        default:
 490                sys_info->freq_sdhc = 0;
 491                printf("Error: Unknown SDHC peripheral clock select!\n");
 492        }
 493#endif
 494#else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
 495
 496        for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
 497                u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27)
 498                                & 0xf;
 499                u32 cplx_pll = core_cplx_PLL[c_pll_sel];
 500
 501                sys_info->freq_processor[cpu] =
 502                         freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
 503        }
 504#define PME_CLK_SEL     0x80000000
 505#define FM1_CLK_SEL     0x40000000
 506#define FM2_CLK_SEL     0x20000000
 507#define HWA_ASYNC_DIV   0x04000000
 508#if (CONFIG_SYS_FSL_NUM_CC_PLLS == 2)
 509#define HWA_CC_PLL      1
 510#elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 3)
 511#define HWA_CC_PLL      2
 512#elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 4)
 513#define HWA_CC_PLL      2
 514#else
 515#error CONFIG_SYS_FSL_NUM_CC_PLLS not set or unknown case
 516#endif
 517        rcw_tmp = in_be32(&gur->rcwsr[7]);
 518
 519#ifdef CONFIG_SYS_DPAA_PME
 520        if (rcw_tmp & PME_CLK_SEL) {
 521                if (rcw_tmp & HWA_ASYNC_DIV)
 522                        sys_info->freq_pme = freq_c_pll[HWA_CC_PLL] / 4;
 523                else
 524                        sys_info->freq_pme = freq_c_pll[HWA_CC_PLL] / 2;
 525        } else {
 526                sys_info->freq_pme = sys_info->freq_systembus / 2;
 527        }
 528#endif
 529
 530#ifdef CONFIG_SYS_DPAA_FMAN
 531        if (rcw_tmp & FM1_CLK_SEL) {
 532                if (rcw_tmp & HWA_ASYNC_DIV)
 533                        sys_info->freq_fman[0] = freq_c_pll[HWA_CC_PLL] / 4;
 534                else
 535                        sys_info->freq_fman[0] = freq_c_pll[HWA_CC_PLL] / 2;
 536        } else {
 537                sys_info->freq_fman[0] = sys_info->freq_systembus / 2;
 538        }
 539#if (CONFIG_SYS_NUM_FMAN) == 2
 540        if (rcw_tmp & FM2_CLK_SEL) {
 541                if (rcw_tmp & HWA_ASYNC_DIV)
 542                        sys_info->freq_fman[1] = freq_c_pll[HWA_CC_PLL] / 4;
 543                else
 544                        sys_info->freq_fman[1] = freq_c_pll[HWA_CC_PLL] / 2;
 545        } else {
 546                sys_info->freq_fman[1] = sys_info->freq_systembus / 2;
 547        }
 548#endif
 549#endif
 550
 551#ifdef CONFIG_SYS_DPAA_QBMAN
 552        sys_info->freq_qman = sys_info->freq_systembus / 2;
 553#endif
 554
 555#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
 556
 557#ifdef CONFIG_U_QE
 558        sys_info->freq_qe =  sys_info->freq_systembus / 2;
 559#endif
 560
 561#else /* CONFIG_FSL_CORENET */
 562        uint plat_ratio, e500_ratio, half_freq_systembus;
 563        int i;
 564#ifdef CONFIG_QE
 565        __maybe_unused u32 qe_ratio;
 566#endif
 567
 568        plat_ratio = (gur->porpllsr) & 0x0000003e;
 569        plat_ratio >>= 1;
 570        sys_info->freq_systembus = plat_ratio * CONFIG_SYS_CLK_FREQ;
 571
 572        /* Divide before multiply to avoid integer
 573         * overflow for processor speeds above 2GHz */
 574        half_freq_systembus = sys_info->freq_systembus/2;
 575        for (i = 0; i < cpu_numcores(); i++) {
 576                e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f;
 577                sys_info->freq_processor[i] = e500_ratio * half_freq_systembus;
 578        }
 579
 580        /* Note: freq_ddrbus is the MCLK frequency, not the data rate. */
 581        sys_info->freq_ddrbus = sys_info->freq_systembus;
 582
 583#ifdef CONFIG_DDR_CLK_FREQ
 584        {
 585                u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO)
 586                        >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
 587                if (ddr_ratio != 0x7)
 588                        sys_info->freq_ddrbus = ddr_ratio * CONFIG_DDR_CLK_FREQ;
 589        }
 590#endif
 591
 592#ifdef CONFIG_QE
 593#if defined(CONFIG_ARCH_P1021) || defined(CONFIG_ARCH_P1025)
 594        sys_info->freq_qe =  sys_info->freq_systembus;
 595#else
 596        qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO)
 597                        >> MPC85xx_PORPLLSR_QE_RATIO_SHIFT;
 598        sys_info->freq_qe = qe_ratio * CONFIG_SYS_CLK_FREQ;
 599#endif
 600#endif
 601
 602#ifdef CONFIG_SYS_DPAA_FMAN
 603                sys_info->freq_fman[0] = sys_info->freq_systembus;
 604#endif
 605
 606#endif /* CONFIG_FSL_CORENET */
 607
 608#if defined(CONFIG_FSL_LBC)
 609        sys_info->freq_localbus = sys_info->freq_systembus /
 610                                                CONFIG_SYS_FSL_LBC_CLK_DIV;
 611#endif
 612
 613#if defined(CONFIG_FSL_IFC)
 614        sys_info->freq_localbus = sys_info->freq_systembus /
 615                                                CONFIG_SYS_FSL_IFC_CLK_DIV;
 616#endif
 617}
 618
 619
 620int get_clocks (void)
 621{
 622        sys_info_t sys_info;
 623#ifdef CONFIG_ARCH_MPC8544
 624        volatile ccsr_gur_t *gur = (void *) CONFIG_SYS_MPC85xx_GUTS_ADDR;
 625#endif
 626#if defined(CONFIG_CPM2)
 627        volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR;
 628        uint sccr, dfbrg;
 629
 630        /* set VCO = 4 * BRG */
 631        cpm->im_cpm_intctl.sccr &= 0xfffffffc;
 632        sccr = cpm->im_cpm_intctl.sccr;
 633        dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT;
 634#endif
 635        get_sys_info (&sys_info);
 636        gd->cpu_clk = sys_info.freq_processor[0];
 637        gd->bus_clk = sys_info.freq_systembus;
 638        gd->mem_clk = sys_info.freq_ddrbus;
 639        gd->arch.lbc_clk = sys_info.freq_localbus;
 640
 641#ifdef CONFIG_QE
 642        gd->arch.qe_clk = sys_info.freq_qe;
 643        gd->arch.brg_clk = gd->arch.qe_clk / 2;
 644#endif
 645        /*
 646         * The base clock for I2C depends on the actual SOC.  Unfortunately,
 647         * there is no pattern that can be used to determine the frequency, so
 648         * the only choice is to look up the actual SOC number and use the value
 649         * for that SOC. This information is taken from application note
 650         * AN2919.
 651         */
 652#if defined(CONFIG_ARCH_MPC8540) || defined(CONFIG_ARCH_MPC8541) || \
 653        defined(CONFIG_ARCH_MPC8560) || defined(CONFIG_ARCH_MPC8555) || \
 654        defined(CONFIG_ARCH_P1022)
 655        gd->arch.i2c1_clk = sys_info.freq_systembus;
 656#elif defined(CONFIG_ARCH_MPC8544)
 657        /*
 658         * On the 8544, the I2C clock is the same as the SEC clock.  This can be
 659         * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See
 660         * 4.4.3.3 of the 8544 RM.  Note that this might actually work for all
 661         * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the
 662         * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544.
 663         */
 664        if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG)
 665                gd->arch.i2c1_clk = sys_info.freq_systembus / 3;
 666        else
 667                gd->arch.i2c1_clk = sys_info.freq_systembus / 2;
 668#else
 669        /* Most 85xx SOCs use CCB/2, so this is the default behavior. */
 670        gd->arch.i2c1_clk = sys_info.freq_systembus / 2;
 671#endif
 672        gd->arch.i2c2_clk = gd->arch.i2c1_clk;
 673
 674#if defined(CONFIG_FSL_ESDHC)
 675#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
 676        gd->arch.sdhc_clk = sys_info.freq_sdhc / 2;
 677#else
 678#if defined(CONFIG_ARCH_MPC8569) || defined(CONFIG_ARCH_P1010)
 679        gd->arch.sdhc_clk = gd->bus_clk;
 680#else
 681        gd->arch.sdhc_clk = gd->bus_clk / 2;
 682#endif
 683#endif
 684#endif /* defined(CONFIG_FSL_ESDHC) */
 685
 686#if defined(CONFIG_CPM2)
 687        gd->arch.vco_out = 2*sys_info.freq_systembus;
 688        gd->arch.cpm_clk = gd->arch.vco_out / 2;
 689        gd->arch.scc_clk = gd->arch.vco_out / 4;
 690        gd->arch.brg_clk = gd->arch.vco_out / (1 << (2 * (dfbrg + 1)));
 691#endif
 692
 693        if(gd->cpu_clk != 0) return (0);
 694        else return (1);
 695}
 696
 697
 698/********************************************
 699 * get_bus_freq
 700 * return system bus freq in Hz
 701 *********************************************/
 702ulong get_bus_freq (ulong dummy)
 703{
 704        return gd->bus_clk;
 705}
 706
 707/********************************************
 708 * get_ddr_freq
 709 * return ddr bus freq in Hz
 710 *********************************************/
 711ulong get_ddr_freq (ulong dummy)
 712{
 713        return gd->mem_clk;
 714}
 715