blob: b7d61adf4cbf30289d77a902fe1a8c6d0d11261f [file] [log] [blame]
Wang Huand60a2092014-09-05 13:52:34 +08001/*
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
13DECLARE_GLOBAL_DATA_PTR;
14
15#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
16#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
17#endif
18
19void get_sys_info(struct sys_info *sys_info)
20{
21 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
Wang Huand60a2092014-09-05 13:52:34 +080022 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)
Prabhakar Kushwaha8e63ed52017-02-02 15:01:37 +053073 sys_info->freq_localbus = sys_info->freq_systembus;
Wang Huand60a2092014-09-05 13:52:34 +080074#endif
75}
76
77int 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
93ulong get_bus_freq(ulong dummy)
94{
95 return gd->bus_clk;
96}
97
98ulong get_ddr_freq(ulong dummy)
99{
100 return gd->mem_clk;
101}
102
103int get_serial_clock(void)
104{
105 return gd->bus_clk / 2;
106}
107
108unsigned 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}