1 /* 2 * Copyright 2014 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <asm/io.h> 9 #include <asm/arch/immap_ls102xa.h> 10 #include <asm/arch/clock.h> 11 #include <fsl_ifc.h> 12 13 DECLARE_GLOBAL_DATA_PTR; 14 15 #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS 16 #define CONFIG_SYS_FSL_NUM_CC_PLLS 2 17 #endif 18 19 void get_sys_info(struct sys_info *sys_info) 20 { 21 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 22 struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR); 23 unsigned int cpu; 24 const u8 core_cplx_pll[6] = { 25 [0] = 0, /* CC1 PPL / 1 */ 26 [1] = 0, /* CC1 PPL / 2 */ 27 [4] = 1, /* CC2 PPL / 1 */ 28 [5] = 1, /* CC2 PPL / 2 */ 29 }; 30 31 const u8 core_cplx_pll_div[6] = { 32 [0] = 1, /* CC1 PPL / 1 */ 33 [1] = 2, /* CC1 PPL / 2 */ 34 [4] = 1, /* CC2 PPL / 1 */ 35 [5] = 2, /* CC2 PPL / 2 */ 36 }; 37 38 uint i; 39 uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS]; 40 uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS]; 41 unsigned long sysclk = CONFIG_SYS_CLK_FREQ; 42 43 sys_info->freq_systembus = sysclk; 44 #ifdef CONFIG_DDR_CLK_FREQ 45 sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; 46 #else 47 sys_info->freq_ddrbus = sysclk; 48 #endif 49 50 sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> 51 RCWSR0_SYS_PLL_RAT_SHIFT) & RCWSR0_SYS_PLL_RAT_MASK; 52 sys_info->freq_ddrbus *= (in_be32(&gur->rcwsr[0]) >> 53 RCWSR0_MEM_PLL_RAT_SHIFT) & RCWSR0_MEM_PLL_RAT_MASK; 54 55 for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) { 56 ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f; 57 if (ratio[i] > 4) 58 freq_c_pll[i] = sysclk * ratio[i]; 59 else 60 freq_c_pll[i] = sys_info->freq_systembus * ratio[i]; 61 } 62 63 for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) { 64 u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27) 65 & 0xf; 66 u32 cplx_pll = core_cplx_pll[c_pll_sel]; 67 68 sys_info->freq_processor[cpu] = 69 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; 70 } 71 72 #if defined(CONFIG_FSL_IFC) 73 sys_info->freq_localbus = sys_info->freq_systembus; 74 #endif 75 } 76 77 int get_clocks(void) 78 { 79 struct sys_info sys_info; 80 81 get_sys_info(&sys_info); 82 gd->cpu_clk = sys_info.freq_processor[0]; 83 gd->bus_clk = sys_info.freq_systembus; 84 gd->mem_clk = sys_info.freq_ddrbus * 2; 85 86 #if defined(CONFIG_FSL_ESDHC) 87 gd->arch.sdhc_clk = gd->bus_clk; 88 #endif 89 90 return 0; 91 } 92 93 ulong get_bus_freq(ulong dummy) 94 { 95 return gd->bus_clk; 96 } 97 98 ulong get_ddr_freq(ulong dummy) 99 { 100 return gd->mem_clk; 101 } 102 103 int get_serial_clock(void) 104 { 105 return gd->bus_clk / 2; 106 } 107 108 unsigned int mxc_get_clock(enum mxc_clock clk) 109 { 110 switch (clk) { 111 case MXC_I2C_CLK: 112 return get_bus_freq(0) / 2; 113 case MXC_ESDHC_CLK: 114 return get_bus_freq(0); 115 case MXC_DSPI_CLK: 116 return get_bus_freq(0) / 2; 117 case MXC_UART_CLK: 118 return get_bus_freq(0) / 2; 119 default: 120 printf("Unsupported clock\n"); 121 } 122 return 0; 123 } 124