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