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 sysInfo->freqDDRBus = sysclk; 86 87 sysInfo->freqSystemBus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; 88 mem_pll_rat = (in_be32(&gur->rcwsr[0]) >> 89 FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT) 90 & FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK; 91 if (mem_pll_rat > 2) 92 sysInfo->freqDDRBus *= mem_pll_rat; 93 else 94 sysInfo->freqDDRBus = sysInfo->freqSystemBus * mem_pll_rat; 95 96 ratio[0] = (in_be32(&clk->pllc1gsr) >> 1) & 0x3f; 97 ratio[1] = (in_be32(&clk->pllc2gsr) >> 1) & 0x3f; 98 ratio[2] = (in_be32(&clk->pllc3gsr) >> 1) & 0x3f; 99 ratio[3] = (in_be32(&clk->pllc4gsr) >> 1) & 0x3f; 100 ratio[4] = (in_be32(&clk->pllc5gsr) >> 1) & 0x3f; 101 ratio[5] = (in_be32(&clk->pllc6gsr) >> 1) & 0x3f; 102 for (i = 0; i < 6; i++) { 103 if (ratio[i] > 4) 104 freqCC_PLL[i] = sysclk * ratio[i]; 105 else 106 freqCC_PLL[i] = sysInfo->freqSystemBus * ratio[i]; 107 } 108 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 109 /* 110 * Each cluster has up to 4 cores, sharing the same PLL selection. 111 * The cluster assignment is fixed per SoC. There is no way identify the 112 * assignment so far, presuming the "first configuration" which is to 113 * fill the lower cluster group first before moving up to next group. 114 * PLL1, PLL2, PLL3 are cluster group A, feeding core 0~3 on cluster 1 115 * and core 4~7 on cluster 2 116 * PLL4, PLL5, PLL6 are cluster group B, feeding core 8~11 on cluster 3 117 * and core 12~15 on cluster 4 if existing 118 */ 119 for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 120 u32 c_pll_sel = (in_be32(&clk->clkc0csr + (cpu / 4) * 8) >> 27) 121 & 0xf; 122 u32 cplx_pll = core_cplx_PLL[c_pll_sel]; 123 if (cplx_pll > 3) 124 printf("Unsupported architecture configuration" 125 " in function %s\n", __func__); 126 cplx_pll += (cpu / 8) * 3; 127 128 sysInfo->freqProcessor[cpu] = 129 freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel]; 130 } 131 #define PME_CLK_SEL 0xe0000000 132 #define PME_CLK_SHIFT 29 133 #define FM1_CLK_SEL 0x1c000000 134 #define FM1_CLK_SHIFT 26 135 rcw_tmp = in_be32(&gur->rcwsr[7]); 136 137 #ifdef CONFIG_SYS_DPAA_PME 138 switch ((rcw_tmp & PME_CLK_SEL) >> PME_CLK_SHIFT) { 139 case 1: 140 sysInfo->freqPME = freqCC_PLL[0]; 141 break; 142 case 2: 143 sysInfo->freqPME = freqCC_PLL[0] / 2; 144 break; 145 case 3: 146 sysInfo->freqPME = freqCC_PLL[0] / 3; 147 break; 148 case 4: 149 sysInfo->freqPME = freqCC_PLL[0] / 4; 150 break; 151 case 6: 152 sysInfo->freqPME = freqCC_PLL[1] / 2; 153 break; 154 case 7: 155 sysInfo->freqPME = freqCC_PLL[1] / 3; 156 break; 157 default: 158 printf("Error: Unknown PME clock select!\n"); 159 case 0: 160 sysInfo->freqPME = sysInfo->freqSystemBus / 2; 161 break; 162 163 } 164 #endif 165 166 #ifdef CONFIG_SYS_DPAA_FMAN 167 switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) { 168 case 1: 169 sysInfo->freqFMan[0] = freqCC_PLL[3]; 170 break; 171 case 2: 172 sysInfo->freqFMan[0] = freqCC_PLL[3] / 2; 173 break; 174 case 3: 175 sysInfo->freqFMan[0] = freqCC_PLL[3] / 3; 176 break; 177 case 4: 178 sysInfo->freqFMan[0] = freqCC_PLL[3] / 4; 179 break; 180 case 6: 181 sysInfo->freqFMan[0] = freqCC_PLL[4] / 2; 182 break; 183 case 7: 184 sysInfo->freqFMan[0] = freqCC_PLL[4] / 3; 185 break; 186 default: 187 printf("Error: Unknown FMan1 clock select!\n"); 188 case 0: 189 sysInfo->freqFMan[0] = sysInfo->freqSystemBus / 2; 190 break; 191 } 192 #if (CONFIG_SYS_NUM_FMAN) == 2 193 #define FM2_CLK_SEL 0x00000038 194 #define FM2_CLK_SHIFT 3 195 rcw_tmp = in_be32(&gur->rcwsr[15]); 196 switch ((rcw_tmp & FM2_CLK_SEL) >> FM2_CLK_SHIFT) { 197 case 1: 198 sysInfo->freqFMan[1] = freqCC_PLL[4]; 199 break; 200 case 2: 201 sysInfo->freqFMan[1] = freqCC_PLL[4] / 2; 202 break; 203 case 3: 204 sysInfo->freqFMan[1] = freqCC_PLL[4] / 3; 205 break; 206 case 4: 207 sysInfo->freqFMan[1] = freqCC_PLL[4] / 4; 208 break; 209 case 6: 210 sysInfo->freqFMan[1] = freqCC_PLL[3] / 2; 211 break; 212 case 7: 213 sysInfo->freqFMan[1] = freqCC_PLL[3] / 3; 214 break; 215 default: 216 printf("Error: Unknown FMan2 clock select!\n"); 217 case 0: 218 sysInfo->freqFMan[1] = sysInfo->freqSystemBus / 2; 219 break; 220 } 221 #endif /* CONFIG_SYS_NUM_FMAN == 2 */ 222 #endif /* CONFIG_SYS_DPAA_FMAN */ 223 224 #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 225 226 for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 227 u32 c_pll_sel = (in_be32(&clk->clkc0csr + cpu*8) >> 27) & 0xf; 228 u32 cplx_pll = core_cplx_PLL[c_pll_sel]; 229 230 sysInfo->freqProcessor[cpu] = 231 freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel]; 232 } 233 #define PME_CLK_SEL 0x80000000 234 #define FM1_CLK_SEL 0x40000000 235 #define FM2_CLK_SEL 0x20000000 236 #define HWA_ASYNC_DIV 0x04000000 237 #if (CONFIG_SYS_FSL_NUM_CC_PLLS == 2) 238 #define HWA_CC_PLL 1 239 #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 3) 240 #define HWA_CC_PLL 2 241 #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 4) 242 #define HWA_CC_PLL 2 243 #else 244 #error CONFIG_SYS_FSL_NUM_CC_PLLS not set or unknown case 245 #endif 246 rcw_tmp = in_be32(&gur->rcwsr[7]); 247 248 #ifdef CONFIG_SYS_DPAA_PME 249 if (rcw_tmp & PME_CLK_SEL) { 250 if (rcw_tmp & HWA_ASYNC_DIV) 251 sysInfo->freqPME = freqCC_PLL[HWA_CC_PLL] / 4; 252 else 253 sysInfo->freqPME = freqCC_PLL[HWA_CC_PLL] / 2; 254 } else { 255 sysInfo->freqPME = sysInfo->freqSystemBus / 2; 256 } 257 #endif 258 259 #ifdef CONFIG_SYS_DPAA_FMAN 260 if (rcw_tmp & FM1_CLK_SEL) { 261 if (rcw_tmp & HWA_ASYNC_DIV) 262 sysInfo->freqFMan[0] = freqCC_PLL[HWA_CC_PLL] / 4; 263 else 264 sysInfo->freqFMan[0] = freqCC_PLL[HWA_CC_PLL] / 2; 265 } else { 266 sysInfo->freqFMan[0] = sysInfo->freqSystemBus / 2; 267 } 268 #if (CONFIG_SYS_NUM_FMAN) == 2 269 if (rcw_tmp & FM2_CLK_SEL) { 270 if (rcw_tmp & HWA_ASYNC_DIV) 271 sysInfo->freqFMan[1] = freqCC_PLL[HWA_CC_PLL] / 4; 272 else 273 sysInfo->freqFMan[1] = freqCC_PLL[HWA_CC_PLL] / 2; 274 } else { 275 sysInfo->freqFMan[1] = sysInfo->freqSystemBus / 2; 276 } 277 #endif 278 #endif 279 280 #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 281 282 #else /* CONFIG_FSL_CORENET */ 283 uint plat_ratio, e500_ratio, half_freqSystemBus; 284 int i; 285 #ifdef CONFIG_QE 286 __maybe_unused u32 qe_ratio; 287 #endif 288 289 plat_ratio = (gur->porpllsr) & 0x0000003e; 290 plat_ratio >>= 1; 291 sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ; 292 293 /* Divide before multiply to avoid integer 294 * overflow for processor speeds above 2GHz */ 295 half_freqSystemBus = sysInfo->freqSystemBus/2; 296 for (i = 0; i < cpu_numcores(); i++) { 297 e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f; 298 sysInfo->freqProcessor[i] = e500_ratio * half_freqSystemBus; 299 } 300 301 /* Note: freqDDRBus is the MCLK frequency, not the data rate. */ 302 sysInfo->freqDDRBus = sysInfo->freqSystemBus; 303 304 #ifdef CONFIG_DDR_CLK_FREQ 305 { 306 u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO) 307 >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; 308 if (ddr_ratio != 0x7) 309 sysInfo->freqDDRBus = ddr_ratio * CONFIG_DDR_CLK_FREQ; 310 } 311 #endif 312 313 #ifdef CONFIG_QE 314 #if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) 315 sysInfo->freqQE = sysInfo->freqSystemBus; 316 #else 317 qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO) 318 >> MPC85xx_PORPLLSR_QE_RATIO_SHIFT; 319 sysInfo->freqQE = qe_ratio * CONFIG_SYS_CLK_FREQ; 320 #endif 321 #endif 322 323 #ifdef CONFIG_SYS_DPAA_FMAN 324 sysInfo->freqFMan[0] = sysInfo->freqSystemBus; 325 #endif 326 327 #endif /* CONFIG_FSL_CORENET */ 328 329 #if defined(CONFIG_FSL_LBC) 330 uint lcrr_div; 331 #if defined(CONFIG_SYS_LBC_LCRR) 332 /* We will program LCRR to this value later */ 333 lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; 334 #else 335 lcrr_div = in_be32(&(LBC_BASE_ADDR)->lcrr) & LCRR_CLKDIV; 336 #endif 337 if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { 338 #if defined(CONFIG_FSL_CORENET) 339 /* If this is corenet based SoC, bit-representation 340 * for four times the clock divider values. 341 */ 342 lcrr_div *= 4; 343 #elif !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ 344 !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) 345 /* 346 * Yes, the entire PQ38 family use the same 347 * bit-representation for twice the clock divider values. 348 */ 349 lcrr_div *= 2; 350 #endif 351 sysInfo->freqLocalBus = sysInfo->freqSystemBus / lcrr_div; 352 } else { 353 /* In case anyone cares what the unknown value is */ 354 sysInfo->freqLocalBus = lcrr_div; 355 } 356 #endif 357 358 #if defined(CONFIG_FSL_IFC) 359 ccr = in_be32(&ifc_regs->ifc_ccr); 360 ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; 361 362 sysInfo->freqLocalBus = sysInfo->freqSystemBus / ccr; 363 #endif 364 } 365 366 367 int get_clocks (void) 368 { 369 sys_info_t sys_info; 370 #ifdef CONFIG_MPC8544 371 volatile ccsr_gur_t *gur = (void *) CONFIG_SYS_MPC85xx_GUTS_ADDR; 372 #endif 373 #if defined(CONFIG_CPM2) 374 volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR; 375 uint sccr, dfbrg; 376 377 /* set VCO = 4 * BRG */ 378 cpm->im_cpm_intctl.sccr &= 0xfffffffc; 379 sccr = cpm->im_cpm_intctl.sccr; 380 dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT; 381 #endif 382 get_sys_info (&sys_info); 383 gd->cpu_clk = sys_info.freqProcessor[0]; 384 gd->bus_clk = sys_info.freqSystemBus; 385 gd->mem_clk = sys_info.freqDDRBus; 386 gd->lbc_clk = sys_info.freqLocalBus; 387 388 #ifdef CONFIG_QE 389 gd->qe_clk = sys_info.freqQE; 390 gd->brg_clk = gd->qe_clk / 2; 391 #endif 392 /* 393 * The base clock for I2C depends on the actual SOC. Unfortunately, 394 * there is no pattern that can be used to determine the frequency, so 395 * the only choice is to look up the actual SOC number and use the value 396 * for that SOC. This information is taken from application note 397 * AN2919. 398 */ 399 #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ 400 defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) 401 gd->i2c1_clk = sys_info.freqSystemBus; 402 #elif defined(CONFIG_MPC8544) 403 /* 404 * On the 8544, the I2C clock is the same as the SEC clock. This can be 405 * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See 406 * 4.4.3.3 of the 8544 RM. Note that this might actually work for all 407 * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the 408 * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544. 409 */ 410 if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG) 411 gd->i2c1_clk = sys_info.freqSystemBus / 3; 412 else 413 gd->i2c1_clk = sys_info.freqSystemBus / 2; 414 #else 415 /* Most 85xx SOCs use CCB/2, so this is the default behavior. */ 416 gd->i2c1_clk = sys_info.freqSystemBus / 2; 417 #endif 418 gd->i2c2_clk = gd->i2c1_clk; 419 420 #if defined(CONFIG_FSL_ESDHC) 421 #if defined(CONFIG_MPC8569) || defined(CONFIG_P1010) ||\ 422 defined(CONFIG_P1014) 423 gd->sdhc_clk = gd->bus_clk; 424 #else 425 gd->sdhc_clk = gd->bus_clk / 2; 426 #endif 427 #endif /* defined(CONFIG_FSL_ESDHC) */ 428 429 #if defined(CONFIG_CPM2) 430 gd->vco_out = 2*sys_info.freqSystemBus; 431 gd->cpm_clk = gd->vco_out / 2; 432 gd->scc_clk = gd->vco_out / 4; 433 gd->brg_clk = gd->vco_out / (1 << (2 * (dfbrg + 1))); 434 #endif 435 436 if(gd->cpu_clk != 0) return (0); 437 else return (1); 438 } 439 440 441 /******************************************** 442 * get_bus_freq 443 * return system bus freq in Hz 444 *********************************************/ 445 ulong get_bus_freq (ulong dummy) 446 { 447 return gd->bus_clk; 448 } 449 450 /******************************************** 451 * get_ddr_freq 452 * return ddr bus freq in Hz 453 *********************************************/ 454 ulong get_ddr_freq (ulong dummy) 455 { 456 return gd->mem_clk; 457 } 458