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