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 #ifdef CONFIG_FSL_IFC 26 struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; 27 u32 ccr; 28 #endif 29 #if (defined(CONFIG_FSL_ESDHC) &&\ 30 defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)) ||\ 31 defined(CONFIG_SYS_DPAA_FMAN) 32 33 u32 rcw_tmp; 34 #endif 35 struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR); 36 unsigned int cpu; 37 const u8 core_cplx_pll[8] = { 38 [0] = 0, /* CC1 PPL / 1 */ 39 [1] = 0, /* CC1 PPL / 2 */ 40 [4] = 1, /* CC2 PPL / 1 */ 41 [5] = 1, /* CC2 PPL / 2 */ 42 }; 43 44 const u8 core_cplx_pll_div[8] = { 45 [0] = 1, /* CC1 PPL / 1 */ 46 [1] = 2, /* CC1 PPL / 2 */ 47 [4] = 1, /* CC2 PPL / 1 */ 48 [5] = 2, /* CC2 PPL / 2 */ 49 }; 50 51 uint i, cluster; 52 uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS]; 53 uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS]; 54 unsigned long sysclk = CONFIG_SYS_CLK_FREQ; 55 56 sys_info->freq_systembus = sysclk; 57 #ifdef CONFIG_DDR_CLK_FREQ 58 sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; 59 #else 60 sys_info->freq_ddrbus = sysclk; 61 #endif 62 63 #ifdef CONFIG_ARCH_LS1012A 64 sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >> 65 FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) & 66 FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK; 67 #else 68 sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >> 69 FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) & 70 FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK; 71 sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >> 72 FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) & 73 FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK; 74 #endif 75 76 for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) { 77 ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff; 78 if (ratio[i] > 4) 79 freq_c_pll[i] = sysclk * ratio[i]; 80 else 81 freq_c_pll[i] = sys_info->freq_systembus * ratio[i]; 82 } 83 84 for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { 85 cluster = fsl_qoriq_core_to_cluster(cpu); 86 u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27) 87 & 0xf; 88 u32 cplx_pll = core_cplx_pll[c_pll_sel]; 89 90 sys_info->freq_processor[cpu] = 91 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; 92 } 93 94 #ifdef CONFIG_ARCH_LS1012A 95 sys_info->freq_systembus = sys_info->freq_ddrbus / 2; 96 sys_info->freq_ddrbus *= 2; 97 #endif 98 99 #define HWA_CGA_M1_CLK_SEL 0xe0000000 100 #define HWA_CGA_M1_CLK_SHIFT 29 101 #ifdef CONFIG_SYS_DPAA_FMAN 102 rcw_tmp = in_be32(&gur->rcwsr[7]); 103 switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) { 104 case 2: 105 sys_info->freq_fman[0] = freq_c_pll[0] / 2; 106 break; 107 case 3: 108 sys_info->freq_fman[0] = freq_c_pll[0] / 3; 109 break; 110 case 4: 111 sys_info->freq_fman[0] = freq_c_pll[0] / 4; 112 break; 113 case 5: 114 sys_info->freq_fman[0] = sys_info->freq_systembus; 115 break; 116 case 6: 117 sys_info->freq_fman[0] = freq_c_pll[1] / 2; 118 break; 119 case 7: 120 sys_info->freq_fman[0] = freq_c_pll[1] / 3; 121 break; 122 default: 123 printf("Error: Unknown FMan1 clock select!\n"); 124 break; 125 } 126 #endif 127 128 #define HWA_CGA_M2_CLK_SEL 0x00000007 129 #define HWA_CGA_M2_CLK_SHIFT 0 130 #ifdef CONFIG_FSL_ESDHC 131 #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK 132 rcw_tmp = in_be32(&gur->rcwsr[15]); 133 switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) { 134 case 1: 135 sys_info->freq_sdhc = freq_c_pll[1]; 136 break; 137 case 2: 138 sys_info->freq_sdhc = freq_c_pll[1] / 2; 139 break; 140 case 3: 141 sys_info->freq_sdhc = freq_c_pll[1] / 3; 142 break; 143 case 6: 144 sys_info->freq_sdhc = freq_c_pll[0] / 2; 145 break; 146 default: 147 printf("Error: Unknown ESDHC clock select!\n"); 148 break; 149 } 150 #else 151 sys_info->freq_sdhc = sys_info->freq_systembus; 152 #endif 153 #endif 154 155 #if defined(CONFIG_FSL_IFC) 156 ccr = ifc_in32(&ifc_regs.gregs->ifc_ccr); 157 ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; 158 159 sys_info->freq_localbus = sys_info->freq_systembus / ccr; 160 #endif 161 } 162 163 int get_clocks(void) 164 { 165 struct sys_info sys_info; 166 167 get_sys_info(&sys_info); 168 gd->cpu_clk = sys_info.freq_processor[0]; 169 gd->bus_clk = sys_info.freq_systembus; 170 gd->mem_clk = sys_info.freq_ddrbus; 171 172 #ifdef CONFIG_FSL_ESDHC 173 gd->arch.sdhc_clk = sys_info.freq_sdhc; 174 #endif 175 176 if (gd->cpu_clk != 0) 177 return 0; 178 else 179 return 1; 180 } 181 182 ulong get_bus_freq(ulong dummy) 183 { 184 return gd->bus_clk; 185 } 186 187 ulong get_ddr_freq(ulong dummy) 188 { 189 return gd->mem_clk; 190 } 191 192 #ifdef CONFIG_FSL_ESDHC 193 int get_sdhc_freq(ulong dummy) 194 { 195 return gd->arch.sdhc_clk; 196 } 197 #endif 198 199 int get_serial_clock(void) 200 { 201 return gd->bus_clk; 202 } 203 204 unsigned int mxc_get_clock(enum mxc_clock clk) 205 { 206 switch (clk) { 207 case MXC_I2C_CLK: 208 return get_bus_freq(0); 209 #if defined(CONFIG_FSL_ESDHC) 210 case MXC_ESDHC_CLK: 211 return get_sdhc_freq(0); 212 #endif 213 case MXC_DSPI_CLK: 214 return get_bus_freq(0); 215 case MXC_UART_CLK: 216 return get_bus_freq(0); 217 default: 218 printf("Unsupported clock\n"); 219 } 220 return 0; 221 } 222