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 * 101a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 11a47a12beSStefan Roese */ 12a47a12beSStefan Roese 13a47a12beSStefan Roese #include <common.h> 14a47a12beSStefan Roese #include <ppc_asm.tmpl> 15a52d2f81SHaiying Wang #include <linux/compiler.h> 16a47a12beSStefan Roese #include <asm/processor.h> 17a47a12beSStefan Roese #include <asm/io.h> 18a47a12beSStefan Roese 19a47a12beSStefan Roese DECLARE_GLOBAL_DATA_PTR; 20a47a12beSStefan Roese 21ce746fe0SPrabhakar Kushwaha 22ce746fe0SPrabhakar Kushwaha #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS 23ce746fe0SPrabhakar Kushwaha #define CONFIG_SYS_FSL_NUM_CC_PLLS 6 24ce746fe0SPrabhakar Kushwaha #endif 25a47a12beSStefan Roese /* --------------------------------------------------------------- */ 26a47a12beSStefan Roese 27997399faSPrabhakar Kushwaha void get_sys_info(sys_info_t *sys_info) 28a47a12beSStefan Roese { 29a47a12beSStefan Roese volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 30800c73c4SKumar Gala #ifdef CONFIG_FSL_IFC 31800c73c4SKumar Gala struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; 32800c73c4SKumar Gala u32 ccr; 33800c73c4SKumar Gala #endif 34a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET 35a47a12beSStefan Roese volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR); 36fbb9ecf7STimur Tabi unsigned int cpu; 37ce746fe0SPrabhakar Kushwaha #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 38ce746fe0SPrabhakar Kushwaha int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS; 39ce746fe0SPrabhakar Kushwaha #endif 40a47a12beSStefan Roese 41a47a12beSStefan Roese const u8 core_cplx_PLL[16] = { 42a47a12beSStefan Roese [ 0] = 0, /* CC1 PPL / 1 */ 43a47a12beSStefan Roese [ 1] = 0, /* CC1 PPL / 2 */ 44a47a12beSStefan Roese [ 2] = 0, /* CC1 PPL / 4 */ 45a47a12beSStefan Roese [ 4] = 1, /* CC2 PPL / 1 */ 46a47a12beSStefan Roese [ 5] = 1, /* CC2 PPL / 2 */ 47a47a12beSStefan Roese [ 6] = 1, /* CC2 PPL / 4 */ 48a47a12beSStefan Roese [ 8] = 2, /* CC3 PPL / 1 */ 49a47a12beSStefan Roese [ 9] = 2, /* CC3 PPL / 2 */ 50a47a12beSStefan Roese [10] = 2, /* CC3 PPL / 4 */ 51a47a12beSStefan Roese [12] = 3, /* CC4 PPL / 1 */ 52a47a12beSStefan Roese [13] = 3, /* CC4 PPL / 2 */ 53a47a12beSStefan Roese [14] = 3, /* CC4 PPL / 4 */ 54a47a12beSStefan Roese }; 55a47a12beSStefan Roese 56997399faSPrabhakar Kushwaha const u8 core_cplx_pll_div[16] = { 57a47a12beSStefan Roese [ 0] = 1, /* CC1 PPL / 1 */ 58a47a12beSStefan Roese [ 1] = 2, /* CC1 PPL / 2 */ 59a47a12beSStefan Roese [ 2] = 4, /* CC1 PPL / 4 */ 60a47a12beSStefan Roese [ 4] = 1, /* CC2 PPL / 1 */ 61a47a12beSStefan Roese [ 5] = 2, /* CC2 PPL / 2 */ 62a47a12beSStefan Roese [ 6] = 4, /* CC2 PPL / 4 */ 63a47a12beSStefan Roese [ 8] = 1, /* CC3 PPL / 1 */ 64a47a12beSStefan Roese [ 9] = 2, /* CC3 PPL / 2 */ 65a47a12beSStefan Roese [10] = 4, /* CC3 PPL / 4 */ 66a47a12beSStefan Roese [12] = 1, /* CC4 PPL / 1 */ 67a47a12beSStefan Roese [13] = 2, /* CC4 PPL / 2 */ 68a47a12beSStefan Roese [14] = 4, /* CC4 PPL / 4 */ 69a47a12beSStefan Roese }; 70ce746fe0SPrabhakar Kushwaha uint i, freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS]; 71ce746fe0SPrabhakar Kushwaha #if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV) 72ce746fe0SPrabhakar Kushwaha uint rcw_tmp; 73ce746fe0SPrabhakar Kushwaha #endif 74ce746fe0SPrabhakar Kushwaha uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS]; 75a47a12beSStefan Roese unsigned long sysclk = CONFIG_SYS_CLK_FREQ; 76ab48ca1aSSrikanth Srinivasan uint mem_pll_rat; 77*b135991aSPriyanka Jain #ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK 78*b135991aSPriyanka Jain uint single_src; 79*b135991aSPriyanka Jain #endif 80a47a12beSStefan Roese 81997399faSPrabhakar Kushwaha sys_info->freq_systembus = sysclk; 82*b135991aSPriyanka Jain #ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK 83*b135991aSPriyanka Jain /* 84*b135991aSPriyanka Jain * DDR_REFCLK_SEL rcw bit is used to determine if DDR PLLS 85*b135991aSPriyanka Jain * are driven by separate DDR Refclock or single source 86*b135991aSPriyanka Jain * differential clock. 87*b135991aSPriyanka Jain */ 88*b135991aSPriyanka Jain single_src = (in_be32(&gur->rcwsr[5]) >> 89*b135991aSPriyanka Jain FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT) & 90*b135991aSPriyanka Jain FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK; 91*b135991aSPriyanka Jain /* 92*b135991aSPriyanka Jain * For single source clocking, both ddrclock and syclock 93*b135991aSPriyanka Jain * are driven by differential sysclock. 94*b135991aSPriyanka Jain */ 95*b135991aSPriyanka Jain if (single_src == FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK) { 96*b135991aSPriyanka Jain printf("Single Source Clock Configuration\n"); 97*b135991aSPriyanka Jain sys_info->freq_ddrbus = CONFIG_SYS_CLK_FREQ; 98*b135991aSPriyanka Jain } else 99*b135991aSPriyanka Jain #endif 10098ffa190SYork Sun #ifdef CONFIG_DDR_CLK_FREQ 101997399faSPrabhakar Kushwaha sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; 10298ffa190SYork Sun #else 103997399faSPrabhakar Kushwaha sys_info->freq_ddrbus = sysclk; 10498ffa190SYork Sun #endif 105a47a12beSStefan Roese 106997399faSPrabhakar Kushwaha sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; 107f77329cfSYork Sun mem_pll_rat = (in_be32(&gur->rcwsr[0]) >> 108f77329cfSYork Sun FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT) 109f77329cfSYork Sun & FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK; 110e88f421eSZang Roy-R61911 /* T4240/T4160 Rev2.0 MEM_PLL_RAT uses a value which is half of 111e88f421eSZang Roy-R61911 * T4240/T4160 Rev1.0. eg. It's 12 in Rev1.0, however, for Rev2.0 112e88f421eSZang Roy-R61911 * it uses 6. 113e88f421eSZang Roy-R61911 */ 114e88f421eSZang Roy-R61911 #if defined(CONFIG_PPC_T4240) || defined(CONFIG_PPC_T4160) 115e88f421eSZang Roy-R61911 if (SVR_MAJ(get_svr()) >= 2) 116e88f421eSZang Roy-R61911 mem_pll_rat *= 2; 117e88f421eSZang Roy-R61911 #endif 118ab48ca1aSSrikanth Srinivasan if (mem_pll_rat > 2) 119997399faSPrabhakar Kushwaha sys_info->freq_ddrbus *= mem_pll_rat; 120ab48ca1aSSrikanth Srinivasan else 121997399faSPrabhakar Kushwaha sys_info->freq_ddrbus = sys_info->freq_systembus * mem_pll_rat; 122a47a12beSStefan Roese 123ce746fe0SPrabhakar Kushwaha for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) { 124ce746fe0SPrabhakar Kushwaha ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f; 125ab48ca1aSSrikanth Srinivasan if (ratio[i] > 4) 126ce746fe0SPrabhakar Kushwaha freq_c_pll[i] = sysclk * ratio[i]; 127ab48ca1aSSrikanth Srinivasan else 128ce746fe0SPrabhakar Kushwaha freq_c_pll[i] = sys_info->freq_systembus * ratio[i]; 129ab48ca1aSSrikanth Srinivasan } 1309a653a98SYork Sun #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 1319a653a98SYork Sun /* 132ce746fe0SPrabhakar Kushwaha * As per CHASSIS2 architeture total 12 clusters are posible and 1339a653a98SYork Sun * Each cluster has up to 4 cores, sharing the same PLL selection. 134ce746fe0SPrabhakar Kushwaha * The cluster clock assignment is SoC defined. 135ce746fe0SPrabhakar Kushwaha * 136ce746fe0SPrabhakar Kushwaha * Total 4 clock groups are possible with 3 PLLs each. 137ce746fe0SPrabhakar Kushwaha * as per array indices, clock group A has 0, 1, 2 numbered PLLs & 138ce746fe0SPrabhakar Kushwaha * clock group B has 3, 4, 6 and so on. 139ce746fe0SPrabhakar Kushwaha * 140ce746fe0SPrabhakar Kushwaha * Clock group A having PLL1, PLL2, PLL3, feeding cores of any cluster 141ce746fe0SPrabhakar Kushwaha * depends upon the SoC architeture. Same applies to other 142ce746fe0SPrabhakar Kushwaha * clock groups and clusters. 143ce746fe0SPrabhakar Kushwaha * 1449a653a98SYork Sun */ 1459a653a98SYork Sun for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 146f6981439SYork Sun int cluster = fsl_qoriq_core_to_cluster(cpu); 147f6981439SYork Sun u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27) 1489a653a98SYork Sun & 0xf; 1499a653a98SYork Sun u32 cplx_pll = core_cplx_PLL[c_pll_sel]; 150ce746fe0SPrabhakar Kushwaha cplx_pll += cc_group[cluster] - 1; 151997399faSPrabhakar Kushwaha sys_info->freq_processor[cpu] = 152ce746fe0SPrabhakar Kushwaha freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; 1539a653a98SYork Sun } 154629d6b32SShengzhou Liu #if defined(CONFIG_PPC_B4860) || defined(CONFIG_PPC_T2080) 1550cb3325cSSandeep Singh #define FM1_CLK_SEL 0xe0000000 1560cb3325cSSandeep Singh #define FM1_CLK_SHIFT 29 1570cb3325cSSandeep Singh #else 1589a653a98SYork Sun #define PME_CLK_SEL 0xe0000000 1599a653a98SYork Sun #define PME_CLK_SHIFT 29 1609a653a98SYork Sun #define FM1_CLK_SEL 0x1c000000 1619a653a98SYork Sun #define FM1_CLK_SHIFT 26 1620cb3325cSSandeep Singh #endif 163ce746fe0SPrabhakar Kushwaha #if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV) 1649a653a98SYork Sun rcw_tmp = in_be32(&gur->rcwsr[7]); 165ce746fe0SPrabhakar Kushwaha #endif 1669a653a98SYork Sun 1679a653a98SYork Sun #ifdef CONFIG_SYS_DPAA_PME 168ce746fe0SPrabhakar Kushwaha #ifndef CONFIG_PME_PLAT_CLK_DIV 1699a653a98SYork Sun switch ((rcw_tmp & PME_CLK_SEL) >> PME_CLK_SHIFT) { 1709a653a98SYork Sun case 1: 171ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK]; 1729a653a98SYork Sun break; 1739a653a98SYork Sun case 2: 174ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 2; 1759a653a98SYork Sun break; 1769a653a98SYork Sun case 3: 177ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 3; 1789a653a98SYork Sun break; 1799a653a98SYork Sun case 4: 180ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 4; 1819a653a98SYork Sun break; 1829a653a98SYork Sun case 6: 183ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK + 1] / 2; 1849a653a98SYork Sun break; 1859a653a98SYork Sun case 7: 186ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK + 1] / 3; 1879a653a98SYork Sun break; 1889a653a98SYork Sun default: 1899a653a98SYork Sun printf("Error: Unknown PME clock select!\n"); 1909a653a98SYork Sun case 0: 191997399faSPrabhakar Kushwaha sys_info->freq_pme = sys_info->freq_systembus / 2; 1929a653a98SYork Sun break; 1939a653a98SYork Sun 1949a653a98SYork Sun } 195ce746fe0SPrabhakar Kushwaha #else 196ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = sys_info->freq_systembus / CONFIG_SYS_PME_CLK; 197ce746fe0SPrabhakar Kushwaha 198ce746fe0SPrabhakar Kushwaha #endif 1999a653a98SYork Sun #endif 2009a653a98SYork Sun 201990e1a8cSHaiying Wang #ifdef CONFIG_SYS_DPAA_QBMAN 202997399faSPrabhakar Kushwaha sys_info->freq_qman = sys_info->freq_systembus / 2; 203990e1a8cSHaiying Wang #endif 204990e1a8cSHaiying Wang 2059a653a98SYork Sun #ifdef CONFIG_SYS_DPAA_FMAN 206ce746fe0SPrabhakar Kushwaha #ifndef CONFIG_FM_PLAT_CLK_DIV 2079a653a98SYork Sun switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) { 2089a653a98SYork Sun case 1: 209ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK]; 2109a653a98SYork Sun break; 2119a653a98SYork Sun case 2: 212ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 2; 2139a653a98SYork Sun break; 2149a653a98SYork Sun case 3: 215ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 3; 2169a653a98SYork Sun break; 2179a653a98SYork Sun case 4: 218ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 4; 2199a653a98SYork Sun break; 2200cb3325cSSandeep Singh case 5: 221997399faSPrabhakar Kushwaha sys_info->freq_fman[0] = sys_info->freq_systembus; 2220cb3325cSSandeep Singh break; 2239a653a98SYork Sun case 6: 224ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK + 1] / 2; 2259a653a98SYork Sun break; 2269a653a98SYork Sun case 7: 227ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK + 1] / 3; 2289a653a98SYork Sun break; 2299a653a98SYork Sun default: 2309a653a98SYork Sun printf("Error: Unknown FMan1 clock select!\n"); 2319a653a98SYork Sun case 0: 232997399faSPrabhakar Kushwaha sys_info->freq_fman[0] = sys_info->freq_systembus / 2; 2339a653a98SYork Sun break; 2349a653a98SYork Sun } 2359a653a98SYork Sun #if (CONFIG_SYS_NUM_FMAN) == 2 236ce746fe0SPrabhakar Kushwaha #ifdef CONFIG_SYS_FM2_CLK 2379a653a98SYork Sun #define FM2_CLK_SEL 0x00000038 2389a653a98SYork Sun #define FM2_CLK_SHIFT 3 2399a653a98SYork Sun rcw_tmp = in_be32(&gur->rcwsr[15]); 2409a653a98SYork Sun switch ((rcw_tmp & FM2_CLK_SEL) >> FM2_CLK_SHIFT) { 2419a653a98SYork Sun case 1: 242ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1]; 2439a653a98SYork Sun break; 2449a653a98SYork Sun case 2: 245ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 2; 2469a653a98SYork Sun break; 2479a653a98SYork Sun case 3: 248ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 3; 2499a653a98SYork Sun break; 2509a653a98SYork Sun case 4: 251ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 4; 2529a653a98SYork Sun break; 253c1015c67SShaohui Xie case 5: 254c1015c67SShaohui Xie sys_info->freq_fman[1] = sys_info->freq_systembus; 255c1015c67SShaohui Xie break; 2569a653a98SYork Sun case 6: 257ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 2; 2589a653a98SYork Sun break; 2599a653a98SYork Sun case 7: 260ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 3; 2619a653a98SYork Sun break; 2629a653a98SYork Sun default: 2639a653a98SYork Sun printf("Error: Unknown FMan2 clock select!\n"); 2649a653a98SYork Sun case 0: 265997399faSPrabhakar Kushwaha sys_info->freq_fman[1] = sys_info->freq_systembus / 2; 2669a653a98SYork Sun break; 2679a653a98SYork Sun } 268ce746fe0SPrabhakar Kushwaha #endif 2699a653a98SYork Sun #endif /* CONFIG_SYS_NUM_FMAN == 2 */ 270ce746fe0SPrabhakar Kushwaha #else 271ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = sys_info->freq_systembus / CONFIG_SYS_FM1_CLK; 272ce746fe0SPrabhakar Kushwaha #endif 273ce746fe0SPrabhakar Kushwaha #endif 2749a653a98SYork Sun 2759a653a98SYork Sun #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 2769a653a98SYork Sun 277fbb9ecf7STimur Tabi for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 278f6981439SYork Sun u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27) 279f6981439SYork Sun & 0xf; 280a47a12beSStefan Roese u32 cplx_pll = core_cplx_PLL[c_pll_sel]; 281a47a12beSStefan Roese 282997399faSPrabhakar Kushwaha sys_info->freq_processor[cpu] = 283ce746fe0SPrabhakar Kushwaha freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; 284a47a12beSStefan Roese } 285a47a12beSStefan Roese #define PME_CLK_SEL 0x80000000 286a47a12beSStefan Roese #define FM1_CLK_SEL 0x40000000 287a47a12beSStefan Roese #define FM2_CLK_SEL 0x20000000 288b5c8753fSKumar Gala #define HWA_ASYNC_DIV 0x04000000 289b5c8753fSKumar Gala #if (CONFIG_SYS_FSL_NUM_CC_PLLS == 2) 290b5c8753fSKumar Gala #define HWA_CC_PLL 1 2914905443fSTimur Tabi #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 3) 2924905443fSTimur Tabi #define HWA_CC_PLL 2 293b5c8753fSKumar Gala #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 4) 294b5c8753fSKumar Gala #define HWA_CC_PLL 2 295b5c8753fSKumar Gala #else 296b5c8753fSKumar Gala #error CONFIG_SYS_FSL_NUM_CC_PLLS not set or unknown case 297b5c8753fSKumar Gala #endif 298a47a12beSStefan Roese rcw_tmp = in_be32(&gur->rcwsr[7]); 299a47a12beSStefan Roese 300a47a12beSStefan Roese #ifdef CONFIG_SYS_DPAA_PME 301b5c8753fSKumar Gala if (rcw_tmp & PME_CLK_SEL) { 302b5c8753fSKumar Gala if (rcw_tmp & HWA_ASYNC_DIV) 303ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = freq_c_pll[HWA_CC_PLL] / 4; 304a47a12beSStefan Roese else 305ce746fe0SPrabhakar Kushwaha sys_info->freq_pme = freq_c_pll[HWA_CC_PLL] / 2; 306b5c8753fSKumar Gala } else { 307997399faSPrabhakar Kushwaha sys_info->freq_pme = sys_info->freq_systembus / 2; 308b5c8753fSKumar Gala } 309a47a12beSStefan Roese #endif 310a47a12beSStefan Roese 311a47a12beSStefan Roese #ifdef CONFIG_SYS_DPAA_FMAN 312b5c8753fSKumar Gala if (rcw_tmp & FM1_CLK_SEL) { 313b5c8753fSKumar Gala if (rcw_tmp & HWA_ASYNC_DIV) 314ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = freq_c_pll[HWA_CC_PLL] / 4; 315a47a12beSStefan Roese else 316ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[0] = freq_c_pll[HWA_CC_PLL] / 2; 317b5c8753fSKumar Gala } else { 318997399faSPrabhakar Kushwaha sys_info->freq_fman[0] = sys_info->freq_systembus / 2; 319b5c8753fSKumar Gala } 320a47a12beSStefan Roese #if (CONFIG_SYS_NUM_FMAN) == 2 321b5c8753fSKumar Gala if (rcw_tmp & FM2_CLK_SEL) { 322b5c8753fSKumar Gala if (rcw_tmp & HWA_ASYNC_DIV) 323ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[1] = freq_c_pll[HWA_CC_PLL] / 4; 324a47a12beSStefan Roese else 325ce746fe0SPrabhakar Kushwaha sys_info->freq_fman[1] = freq_c_pll[HWA_CC_PLL] / 2; 326b5c8753fSKumar Gala } else { 327997399faSPrabhakar Kushwaha sys_info->freq_fman[1] = sys_info->freq_systembus / 2; 328b5c8753fSKumar Gala } 329a47a12beSStefan Roese #endif 330a47a12beSStefan Roese #endif 331a47a12beSStefan Roese 3323e83fc9bSShaohui Xie #ifdef CONFIG_SYS_DPAA_QBMAN 333997399faSPrabhakar Kushwaha sys_info->freq_qman = sys_info->freq_systembus / 2; 3343e83fc9bSShaohui Xie #endif 3353e83fc9bSShaohui Xie 3369a653a98SYork Sun #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 3379a653a98SYork Sun 3389a653a98SYork Sun #else /* CONFIG_FSL_CORENET */ 339997399faSPrabhakar Kushwaha uint plat_ratio, e500_ratio, half_freq_systembus; 340a47a12beSStefan Roese int i; 341a47a12beSStefan Roese #ifdef CONFIG_QE 342a52d2f81SHaiying Wang __maybe_unused u32 qe_ratio; 343a47a12beSStefan Roese #endif 344a47a12beSStefan Roese 345a47a12beSStefan Roese plat_ratio = (gur->porpllsr) & 0x0000003e; 346a47a12beSStefan Roese plat_ratio >>= 1; 347997399faSPrabhakar Kushwaha sys_info->freq_systembus = plat_ratio * CONFIG_SYS_CLK_FREQ; 348a47a12beSStefan Roese 349a47a12beSStefan Roese /* Divide before multiply to avoid integer 350a47a12beSStefan Roese * overflow for processor speeds above 2GHz */ 351997399faSPrabhakar Kushwaha half_freq_systembus = sys_info->freq_systembus/2; 352a47a12beSStefan Roese for (i = 0; i < cpu_numcores(); i++) { 353a47a12beSStefan Roese e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f; 354997399faSPrabhakar Kushwaha sys_info->freq_processor[i] = e500_ratio * half_freq_systembus; 355a47a12beSStefan Roese } 356a47a12beSStefan Roese 357997399faSPrabhakar Kushwaha /* Note: freq_ddrbus is the MCLK frequency, not the data rate. */ 358997399faSPrabhakar Kushwaha sys_info->freq_ddrbus = sys_info->freq_systembus; 359a47a12beSStefan Roese 360a47a12beSStefan Roese #ifdef CONFIG_DDR_CLK_FREQ 361a47a12beSStefan Roese { 362a47a12beSStefan Roese u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO) 363a47a12beSStefan Roese >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; 364a47a12beSStefan Roese if (ddr_ratio != 0x7) 365997399faSPrabhakar Kushwaha sys_info->freq_ddrbus = ddr_ratio * CONFIG_DDR_CLK_FREQ; 366a47a12beSStefan Roese } 367a47a12beSStefan Roese #endif 368a47a12beSStefan Roese 369a47a12beSStefan Roese #ifdef CONFIG_QE 370be7bebeaSYork Sun #if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) 371997399faSPrabhakar Kushwaha sys_info->freq_qe = sys_info->freq_systembus; 372a52d2f81SHaiying Wang #else 373a47a12beSStefan Roese qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO) 374a47a12beSStefan Roese >> MPC85xx_PORPLLSR_QE_RATIO_SHIFT; 375997399faSPrabhakar Kushwaha sys_info->freq_qe = qe_ratio * CONFIG_SYS_CLK_FREQ; 376a47a12beSStefan Roese #endif 377a52d2f81SHaiying Wang #endif 378a47a12beSStefan Roese 37924995d82SHaiying Wang #ifdef CONFIG_SYS_DPAA_FMAN 380997399faSPrabhakar Kushwaha sys_info->freq_fman[0] = sys_info->freq_systembus; 38124995d82SHaiying Wang #endif 38224995d82SHaiying Wang 38324995d82SHaiying Wang #endif /* CONFIG_FSL_CORENET */ 38424995d82SHaiying Wang 385beba93edSDipen Dudhat #if defined(CONFIG_FSL_LBC) 3869a653a98SYork Sun uint lcrr_div; 387a47a12beSStefan Roese #if defined(CONFIG_SYS_LBC_LCRR) 388a47a12beSStefan Roese /* We will program LCRR to this value later */ 389a47a12beSStefan Roese lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; 390a47a12beSStefan Roese #else 391f51cdaf1SBecky Bruce lcrr_div = in_be32(&(LBC_BASE_ADDR)->lcrr) & LCRR_CLKDIV; 392a47a12beSStefan Roese #endif 393a47a12beSStefan Roese if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { 394a47a12beSStefan Roese #if defined(CONFIG_FSL_CORENET) 395a47a12beSStefan Roese /* If this is corenet based SoC, bit-representation 396a47a12beSStefan Roese * for four times the clock divider values. 397a47a12beSStefan Roese */ 398a47a12beSStefan Roese lcrr_div *= 4; 399a47a12beSStefan Roese #elif !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ 400a47a12beSStefan Roese !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) 401a47a12beSStefan Roese /* 402a47a12beSStefan Roese * Yes, the entire PQ38 family use the same 403a47a12beSStefan Roese * bit-representation for twice the clock divider values. 404a47a12beSStefan Roese */ 405a47a12beSStefan Roese lcrr_div *= 2; 406a47a12beSStefan Roese #endif 407997399faSPrabhakar Kushwaha sys_info->freq_localbus = sys_info->freq_systembus / lcrr_div; 408a47a12beSStefan Roese } else { 409a47a12beSStefan Roese /* In case anyone cares what the unknown value is */ 410997399faSPrabhakar Kushwaha sys_info->freq_localbus = lcrr_div; 411a47a12beSStefan Roese } 412beba93edSDipen Dudhat #endif 413800c73c4SKumar Gala 414800c73c4SKumar Gala #if defined(CONFIG_FSL_IFC) 415800c73c4SKumar Gala ccr = in_be32(&ifc_regs->ifc_ccr); 416800c73c4SKumar Gala ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; 417800c73c4SKumar Gala 418997399faSPrabhakar Kushwaha sys_info->freq_localbus = sys_info->freq_systembus / ccr; 419800c73c4SKumar Gala #endif 420a47a12beSStefan Roese } 421a47a12beSStefan Roese 422a47a12beSStefan Roese 423a47a12beSStefan Roese int get_clocks (void) 424a47a12beSStefan Roese { 425a47a12beSStefan Roese sys_info_t sys_info; 426a47a12beSStefan Roese #ifdef CONFIG_MPC8544 427a47a12beSStefan Roese volatile ccsr_gur_t *gur = (void *) CONFIG_SYS_MPC85xx_GUTS_ADDR; 428a47a12beSStefan Roese #endif 429a47a12beSStefan Roese #if defined(CONFIG_CPM2) 430a47a12beSStefan Roese volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR; 431a47a12beSStefan Roese uint sccr, dfbrg; 432a47a12beSStefan Roese 433a47a12beSStefan Roese /* set VCO = 4 * BRG */ 434a47a12beSStefan Roese cpm->im_cpm_intctl.sccr &= 0xfffffffc; 435a47a12beSStefan Roese sccr = cpm->im_cpm_intctl.sccr; 436a47a12beSStefan Roese dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT; 437a47a12beSStefan Roese #endif 438a47a12beSStefan Roese get_sys_info (&sys_info); 439997399faSPrabhakar Kushwaha gd->cpu_clk = sys_info.freq_processor[0]; 440997399faSPrabhakar Kushwaha gd->bus_clk = sys_info.freq_systembus; 441997399faSPrabhakar Kushwaha gd->mem_clk = sys_info.freq_ddrbus; 442997399faSPrabhakar Kushwaha gd->arch.lbc_clk = sys_info.freq_localbus; 443a47a12beSStefan Roese 444a47a12beSStefan Roese #ifdef CONFIG_QE 445997399faSPrabhakar Kushwaha gd->arch.qe_clk = sys_info.freq_qe; 44645bae2e3SSimon Glass gd->arch.brg_clk = gd->arch.qe_clk / 2; 447a47a12beSStefan Roese #endif 448a47a12beSStefan Roese /* 449a47a12beSStefan Roese * The base clock for I2C depends on the actual SOC. Unfortunately, 450a47a12beSStefan Roese * there is no pattern that can be used to determine the frequency, so 451a47a12beSStefan Roese * the only choice is to look up the actual SOC number and use the value 452a47a12beSStefan Roese * for that SOC. This information is taken from application note 453a47a12beSStefan Roese * AN2919. 454a47a12beSStefan Roese */ 455a47a12beSStefan Roese #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ 456f62b1238STang Yuantian defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) || \ 457f62b1238STang Yuantian defined(CONFIG_P1022) 458997399faSPrabhakar Kushwaha gd->arch.i2c1_clk = sys_info.freq_systembus; 459a47a12beSStefan Roese #elif defined(CONFIG_MPC8544) 460a47a12beSStefan Roese /* 461a47a12beSStefan Roese * On the 8544, the I2C clock is the same as the SEC clock. This can be 462a47a12beSStefan Roese * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See 463a47a12beSStefan Roese * 4.4.3.3 of the 8544 RM. Note that this might actually work for all 464a47a12beSStefan Roese * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the 465a47a12beSStefan Roese * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544. 466a47a12beSStefan Roese */ 467a47a12beSStefan Roese if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG) 468997399faSPrabhakar Kushwaha gd->arch.i2c1_clk = sys_info.freq_systembus / 3; 469a47a12beSStefan Roese else 470997399faSPrabhakar Kushwaha gd->arch.i2c1_clk = sys_info.freq_systembus / 2; 471a47a12beSStefan Roese #else 472a47a12beSStefan Roese /* Most 85xx SOCs use CCB/2, so this is the default behavior. */ 473997399faSPrabhakar Kushwaha gd->arch.i2c1_clk = sys_info.freq_systembus / 2; 474a47a12beSStefan Roese #endif 475609e6ec3SSimon Glass gd->arch.i2c2_clk = gd->arch.i2c1_clk; 476a47a12beSStefan Roese 477a47a12beSStefan Roese #if defined(CONFIG_FSL_ESDHC) 4787d640e9bSPriyanka Jain #if defined(CONFIG_MPC8569) || defined(CONFIG_P1010) ||\ 4797d640e9bSPriyanka Jain defined(CONFIG_P1014) 480e9adeca3SSimon Glass gd->arch.sdhc_clk = gd->bus_clk; 481a47a12beSStefan Roese #else 482e9adeca3SSimon Glass gd->arch.sdhc_clk = gd->bus_clk / 2; 483a47a12beSStefan Roese #endif 484a47a12beSStefan Roese #endif /* defined(CONFIG_FSL_ESDHC) */ 485a47a12beSStefan Roese 486a47a12beSStefan Roese #if defined(CONFIG_CPM2) 487997399faSPrabhakar Kushwaha gd->arch.vco_out = 2*sys_info.freq_systembus; 488748cd059SSimon Glass gd->arch.cpm_clk = gd->arch.vco_out / 2; 489748cd059SSimon Glass gd->arch.scc_clk = gd->arch.vco_out / 4; 490748cd059SSimon Glass gd->arch.brg_clk = gd->arch.vco_out / (1 << (2 * (dfbrg + 1))); 491a47a12beSStefan Roese #endif 492a47a12beSStefan Roese 493a47a12beSStefan Roese if(gd->cpu_clk != 0) return (0); 494a47a12beSStefan Roese else return (1); 495a47a12beSStefan Roese } 496a47a12beSStefan Roese 497a47a12beSStefan Roese 498a47a12beSStefan Roese /******************************************** 499a47a12beSStefan Roese * get_bus_freq 500a47a12beSStefan Roese * return system bus freq in Hz 501a47a12beSStefan Roese *********************************************/ 502a47a12beSStefan Roese ulong get_bus_freq (ulong dummy) 503a47a12beSStefan Roese { 504a47a12beSStefan Roese return gd->bus_clk; 505a47a12beSStefan Roese } 506a47a12beSStefan Roese 507a47a12beSStefan Roese /******************************************** 508a47a12beSStefan Roese * get_ddr_freq 509a47a12beSStefan Roese * return ddr bus freq in Hz 510a47a12beSStefan Roese *********************************************/ 511a47a12beSStefan Roese ulong get_ddr_freq (ulong dummy) 512a47a12beSStefan Roese { 513a47a12beSStefan Roese return gd->mem_clk; 514a47a12beSStefan Roese } 515