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