1 /* 2 * Copyright 2004, 2007-2011 Freescale Semiconductor, Inc. 3 * 4 * (C) Copyright 2003 Motorola Inc. 5 * Xianghua Xiao, (X.Xiao@motorola.com) 6 * 7 * (C) Copyright 2000 8 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 9 * 10 * See file CREDITS for list of people who contributed to this 11 * project. 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License as 15 * published by the Free Software Foundation; either version 2 of 16 * the License, or (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 26 * MA 02111-1307 USA 27 */ 28 29 #include <common.h> 30 #include <ppc_asm.tmpl> 31 #include <linux/compiler.h> 32 #include <asm/processor.h> 33 #include <asm/io.h> 34 35 DECLARE_GLOBAL_DATA_PTR; 36 37 /* --------------------------------------------------------------- */ 38 39 void get_sys_info (sys_info_t * sysInfo) 40 { 41 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 42 #ifdef CONFIG_FSL_IFC 43 struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; 44 u32 ccr; 45 #endif 46 #ifdef CONFIG_FSL_CORENET 47 volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR); 48 unsigned int cpu; 49 50 const u8 core_cplx_PLL[16] = { 51 [ 0] = 0, /* CC1 PPL / 1 */ 52 [ 1] = 0, /* CC1 PPL / 2 */ 53 [ 2] = 0, /* CC1 PPL / 4 */ 54 [ 4] = 1, /* CC2 PPL / 1 */ 55 [ 5] = 1, /* CC2 PPL / 2 */ 56 [ 6] = 1, /* CC2 PPL / 4 */ 57 [ 8] = 2, /* CC3 PPL / 1 */ 58 [ 9] = 2, /* CC3 PPL / 2 */ 59 [10] = 2, /* CC3 PPL / 4 */ 60 [12] = 3, /* CC4 PPL / 1 */ 61 [13] = 3, /* CC4 PPL / 2 */ 62 [14] = 3, /* CC4 PPL / 4 */ 63 }; 64 65 const u8 core_cplx_PLL_div[16] = { 66 [ 0] = 1, /* CC1 PPL / 1 */ 67 [ 1] = 2, /* CC1 PPL / 2 */ 68 [ 2] = 4, /* CC1 PPL / 4 */ 69 [ 4] = 1, /* CC2 PPL / 1 */ 70 [ 5] = 2, /* CC2 PPL / 2 */ 71 [ 6] = 4, /* CC2 PPL / 4 */ 72 [ 8] = 1, /* CC3 PPL / 1 */ 73 [ 9] = 2, /* CC3 PPL / 2 */ 74 [10] = 4, /* CC3 PPL / 4 */ 75 [12] = 1, /* CC4 PPL / 1 */ 76 [13] = 2, /* CC4 PPL / 2 */ 77 [14] = 4, /* CC4 PPL / 4 */ 78 }; 79 uint i, freqCC_PLL[6], rcw_tmp; 80 uint ratio[6]; 81 unsigned long sysclk = CONFIG_SYS_CLK_FREQ; 82 uint mem_pll_rat; 83 84 sysInfo->freqSystemBus = sysclk; 85 #ifdef CONFIG_DDR_CLK_FREQ 86 sysInfo->freqDDRBus = CONFIG_DDR_CLK_FREQ; 87 #else 88 sysInfo->freqDDRBus = sysclk; 89 #endif 90 91 sysInfo->freqSystemBus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; 92 mem_pll_rat = (in_be32(&gur->rcwsr[0]) >> 93 FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT) 94 & FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK; 95 if (mem_pll_rat > 2) 96 sysInfo->freqDDRBus *= mem_pll_rat; 97 else 98 sysInfo->freqDDRBus = sysInfo->freqSystemBus * mem_pll_rat; 99 100 ratio[0] = (in_be32(&clk->pllc1gsr) >> 1) & 0x3f; 101 ratio[1] = (in_be32(&clk->pllc2gsr) >> 1) & 0x3f; 102 ratio[2] = (in_be32(&clk->pllc3gsr) >> 1) & 0x3f; 103 ratio[3] = (in_be32(&clk->pllc4gsr) >> 1) & 0x3f; 104 ratio[4] = (in_be32(&clk->pllc5gsr) >> 1) & 0x3f; 105 ratio[5] = (in_be32(&clk->pllc6gsr) >> 1) & 0x3f; 106 for (i = 0; i < 6; i++) { 107 if (ratio[i] > 4) 108 freqCC_PLL[i] = sysclk * ratio[i]; 109 else 110 freqCC_PLL[i] = sysInfo->freqSystemBus * ratio[i]; 111 } 112 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 113 /* 114 * Each cluster has up to 4 cores, sharing the same PLL selection. 115 * The cluster assignment is fixed per SoC. There is no way identify the 116 * assignment so far, presuming the "first configuration" which is to 117 * fill the lower cluster group first before moving up to next group. 118 * PLL1, PLL2, PLL3 are cluster group A, feeding core 0~3 on cluster 1 119 * and core 4~7 on cluster 2 120 * PLL4, PLL5, PLL6 are cluster group B, feeding core 8~11 on cluster 3 121 * and core 12~15 on cluster 4 if existing 122 */ 123 for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 124 u32 c_pll_sel = (in_be32(&clk->clkc0csr + (cpu / 4) * 8) >> 27) 125 & 0xf; 126 u32 cplx_pll = core_cplx_PLL[c_pll_sel]; 127 if (cplx_pll > 3) 128 printf("Unsupported architecture configuration" 129 " in function %s\n", __func__); 130 cplx_pll += (cpu / 8) * 3; 131 132 sysInfo->freqProcessor[cpu] = 133 freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel]; 134 } 135 #ifdef CONFIG_PPC_B4860 136 #define FM1_CLK_SEL 0xe0000000 137 #define FM1_CLK_SHIFT 29 138 #else 139 #define PME_CLK_SEL 0xe0000000 140 #define PME_CLK_SHIFT 29 141 #define FM1_CLK_SEL 0x1c000000 142 #define FM1_CLK_SHIFT 26 143 #endif 144 rcw_tmp = in_be32(&gur->rcwsr[7]); 145 146 #ifdef CONFIG_SYS_DPAA_PME 147 switch ((rcw_tmp & PME_CLK_SEL) >> PME_CLK_SHIFT) { 148 case 1: 149 sysInfo->freqPME = freqCC_PLL[0]; 150 break; 151 case 2: 152 sysInfo->freqPME = freqCC_PLL[0] / 2; 153 break; 154 case 3: 155 sysInfo->freqPME = freqCC_PLL[0] / 3; 156 break; 157 case 4: 158 sysInfo->freqPME = freqCC_PLL[0] / 4; 159 break; 160 case 6: 161 sysInfo->freqPME = freqCC_PLL[1] / 2; 162 break; 163 case 7: 164 sysInfo->freqPME = freqCC_PLL[1] / 3; 165 break; 166 default: 167 printf("Error: Unknown PME clock select!\n"); 168 case 0: 169 sysInfo->freqPME = sysInfo->freqSystemBus / 2; 170 break; 171 172 } 173 #endif 174 175 #ifdef CONFIG_SYS_DPAA_QBMAN 176 sysInfo->freqQMAN = sysInfo->freqSystemBus / 2; 177 #endif 178 179 #ifdef CONFIG_SYS_DPAA_FMAN 180 switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) { 181 case 1: 182 sysInfo->freqFMan[0] = freqCC_PLL[3]; 183 break; 184 case 2: 185 sysInfo->freqFMan[0] = freqCC_PLL[3] / 2; 186 break; 187 case 3: 188 sysInfo->freqFMan[0] = freqCC_PLL[3] / 3; 189 break; 190 case 4: 191 sysInfo->freqFMan[0] = freqCC_PLL[3] / 4; 192 break; 193 case 5: 194 sysInfo->freqFMan[0] = sysInfo->freqSystemBus; 195 break; 196 case 6: 197 sysInfo->freqFMan[0] = freqCC_PLL[4] / 2; 198 break; 199 case 7: 200 sysInfo->freqFMan[0] = freqCC_PLL[4] / 3; 201 break; 202 default: 203 printf("Error: Unknown FMan1 clock select!\n"); 204 case 0: 205 sysInfo->freqFMan[0] = sysInfo->freqSystemBus / 2; 206 break; 207 } 208 #if (CONFIG_SYS_NUM_FMAN) == 2 209 #define FM2_CLK_SEL 0x00000038 210 #define FM2_CLK_SHIFT 3 211 rcw_tmp = in_be32(&gur->rcwsr[15]); 212 switch ((rcw_tmp & FM2_CLK_SEL) >> FM2_CLK_SHIFT) { 213 case 1: 214 sysInfo->freqFMan[1] = freqCC_PLL[4]; 215 break; 216 case 2: 217 sysInfo->freqFMan[1] = freqCC_PLL[4] / 2; 218 break; 219 case 3: 220 sysInfo->freqFMan[1] = freqCC_PLL[4] / 3; 221 break; 222 case 4: 223 sysInfo->freqFMan[1] = freqCC_PLL[4] / 4; 224 break; 225 case 6: 226 sysInfo->freqFMan[1] = freqCC_PLL[3] / 2; 227 break; 228 case 7: 229 sysInfo->freqFMan[1] = freqCC_PLL[3] / 3; 230 break; 231 default: 232 printf("Error: Unknown FMan2 clock select!\n"); 233 case 0: 234 sysInfo->freqFMan[1] = sysInfo->freqSystemBus / 2; 235 break; 236 } 237 #endif /* CONFIG_SYS_NUM_FMAN == 2 */ 238 #endif /* CONFIG_SYS_DPAA_FMAN */ 239 240 #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 241 242 for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 243 u32 c_pll_sel = (in_be32(&clk->clkc0csr + cpu*8) >> 27) & 0xf; 244 u32 cplx_pll = core_cplx_PLL[c_pll_sel]; 245 246 sysInfo->freqProcessor[cpu] = 247 freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel]; 248 } 249 #define PME_CLK_SEL 0x80000000 250 #define FM1_CLK_SEL 0x40000000 251 #define FM2_CLK_SEL 0x20000000 252 #define HWA_ASYNC_DIV 0x04000000 253 #if (CONFIG_SYS_FSL_NUM_CC_PLLS == 2) 254 #define HWA_CC_PLL 1 255 #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 3) 256 #define HWA_CC_PLL 2 257 #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 4) 258 #define HWA_CC_PLL 2 259 #else 260 #error CONFIG_SYS_FSL_NUM_CC_PLLS not set or unknown case 261 #endif 262 rcw_tmp = in_be32(&gur->rcwsr[7]); 263 264 #ifdef CONFIG_SYS_DPAA_PME 265 if (rcw_tmp & PME_CLK_SEL) { 266 if (rcw_tmp & HWA_ASYNC_DIV) 267 sysInfo->freqPME = freqCC_PLL[HWA_CC_PLL] / 4; 268 else 269 sysInfo->freqPME = freqCC_PLL[HWA_CC_PLL] / 2; 270 } else { 271 sysInfo->freqPME = sysInfo->freqSystemBus / 2; 272 } 273 #endif 274 275 #ifdef CONFIG_SYS_DPAA_FMAN 276 if (rcw_tmp & FM1_CLK_SEL) { 277 if (rcw_tmp & HWA_ASYNC_DIV) 278 sysInfo->freqFMan[0] = freqCC_PLL[HWA_CC_PLL] / 4; 279 else 280 sysInfo->freqFMan[0] = freqCC_PLL[HWA_CC_PLL] / 2; 281 } else { 282 sysInfo->freqFMan[0] = sysInfo->freqSystemBus / 2; 283 } 284 #if (CONFIG_SYS_NUM_FMAN) == 2 285 if (rcw_tmp & FM2_CLK_SEL) { 286 if (rcw_tmp & HWA_ASYNC_DIV) 287 sysInfo->freqFMan[1] = freqCC_PLL[HWA_CC_PLL] / 4; 288 else 289 sysInfo->freqFMan[1] = freqCC_PLL[HWA_CC_PLL] / 2; 290 } else { 291 sysInfo->freqFMan[1] = sysInfo->freqSystemBus / 2; 292 } 293 #endif 294 #endif 295 296 #ifdef CONFIG_SYS_DPAA_QBMAN 297 sysInfo->freqQMAN = sysInfo->freqSystemBus / 2; 298 #endif 299 300 #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 301 302 #else /* CONFIG_FSL_CORENET */ 303 uint plat_ratio, e500_ratio, half_freqSystemBus; 304 int i; 305 #ifdef CONFIG_QE 306 __maybe_unused u32 qe_ratio; 307 #endif 308 309 plat_ratio = (gur->porpllsr) & 0x0000003e; 310 plat_ratio >>= 1; 311 sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ; 312 313 /* Divide before multiply to avoid integer 314 * overflow for processor speeds above 2GHz */ 315 half_freqSystemBus = sysInfo->freqSystemBus/2; 316 for (i = 0; i < cpu_numcores(); i++) { 317 e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f; 318 sysInfo->freqProcessor[i] = e500_ratio * half_freqSystemBus; 319 } 320 321 /* Note: freqDDRBus is the MCLK frequency, not the data rate. */ 322 sysInfo->freqDDRBus = sysInfo->freqSystemBus; 323 324 #ifdef CONFIG_DDR_CLK_FREQ 325 { 326 u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO) 327 >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; 328 if (ddr_ratio != 0x7) 329 sysInfo->freqDDRBus = ddr_ratio * CONFIG_DDR_CLK_FREQ; 330 } 331 #endif 332 333 #ifdef CONFIG_QE 334 #if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) 335 sysInfo->freqQE = sysInfo->freqSystemBus; 336 #else 337 qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO) 338 >> MPC85xx_PORPLLSR_QE_RATIO_SHIFT; 339 sysInfo->freqQE = qe_ratio * CONFIG_SYS_CLK_FREQ; 340 #endif 341 #endif 342 343 #ifdef CONFIG_SYS_DPAA_FMAN 344 sysInfo->freqFMan[0] = sysInfo->freqSystemBus; 345 #endif 346 347 #endif /* CONFIG_FSL_CORENET */ 348 349 #if defined(CONFIG_FSL_LBC) 350 uint lcrr_div; 351 #if defined(CONFIG_SYS_LBC_LCRR) 352 /* We will program LCRR to this value later */ 353 lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; 354 #else 355 lcrr_div = in_be32(&(LBC_BASE_ADDR)->lcrr) & LCRR_CLKDIV; 356 #endif 357 if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { 358 #if defined(CONFIG_FSL_CORENET) 359 /* If this is corenet based SoC, bit-representation 360 * for four times the clock divider values. 361 */ 362 lcrr_div *= 4; 363 #elif !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ 364 !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) 365 /* 366 * Yes, the entire PQ38 family use the same 367 * bit-representation for twice the clock divider values. 368 */ 369 lcrr_div *= 2; 370 #endif 371 sysInfo->freqLocalBus = sysInfo->freqSystemBus / lcrr_div; 372 } else { 373 /* In case anyone cares what the unknown value is */ 374 sysInfo->freqLocalBus = lcrr_div; 375 } 376 #endif 377 378 #if defined(CONFIG_FSL_IFC) 379 ccr = in_be32(&ifc_regs->ifc_ccr); 380 ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; 381 382 sysInfo->freqLocalBus = sysInfo->freqSystemBus / ccr; 383 #endif 384 } 385 386 387 int get_clocks (void) 388 { 389 sys_info_t sys_info; 390 #ifdef CONFIG_MPC8544 391 volatile ccsr_gur_t *gur = (void *) CONFIG_SYS_MPC85xx_GUTS_ADDR; 392 #endif 393 #if defined(CONFIG_CPM2) 394 volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR; 395 uint sccr, dfbrg; 396 397 /* set VCO = 4 * BRG */ 398 cpm->im_cpm_intctl.sccr &= 0xfffffffc; 399 sccr = cpm->im_cpm_intctl.sccr; 400 dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT; 401 #endif 402 get_sys_info (&sys_info); 403 gd->cpu_clk = sys_info.freqProcessor[0]; 404 gd->bus_clk = sys_info.freqSystemBus; 405 gd->mem_clk = sys_info.freqDDRBus; 406 gd->arch.lbc_clk = sys_info.freqLocalBus; 407 408 #ifdef CONFIG_QE 409 gd->arch.qe_clk = sys_info.freqQE; 410 gd->arch.brg_clk = gd->arch.qe_clk / 2; 411 #endif 412 /* 413 * The base clock for I2C depends on the actual SOC. Unfortunately, 414 * there is no pattern that can be used to determine the frequency, so 415 * the only choice is to look up the actual SOC number and use the value 416 * for that SOC. This information is taken from application note 417 * AN2919. 418 */ 419 #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ 420 defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) 421 gd->arch.i2c1_clk = sys_info.freqSystemBus; 422 #elif defined(CONFIG_MPC8544) 423 /* 424 * On the 8544, the I2C clock is the same as the SEC clock. This can be 425 * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See 426 * 4.4.3.3 of the 8544 RM. Note that this might actually work for all 427 * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the 428 * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544. 429 */ 430 if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG) 431 gd->arch.i2c1_clk = sys_info.freqSystemBus / 3; 432 else 433 gd->arch.i2c1_clk = sys_info.freqSystemBus / 2; 434 #else 435 /* Most 85xx SOCs use CCB/2, so this is the default behavior. */ 436 gd->arch.i2c1_clk = sys_info.freqSystemBus / 2; 437 #endif 438 gd->arch.i2c2_clk = gd->arch.i2c1_clk; 439 440 #if defined(CONFIG_FSL_ESDHC) 441 #if defined(CONFIG_MPC8569) || defined(CONFIG_P1010) ||\ 442 defined(CONFIG_P1014) 443 gd->arch.sdhc_clk = gd->bus_clk; 444 #else 445 gd->arch.sdhc_clk = gd->bus_clk / 2; 446 #endif 447 #endif /* defined(CONFIG_FSL_ESDHC) */ 448 449 #if defined(CONFIG_CPM2) 450 gd->arch.vco_out = 2*sys_info.freqSystemBus; 451 gd->arch.cpm_clk = gd->arch.vco_out / 2; 452 gd->arch.scc_clk = gd->arch.vco_out / 4; 453 gd->arch.brg_clk = gd->arch.vco_out / (1 << (2 * (dfbrg + 1))); 454 #endif 455 456 if(gd->cpu_clk != 0) return (0); 457 else return (1); 458 } 459 460 461 /******************************************** 462 * get_bus_freq 463 * return system bus freq in Hz 464 *********************************************/ 465 ulong get_bus_freq (ulong dummy) 466 { 467 return gd->bus_clk; 468 } 469 470 /******************************************** 471 * get_ddr_freq 472 * return ddr bus freq in Hz 473 *********************************************/ 474 ulong get_ddr_freq (ulong dummy) 475 { 476 return gd->mem_clk; 477 } 478