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