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 #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 297 298 #else /* CONFIG_FSL_CORENET */ 299 uint plat_ratio, e500_ratio, half_freqSystemBus; 300 int i; 301 #ifdef CONFIG_QE 302 __maybe_unused u32 qe_ratio; 303 #endif 304 305 plat_ratio = (gur->porpllsr) & 0x0000003e; 306 plat_ratio >>= 1; 307 sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ; 308 309 /* Divide before multiply to avoid integer 310 * overflow for processor speeds above 2GHz */ 311 half_freqSystemBus = sysInfo->freqSystemBus/2; 312 for (i = 0; i < cpu_numcores(); i++) { 313 e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f; 314 sysInfo->freqProcessor[i] = e500_ratio * half_freqSystemBus; 315 } 316 317 /* Note: freqDDRBus is the MCLK frequency, not the data rate. */ 318 sysInfo->freqDDRBus = sysInfo->freqSystemBus; 319 320 #ifdef CONFIG_DDR_CLK_FREQ 321 { 322 u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO) 323 >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; 324 if (ddr_ratio != 0x7) 325 sysInfo->freqDDRBus = ddr_ratio * CONFIG_DDR_CLK_FREQ; 326 } 327 #endif 328 329 #ifdef CONFIG_QE 330 #if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) 331 sysInfo->freqQE = sysInfo->freqSystemBus; 332 #else 333 qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO) 334 >> MPC85xx_PORPLLSR_QE_RATIO_SHIFT; 335 sysInfo->freqQE = qe_ratio * CONFIG_SYS_CLK_FREQ; 336 #endif 337 #endif 338 339 #ifdef CONFIG_SYS_DPAA_FMAN 340 sysInfo->freqFMan[0] = sysInfo->freqSystemBus; 341 #endif 342 343 #endif /* CONFIG_FSL_CORENET */ 344 345 #if defined(CONFIG_FSL_LBC) 346 uint lcrr_div; 347 #if defined(CONFIG_SYS_LBC_LCRR) 348 /* We will program LCRR to this value later */ 349 lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; 350 #else 351 lcrr_div = in_be32(&(LBC_BASE_ADDR)->lcrr) & LCRR_CLKDIV; 352 #endif 353 if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { 354 #if defined(CONFIG_FSL_CORENET) 355 /* If this is corenet based SoC, bit-representation 356 * for four times the clock divider values. 357 */ 358 lcrr_div *= 4; 359 #elif !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ 360 !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) 361 /* 362 * Yes, the entire PQ38 family use the same 363 * bit-representation for twice the clock divider values. 364 */ 365 lcrr_div *= 2; 366 #endif 367 sysInfo->freqLocalBus = sysInfo->freqSystemBus / lcrr_div; 368 } else { 369 /* In case anyone cares what the unknown value is */ 370 sysInfo->freqLocalBus = lcrr_div; 371 } 372 #endif 373 374 #if defined(CONFIG_FSL_IFC) 375 ccr = in_be32(&ifc_regs->ifc_ccr); 376 ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; 377 378 sysInfo->freqLocalBus = sysInfo->freqSystemBus / ccr; 379 #endif 380 } 381 382 383 int get_clocks (void) 384 { 385 sys_info_t sys_info; 386 #ifdef CONFIG_MPC8544 387 volatile ccsr_gur_t *gur = (void *) CONFIG_SYS_MPC85xx_GUTS_ADDR; 388 #endif 389 #if defined(CONFIG_CPM2) 390 volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR; 391 uint sccr, dfbrg; 392 393 /* set VCO = 4 * BRG */ 394 cpm->im_cpm_intctl.sccr &= 0xfffffffc; 395 sccr = cpm->im_cpm_intctl.sccr; 396 dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT; 397 #endif 398 get_sys_info (&sys_info); 399 gd->cpu_clk = sys_info.freqProcessor[0]; 400 gd->bus_clk = sys_info.freqSystemBus; 401 gd->mem_clk = sys_info.freqDDRBus; 402 gd->arch.lbc_clk = sys_info.freqLocalBus; 403 404 #ifdef CONFIG_QE 405 gd->arch.qe_clk = sys_info.freqQE; 406 gd->arch.brg_clk = gd->arch.qe_clk / 2; 407 #endif 408 /* 409 * The base clock for I2C depends on the actual SOC. Unfortunately, 410 * there is no pattern that can be used to determine the frequency, so 411 * the only choice is to look up the actual SOC number and use the value 412 * for that SOC. This information is taken from application note 413 * AN2919. 414 */ 415 #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ 416 defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) 417 gd->arch.i2c1_clk = sys_info.freqSystemBus; 418 #elif defined(CONFIG_MPC8544) 419 /* 420 * On the 8544, the I2C clock is the same as the SEC clock. This can be 421 * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See 422 * 4.4.3.3 of the 8544 RM. Note that this might actually work for all 423 * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the 424 * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544. 425 */ 426 if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG) 427 gd->arch.i2c1_clk = sys_info.freqSystemBus / 3; 428 else 429 gd->arch.i2c1_clk = sys_info.freqSystemBus / 2; 430 #else 431 /* Most 85xx SOCs use CCB/2, so this is the default behavior. */ 432 gd->arch.i2c1_clk = sys_info.freqSystemBus / 2; 433 #endif 434 gd->arch.i2c2_clk = gd->arch.i2c1_clk; 435 436 #if defined(CONFIG_FSL_ESDHC) 437 #if defined(CONFIG_MPC8569) || defined(CONFIG_P1010) ||\ 438 defined(CONFIG_P1014) 439 gd->arch.sdhc_clk = gd->bus_clk; 440 #else 441 gd->arch.sdhc_clk = gd->bus_clk / 2; 442 #endif 443 #endif /* defined(CONFIG_FSL_ESDHC) */ 444 445 #if defined(CONFIG_CPM2) 446 gd->arch.vco_out = 2*sys_info.freqSystemBus; 447 gd->arch.cpm_clk = gd->arch.vco_out / 2; 448 gd->arch.scc_clk = gd->arch.vco_out / 4; 449 gd->arch.brg_clk = gd->arch.vco_out / (1 << (2 * (dfbrg + 1))); 450 #endif 451 452 if(gd->cpu_clk != 0) return (0); 453 else return (1); 454 } 455 456 457 /******************************************** 458 * get_bus_freq 459 * return system bus freq in Hz 460 *********************************************/ 461 ulong get_bus_freq (ulong dummy) 462 { 463 return gd->bus_clk; 464 } 465 466 /******************************************** 467 * get_ddr_freq 468 * return ddr bus freq in Hz 469 *********************************************/ 470 ulong get_ddr_freq (ulong dummy) 471 { 472 return gd->mem_clk; 473 } 474