1a47a12beSStefan Roese /* 2beba93edSDipen Dudhat * Copyright 2004, 2007-2011 Freescale Semiconductor, Inc. 3a47a12beSStefan Roese * 4a47a12beSStefan Roese * (C) Copyright 2003 Motorola Inc. 5a47a12beSStefan Roese * Xianghua Xiao, (X.Xiao@motorola.com) 6a47a12beSStefan Roese * 7a47a12beSStefan Roese * (C) Copyright 2000 8a47a12beSStefan Roese * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 9a47a12beSStefan Roese * 10a47a12beSStefan Roese * See file CREDITS for list of people who contributed to this 11a47a12beSStefan Roese * project. 12a47a12beSStefan Roese * 13a47a12beSStefan Roese * This program is free software; you can redistribute it and/or 14a47a12beSStefan Roese * modify it under the terms of the GNU General Public License as 15a47a12beSStefan Roese * published by the Free Software Foundation; either version 2 of 16a47a12beSStefan Roese * the License, or (at your option) any later version. 17a47a12beSStefan Roese * 18a47a12beSStefan Roese * This program is distributed in the hope that it will be useful, 19a47a12beSStefan Roese * but WITHOUT ANY WARRANTY; without even the implied warranty of 20a47a12beSStefan Roese * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21a47a12beSStefan Roese * GNU General Public License for more details. 22a47a12beSStefan Roese * 23a47a12beSStefan Roese * You should have received a copy of the GNU General Public License 24a47a12beSStefan Roese * along with this program; if not, write to the Free Software 25a47a12beSStefan Roese * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 26a47a12beSStefan Roese * MA 02111-1307 USA 27a47a12beSStefan Roese */ 28a47a12beSStefan Roese 29a47a12beSStefan Roese #include <common.h> 30a47a12beSStefan Roese #include <ppc_asm.tmpl> 31a52d2f81SHaiying Wang #include <linux/compiler.h> 32a47a12beSStefan Roese #include <asm/processor.h> 33a47a12beSStefan Roese #include <asm/io.h> 34a47a12beSStefan Roese 35a47a12beSStefan Roese DECLARE_GLOBAL_DATA_PTR; 36a47a12beSStefan Roese 37a47a12beSStefan Roese /* --------------------------------------------------------------- */ 38a47a12beSStefan Roese 39a47a12beSStefan Roese void get_sys_info (sys_info_t * sysInfo) 40a47a12beSStefan Roese { 41a47a12beSStefan Roese volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 42a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET 43a47a12beSStefan Roese volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR); 44fbb9ecf7STimur Tabi unsigned int cpu; 45a47a12beSStefan Roese 46a47a12beSStefan Roese const u8 core_cplx_PLL[16] = { 47a47a12beSStefan Roese [ 0] = 0, /* CC1 PPL / 1 */ 48a47a12beSStefan Roese [ 1] = 0, /* CC1 PPL / 2 */ 49a47a12beSStefan Roese [ 2] = 0, /* CC1 PPL / 4 */ 50a47a12beSStefan Roese [ 4] = 1, /* CC2 PPL / 1 */ 51a47a12beSStefan Roese [ 5] = 1, /* CC2 PPL / 2 */ 52a47a12beSStefan Roese [ 6] = 1, /* CC2 PPL / 4 */ 53a47a12beSStefan Roese [ 8] = 2, /* CC3 PPL / 1 */ 54a47a12beSStefan Roese [ 9] = 2, /* CC3 PPL / 2 */ 55a47a12beSStefan Roese [10] = 2, /* CC3 PPL / 4 */ 56a47a12beSStefan Roese [12] = 3, /* CC4 PPL / 1 */ 57a47a12beSStefan Roese [13] = 3, /* CC4 PPL / 2 */ 58a47a12beSStefan Roese [14] = 3, /* CC4 PPL / 4 */ 59a47a12beSStefan Roese }; 60a47a12beSStefan Roese 61a47a12beSStefan Roese const u8 core_cplx_PLL_div[16] = { 62a47a12beSStefan Roese [ 0] = 1, /* CC1 PPL / 1 */ 63a47a12beSStefan Roese [ 1] = 2, /* CC1 PPL / 2 */ 64a47a12beSStefan Roese [ 2] = 4, /* CC1 PPL / 4 */ 65a47a12beSStefan Roese [ 4] = 1, /* CC2 PPL / 1 */ 66a47a12beSStefan Roese [ 5] = 2, /* CC2 PPL / 2 */ 67a47a12beSStefan Roese [ 6] = 4, /* CC2 PPL / 4 */ 68a47a12beSStefan Roese [ 8] = 1, /* CC3 PPL / 1 */ 69a47a12beSStefan Roese [ 9] = 2, /* CC3 PPL / 2 */ 70a47a12beSStefan Roese [10] = 4, /* CC3 PPL / 4 */ 71a47a12beSStefan Roese [12] = 1, /* CC4 PPL / 1 */ 72a47a12beSStefan Roese [13] = 2, /* CC4 PPL / 2 */ 73a47a12beSStefan Roese [14] = 4, /* CC4 PPL / 4 */ 74a47a12beSStefan Roese }; 75a47a12beSStefan Roese uint lcrr_div, i, freqCC_PLL[4], rcw_tmp; 76ab48ca1aSSrikanth Srinivasan uint ratio[4]; 77a47a12beSStefan Roese unsigned long sysclk = CONFIG_SYS_CLK_FREQ; 78ab48ca1aSSrikanth Srinivasan uint mem_pll_rat; 79a47a12beSStefan Roese 80a47a12beSStefan Roese sysInfo->freqSystemBus = sysclk; 81a47a12beSStefan Roese sysInfo->freqDDRBus = sysclk; 82a47a12beSStefan Roese 83a47a12beSStefan Roese sysInfo->freqSystemBus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; 84ab48ca1aSSrikanth Srinivasan mem_pll_rat = (in_be32(&gur->rcwsr[0]) >> 17) & 0x1f; 85ab48ca1aSSrikanth Srinivasan if (mem_pll_rat > 2) 86ab48ca1aSSrikanth Srinivasan sysInfo->freqDDRBus *= mem_pll_rat; 87ab48ca1aSSrikanth Srinivasan else 88ab48ca1aSSrikanth Srinivasan sysInfo->freqDDRBus = sysInfo->freqSystemBus * mem_pll_rat; 89a47a12beSStefan Roese 90ab48ca1aSSrikanth Srinivasan ratio[0] = (in_be32(&clk->pllc1gsr) >> 1) & 0x3f; 91ab48ca1aSSrikanth Srinivasan ratio[1] = (in_be32(&clk->pllc2gsr) >> 1) & 0x3f; 92ab48ca1aSSrikanth Srinivasan ratio[2] = (in_be32(&clk->pllc3gsr) >> 1) & 0x3f; 93ab48ca1aSSrikanth Srinivasan ratio[3] = (in_be32(&clk->pllc4gsr) >> 1) & 0x3f; 94ab48ca1aSSrikanth Srinivasan for (i = 0; i < 4; i++) { 95ab48ca1aSSrikanth Srinivasan if (ratio[i] > 4) 96ab48ca1aSSrikanth Srinivasan freqCC_PLL[i] = sysclk * ratio[i]; 97ab48ca1aSSrikanth Srinivasan else 98ab48ca1aSSrikanth Srinivasan freqCC_PLL[i] = sysInfo->freqSystemBus * ratio[i]; 99ab48ca1aSSrikanth Srinivasan } 100a47a12beSStefan Roese rcw_tmp = in_be32(&gur->rcwsr[3]); 101fbb9ecf7STimur Tabi for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 102fbb9ecf7STimur Tabi u32 c_pll_sel = (in_be32(&clk->clkc0csr + cpu*8) >> 27) & 0xf; 103a47a12beSStefan Roese u32 cplx_pll = core_cplx_PLL[c_pll_sel]; 104a47a12beSStefan Roese 105fbb9ecf7STimur Tabi sysInfo->freqProcessor[cpu] = 106a47a12beSStefan Roese freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel]; 107a47a12beSStefan Roese } 108a47a12beSStefan Roese 109a47a12beSStefan Roese #define PME_CLK_SEL 0x80000000 110a47a12beSStefan Roese #define FM1_CLK_SEL 0x40000000 111a47a12beSStefan Roese #define FM2_CLK_SEL 0x20000000 112b5c8753fSKumar Gala #define HWA_ASYNC_DIV 0x04000000 113b5c8753fSKumar Gala #if (CONFIG_SYS_FSL_NUM_CC_PLLS == 2) 114b5c8753fSKumar Gala #define HWA_CC_PLL 1 115b5c8753fSKumar Gala #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 4) 116b5c8753fSKumar Gala #define HWA_CC_PLL 2 117b5c8753fSKumar Gala #else 118b5c8753fSKumar Gala #error CONFIG_SYS_FSL_NUM_CC_PLLS not set or unknown case 119b5c8753fSKumar Gala #endif 120a47a12beSStefan Roese rcw_tmp = in_be32(&gur->rcwsr[7]); 121a47a12beSStefan Roese 122a47a12beSStefan Roese #ifdef CONFIG_SYS_DPAA_PME 123b5c8753fSKumar Gala if (rcw_tmp & PME_CLK_SEL) { 124b5c8753fSKumar Gala if (rcw_tmp & HWA_ASYNC_DIV) 125b5c8753fSKumar Gala sysInfo->freqPME = freqCC_PLL[HWA_CC_PLL] / 4; 126a47a12beSStefan Roese else 127b5c8753fSKumar Gala sysInfo->freqPME = freqCC_PLL[HWA_CC_PLL] / 2; 128b5c8753fSKumar Gala } else { 129a47a12beSStefan Roese sysInfo->freqPME = sysInfo->freqSystemBus / 2; 130b5c8753fSKumar Gala } 131a47a12beSStefan Roese #endif 132a47a12beSStefan Roese 133a47a12beSStefan Roese #ifdef CONFIG_SYS_DPAA_FMAN 134b5c8753fSKumar Gala if (rcw_tmp & FM1_CLK_SEL) { 135b5c8753fSKumar Gala if (rcw_tmp & HWA_ASYNC_DIV) 136b5c8753fSKumar Gala sysInfo->freqFMan[0] = freqCC_PLL[HWA_CC_PLL] / 4; 137a47a12beSStefan Roese else 138b5c8753fSKumar Gala sysInfo->freqFMan[0] = freqCC_PLL[HWA_CC_PLL] / 2; 139b5c8753fSKumar Gala } else { 140a47a12beSStefan Roese sysInfo->freqFMan[0] = sysInfo->freqSystemBus / 2; 141b5c8753fSKumar Gala } 142a47a12beSStefan Roese #if (CONFIG_SYS_NUM_FMAN) == 2 143b5c8753fSKumar Gala if (rcw_tmp & FM2_CLK_SEL) { 144b5c8753fSKumar Gala if (rcw_tmp & HWA_ASYNC_DIV) 145b5c8753fSKumar Gala sysInfo->freqFMan[1] = freqCC_PLL[HWA_CC_PLL] / 4; 146a47a12beSStefan Roese else 147b5c8753fSKumar Gala sysInfo->freqFMan[1] = freqCC_PLL[HWA_CC_PLL] / 2; 148b5c8753fSKumar Gala } else { 149a47a12beSStefan Roese sysInfo->freqFMan[1] = sysInfo->freqSystemBus / 2; 150b5c8753fSKumar Gala } 151a47a12beSStefan Roese #endif 152a47a12beSStefan Roese #endif 153a47a12beSStefan Roese 154a47a12beSStefan Roese #else 155a47a12beSStefan Roese uint plat_ratio,e500_ratio,half_freqSystemBus; 156beba93edSDipen Dudhat #if defined(CONFIG_FSL_LBC) 157a47a12beSStefan Roese uint lcrr_div; 158beba93edSDipen Dudhat #endif 159a47a12beSStefan Roese int i; 160a47a12beSStefan Roese #ifdef CONFIG_QE 161a52d2f81SHaiying Wang __maybe_unused u32 qe_ratio; 162a47a12beSStefan Roese #endif 163a47a12beSStefan Roese 164a47a12beSStefan Roese plat_ratio = (gur->porpllsr) & 0x0000003e; 165a47a12beSStefan Roese plat_ratio >>= 1; 166a47a12beSStefan Roese sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ; 167a47a12beSStefan Roese 168a47a12beSStefan Roese /* Divide before multiply to avoid integer 169a47a12beSStefan Roese * overflow for processor speeds above 2GHz */ 170a47a12beSStefan Roese half_freqSystemBus = sysInfo->freqSystemBus/2; 171a47a12beSStefan Roese for (i = 0; i < cpu_numcores(); i++) { 172a47a12beSStefan Roese e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f; 173a47a12beSStefan Roese sysInfo->freqProcessor[i] = e500_ratio * half_freqSystemBus; 174a47a12beSStefan Roese } 175a47a12beSStefan Roese 176a47a12beSStefan Roese /* Note: freqDDRBus is the MCLK frequency, not the data rate. */ 177a47a12beSStefan Roese sysInfo->freqDDRBus = sysInfo->freqSystemBus; 178a47a12beSStefan Roese 179a47a12beSStefan Roese #ifdef CONFIG_DDR_CLK_FREQ 180a47a12beSStefan Roese { 181a47a12beSStefan Roese u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO) 182a47a12beSStefan Roese >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; 183a47a12beSStefan Roese if (ddr_ratio != 0x7) 184a47a12beSStefan Roese sysInfo->freqDDRBus = ddr_ratio * CONFIG_DDR_CLK_FREQ; 185a47a12beSStefan Roese } 186a47a12beSStefan Roese #endif 187a47a12beSStefan Roese 188a47a12beSStefan Roese #ifdef CONFIG_QE 189*be7bebeaSYork Sun #if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) 190a52d2f81SHaiying Wang sysInfo->freqQE = sysInfo->freqSystemBus; 191a52d2f81SHaiying Wang #else 192a47a12beSStefan Roese qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO) 193a47a12beSStefan Roese >> MPC85xx_PORPLLSR_QE_RATIO_SHIFT; 194a47a12beSStefan Roese sysInfo->freqQE = qe_ratio * CONFIG_SYS_CLK_FREQ; 195a47a12beSStefan Roese #endif 196a52d2f81SHaiying Wang #endif 197a47a12beSStefan Roese 19824995d82SHaiying Wang #ifdef CONFIG_SYS_DPAA_FMAN 199939cdcdcSKumar Gala sysInfo->freqFMan[0] = sysInfo->freqSystemBus; 20024995d82SHaiying Wang #endif 20124995d82SHaiying Wang 20224995d82SHaiying Wang #endif /* CONFIG_FSL_CORENET */ 20324995d82SHaiying Wang 204beba93edSDipen Dudhat #if defined(CONFIG_FSL_LBC) 205a47a12beSStefan Roese #if defined(CONFIG_SYS_LBC_LCRR) 206a47a12beSStefan Roese /* We will program LCRR to this value later */ 207a47a12beSStefan Roese lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; 208a47a12beSStefan Roese #else 209f51cdaf1SBecky Bruce lcrr_div = in_be32(&(LBC_BASE_ADDR)->lcrr) & LCRR_CLKDIV; 210a47a12beSStefan Roese #endif 211a47a12beSStefan Roese if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { 212a47a12beSStefan Roese #if defined(CONFIG_FSL_CORENET) 213a47a12beSStefan Roese /* If this is corenet based SoC, bit-representation 214a47a12beSStefan Roese * for four times the clock divider values. 215a47a12beSStefan Roese */ 216a47a12beSStefan Roese lcrr_div *= 4; 217a47a12beSStefan Roese #elif !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ 218a47a12beSStefan Roese !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) 219a47a12beSStefan Roese /* 220a47a12beSStefan Roese * Yes, the entire PQ38 family use the same 221a47a12beSStefan Roese * bit-representation for twice the clock divider values. 222a47a12beSStefan Roese */ 223a47a12beSStefan Roese lcrr_div *= 2; 224a47a12beSStefan Roese #endif 225a47a12beSStefan Roese sysInfo->freqLocalBus = sysInfo->freqSystemBus / lcrr_div; 226a47a12beSStefan Roese } else { 227a47a12beSStefan Roese /* In case anyone cares what the unknown value is */ 228a47a12beSStefan Roese sysInfo->freqLocalBus = lcrr_div; 229a47a12beSStefan Roese } 230beba93edSDipen Dudhat #endif 231a47a12beSStefan Roese } 232a47a12beSStefan Roese 233a47a12beSStefan Roese 234a47a12beSStefan Roese int get_clocks (void) 235a47a12beSStefan Roese { 236a47a12beSStefan Roese sys_info_t sys_info; 237a47a12beSStefan Roese #ifdef CONFIG_MPC8544 238a47a12beSStefan Roese volatile ccsr_gur_t *gur = (void *) CONFIG_SYS_MPC85xx_GUTS_ADDR; 239a47a12beSStefan Roese #endif 240a47a12beSStefan Roese #if defined(CONFIG_CPM2) 241a47a12beSStefan Roese volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR; 242a47a12beSStefan Roese uint sccr, dfbrg; 243a47a12beSStefan Roese 244a47a12beSStefan Roese /* set VCO = 4 * BRG */ 245a47a12beSStefan Roese cpm->im_cpm_intctl.sccr &= 0xfffffffc; 246a47a12beSStefan Roese sccr = cpm->im_cpm_intctl.sccr; 247a47a12beSStefan Roese dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT; 248a47a12beSStefan Roese #endif 249a47a12beSStefan Roese get_sys_info (&sys_info); 250a47a12beSStefan Roese gd->cpu_clk = sys_info.freqProcessor[0]; 251a47a12beSStefan Roese gd->bus_clk = sys_info.freqSystemBus; 252a47a12beSStefan Roese gd->mem_clk = sys_info.freqDDRBus; 253a47a12beSStefan Roese gd->lbc_clk = sys_info.freqLocalBus; 254a47a12beSStefan Roese 255a47a12beSStefan Roese #ifdef CONFIG_QE 256a47a12beSStefan Roese gd->qe_clk = sys_info.freqQE; 257a47a12beSStefan Roese gd->brg_clk = gd->qe_clk / 2; 258a47a12beSStefan Roese #endif 259a47a12beSStefan Roese /* 260a47a12beSStefan Roese * The base clock for I2C depends on the actual SOC. Unfortunately, 261a47a12beSStefan Roese * there is no pattern that can be used to determine the frequency, so 262a47a12beSStefan Roese * the only choice is to look up the actual SOC number and use the value 263a47a12beSStefan Roese * for that SOC. This information is taken from application note 264a47a12beSStefan Roese * AN2919. 265a47a12beSStefan Roese */ 266a47a12beSStefan Roese #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ 267a47a12beSStefan Roese defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) 268a47a12beSStefan Roese gd->i2c1_clk = sys_info.freqSystemBus; 269a47a12beSStefan Roese #elif defined(CONFIG_MPC8544) 270a47a12beSStefan Roese /* 271a47a12beSStefan Roese * On the 8544, the I2C clock is the same as the SEC clock. This can be 272a47a12beSStefan Roese * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See 273a47a12beSStefan Roese * 4.4.3.3 of the 8544 RM. Note that this might actually work for all 274a47a12beSStefan Roese * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the 275a47a12beSStefan Roese * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544. 276a47a12beSStefan Roese */ 277a47a12beSStefan Roese if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG) 278a47a12beSStefan Roese gd->i2c1_clk = sys_info.freqSystemBus / 3; 279a47a12beSStefan Roese else 280a47a12beSStefan Roese gd->i2c1_clk = sys_info.freqSystemBus / 2; 281a47a12beSStefan Roese #else 282a47a12beSStefan Roese /* Most 85xx SOCs use CCB/2, so this is the default behavior. */ 283a47a12beSStefan Roese gd->i2c1_clk = sys_info.freqSystemBus / 2; 284a47a12beSStefan Roese #endif 285a47a12beSStefan Roese gd->i2c2_clk = gd->i2c1_clk; 286a47a12beSStefan Roese 287a47a12beSStefan Roese #if defined(CONFIG_FSL_ESDHC) 2887d640e9bSPriyanka Jain #if defined(CONFIG_MPC8569) || defined(CONFIG_P1010) ||\ 2897d640e9bSPriyanka Jain defined(CONFIG_P1014) 290a47a12beSStefan Roese gd->sdhc_clk = gd->bus_clk; 291a47a12beSStefan Roese #else 292a47a12beSStefan Roese gd->sdhc_clk = gd->bus_clk / 2; 293a47a12beSStefan Roese #endif 294a47a12beSStefan Roese #endif /* defined(CONFIG_FSL_ESDHC) */ 295a47a12beSStefan Roese 296a47a12beSStefan Roese #if defined(CONFIG_CPM2) 297a47a12beSStefan Roese gd->vco_out = 2*sys_info.freqSystemBus; 298a47a12beSStefan Roese gd->cpm_clk = gd->vco_out / 2; 299a47a12beSStefan Roese gd->scc_clk = gd->vco_out / 4; 300a47a12beSStefan Roese gd->brg_clk = gd->vco_out / (1 << (2 * (dfbrg + 1))); 301a47a12beSStefan Roese #endif 302a47a12beSStefan Roese 303a47a12beSStefan Roese if(gd->cpu_clk != 0) return (0); 304a47a12beSStefan Roese else return (1); 305a47a12beSStefan Roese } 306a47a12beSStefan Roese 307a47a12beSStefan Roese 308a47a12beSStefan Roese /******************************************** 309a47a12beSStefan Roese * get_bus_freq 310a47a12beSStefan Roese * return system bus freq in Hz 311a47a12beSStefan Roese *********************************************/ 312a47a12beSStefan Roese ulong get_bus_freq (ulong dummy) 313a47a12beSStefan Roese { 314a47a12beSStefan Roese return gd->bus_clk; 315a47a12beSStefan Roese } 316a47a12beSStefan Roese 317a47a12beSStefan Roese /******************************************** 318a47a12beSStefan Roese * get_ddr_freq 319a47a12beSStefan Roese * return ddr bus freq in Hz 320a47a12beSStefan Roese *********************************************/ 321a47a12beSStefan Roese ulong get_ddr_freq (ulong dummy) 322a47a12beSStefan Roese { 323a47a12beSStefan Roese return gd->mem_clk; 324a47a12beSStefan Roese } 325