1 /* 2 * Copyright 2015 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <linux/compiler.h> 9 #include <asm/io.h> 10 #include <asm/processor.h> 11 #include <asm/arch/clock.h> 12 #include <asm/arch/soc.h> 13 #include <fsl_ifc.h> 14 #include "cpu.h" 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS 19 #define CONFIG_SYS_FSL_NUM_CC_PLLS 2 20 #endif 21 22 void get_sys_info(struct sys_info *sys_info) 23 { 24 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 25 #if (defined(CONFIG_FSL_ESDHC) &&\ 26 defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)) ||\ 27 defined(CONFIG_SYS_DPAA_FMAN) 28 29 u32 rcw_tmp; 30 #endif 31 struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR); 32 unsigned int cpu; 33 const u8 core_cplx_pll[8] = { 34 [0] = 0, /* CC1 PPL / 1 */ 35 [1] = 0, /* CC1 PPL / 2 */ 36 [4] = 1, /* CC2 PPL / 1 */ 37 [5] = 1, /* CC2 PPL / 2 */ 38 }; 39 40 const u8 core_cplx_pll_div[8] = { 41 [0] = 1, /* CC1 PPL / 1 */ 42 [1] = 2, /* CC1 PPL / 2 */ 43 [4] = 1, /* CC2 PPL / 1 */ 44 [5] = 2, /* CC2 PPL / 2 */ 45 }; 46 47 uint i, cluster; 48 uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS]; 49 uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS]; 50 unsigned long sysclk = CONFIG_SYS_CLK_FREQ; 51 unsigned long cluster_clk; 52 53 sys_info->freq_systembus = sysclk; 54 #ifndef CONFIG_CLUSTER_CLK_FREQ 55 #define CONFIG_CLUSTER_CLK_FREQ CONFIG_SYS_CLK_FREQ 56 #endif 57 cluster_clk = CONFIG_CLUSTER_CLK_FREQ; 58 59 #ifdef CONFIG_DDR_CLK_FREQ 60 sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; 61 #else 62 sys_info->freq_ddrbus = sysclk; 63 #endif 64 65 /* The freq_systembus is used to record frequency of platform PLL */ 66 sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >> 67 FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) & 68 FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK; 69 70 #ifdef CONFIG_ARCH_LS1012A 71 sys_info->freq_ddrbus = 2 * sys_info->freq_systembus; 72 #else 73 sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >> 74 FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) & 75 FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK; 76 #endif 77 78 for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) { 79 ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff; 80 if (ratio[i] > 4) 81 freq_c_pll[i] = cluster_clk * ratio[i]; 82 else 83 freq_c_pll[i] = sys_info->freq_systembus * ratio[i]; 84 } 85 86 for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 87 cluster = fsl_qoriq_core_to_cluster(cpu); 88 u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27) 89 & 0xf; 90 u32 cplx_pll = core_cplx_pll[c_pll_sel]; 91 92 sys_info->freq_processor[cpu] = 93 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; 94 } 95 96 #define HWA_CGA_M1_CLK_SEL 0xe0000000 97 #define HWA_CGA_M1_CLK_SHIFT 29 98 #ifdef CONFIG_SYS_DPAA_FMAN 99 rcw_tmp = in_be32(&gur->rcwsr[7]); 100 switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) { 101 case 2: 102 sys_info->freq_fman[0] = freq_c_pll[0] / 2; 103 break; 104 case 3: 105 sys_info->freq_fman[0] = freq_c_pll[0] / 3; 106 break; 107 case 4: 108 sys_info->freq_fman[0] = freq_c_pll[0] / 4; 109 break; 110 case 5: 111 sys_info->freq_fman[0] = sys_info->freq_systembus; 112 break; 113 case 6: 114 sys_info->freq_fman[0] = freq_c_pll[1] / 2; 115 break; 116 case 7: 117 sys_info->freq_fman[0] = freq_c_pll[1] / 3; 118 break; 119 default: 120 printf("Error: Unknown FMan1 clock select!\n"); 121 break; 122 } 123 #endif 124 125 #define HWA_CGA_M2_CLK_SEL 0x00000007 126 #define HWA_CGA_M2_CLK_SHIFT 0 127 #ifdef CONFIG_FSL_ESDHC 128 #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK 129 rcw_tmp = in_be32(&gur->rcwsr[15]); 130 switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) { 131 case 1: 132 sys_info->freq_sdhc = freq_c_pll[1]; 133 break; 134 case 2: 135 sys_info->freq_sdhc = freq_c_pll[1] / 2; 136 break; 137 case 3: 138 sys_info->freq_sdhc = freq_c_pll[1] / 3; 139 break; 140 case 6: 141 sys_info->freq_sdhc = freq_c_pll[0] / 2; 142 break; 143 default: 144 printf("Error: Unknown ESDHC clock select!\n"); 145 break; 146 } 147 #else 148 sys_info->freq_sdhc = (sys_info->freq_systembus / 149 CONFIG_SYS_FSL_PCLK_DIV) / 150 CONFIG_SYS_FSL_SDHC_CLK_DIV; 151 #endif 152 #endif 153 154 #if defined(CONFIG_FSL_IFC) 155 sys_info->freq_localbus = sys_info->freq_systembus / 156 CONFIG_SYS_FSL_IFC_CLK_DIV; 157 #endif 158 #ifdef CONFIG_SYS_DPAA_QBMAN 159 sys_info->freq_qman = sys_info->freq_systembus; 160 #endif 161 } 162 163 #ifdef CONFIG_SYS_DPAA_QBMAN 164 unsigned long get_qman_freq(void) 165 { 166 struct sys_info sys_info; 167 168 get_sys_info(&sys_info); 169 170 return sys_info.freq_qman; 171 } 172 #endif 173 174 int get_clocks(void) 175 { 176 struct sys_info sys_info; 177 178 get_sys_info(&sys_info); 179 gd->cpu_clk = sys_info.freq_processor[0]; 180 gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV; 181 gd->mem_clk = sys_info.freq_ddrbus; 182 183 #ifdef CONFIG_FSL_ESDHC 184 gd->arch.sdhc_clk = sys_info.freq_sdhc; 185 #endif 186 187 if (gd->cpu_clk != 0) 188 return 0; 189 else 190 return 1; 191 } 192 193 /******************************************** 194 * get_bus_freq 195 * return platform clock in Hz 196 *********************************************/ 197 ulong get_bus_freq(ulong dummy) 198 { 199 if (!gd->bus_clk) 200 get_clocks(); 201 202 return gd->bus_clk; 203 } 204 205 ulong get_ddr_freq(ulong dummy) 206 { 207 if (!gd->mem_clk) 208 get_clocks(); 209 210 return gd->mem_clk; 211 } 212 213 #ifdef CONFIG_FSL_ESDHC 214 int get_sdhc_freq(ulong dummy) 215 { 216 if (!gd->arch.sdhc_clk) 217 get_clocks(); 218 219 return gd->arch.sdhc_clk; 220 } 221 #endif 222 223 int get_serial_clock(void) 224 { 225 return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV; 226 } 227 228 int get_i2c_freq(ulong dummy) 229 { 230 return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV; 231 } 232 233 int get_dspi_freq(ulong dummy) 234 { 235 return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV; 236 } 237 238 #ifdef CONFIG_FSL_LPUART 239 int get_uart_freq(ulong dummy) 240 { 241 return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV; 242 } 243 #endif 244 245 unsigned int mxc_get_clock(enum mxc_clock clk) 246 { 247 switch (clk) { 248 case MXC_I2C_CLK: 249 return get_i2c_freq(0); 250 #if defined(CONFIG_FSL_ESDHC) 251 case MXC_ESDHC_CLK: 252 return get_sdhc_freq(0); 253 #endif 254 case MXC_DSPI_CLK: 255 return get_dspi_freq(0); 256 #ifdef CONFIG_FSL_LPUART 257 case MXC_UART_CLK: 258 return get_uart_freq(0); 259 #endif 260 default: 261 printf("Unsupported clock\n"); 262 } 263 return 0; 264 } 265