2 * Copyright 2013 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/arch/imx-regs.h>
10 #include <asm/arch/clock.h>
11 #include <asm/arch/crm_regs.h>
12 #include <asm/imx-common/sys_proto.h>
14 #ifdef CONFIG_FSL_ESDHC
15 #include <fsl_esdhc.h>
18 #ifdef CONFIG_FSL_ESDHC
19 DECLARE_GLOBAL_DATA_PTR
;
22 static char soc_type
[] = "xx0";
24 #ifdef CONFIG_MXC_OCOTP
25 void enable_ocotp_clk(unsigned char enable
)
27 struct ccm_reg
*ccm
= (struct ccm_reg
*)CCM_BASE_ADDR
;
30 reg
= readl(&ccm
->ccgr6
);
32 reg
|= CCM_CCGR6_OCOTP_CTRL_MASK
;
34 reg
&= ~CCM_CCGR6_OCOTP_CTRL_MASK
;
35 writel(reg
, &ccm
->ccgr6
);
39 static u32
get_mcu_main_clk(void)
41 struct ccm_reg
*ccm
= (struct ccm_reg
*)CCM_BASE_ADDR
;
42 u32 ccm_ccsr
, ccm_cacrr
, armclk_div
;
43 u32 sysclk_sel
, pll_pfd_sel
= 0;
46 ccm_ccsr
= readl(&ccm
->ccsr
);
47 sysclk_sel
= ccm_ccsr
& CCM_CCSR_SYS_CLK_SEL_MASK
;
48 sysclk_sel
>>= CCM_CCSR_SYS_CLK_SEL_OFFSET
;
50 ccm_cacrr
= readl(&ccm
->cacrr
);
51 armclk_div
= ccm_cacrr
& CCM_CACRR_ARM_CLK_DIV_MASK
;
52 armclk_div
>>= CCM_CACRR_ARM_CLK_DIV_OFFSET
;
63 pll_pfd_sel
= ccm_ccsr
& CCM_CCSR_PLL2_PFD_CLK_SEL_MASK
;
64 pll_pfd_sel
>>= CCM_CCSR_PLL2_PFD_CLK_SEL_OFFSET
;
66 freq
= PLL2_MAIN_FREQ
;
67 else if (pll_pfd_sel
== 1)
68 freq
= PLL2_PFD1_FREQ
;
69 else if (pll_pfd_sel
== 2)
70 freq
= PLL2_PFD2_FREQ
;
71 else if (pll_pfd_sel
== 3)
72 freq
= PLL2_PFD3_FREQ
;
73 else if (pll_pfd_sel
== 4)
74 freq
= PLL2_PFD4_FREQ
;
77 freq
= PLL2_MAIN_FREQ
;
80 pll_pfd_sel
= ccm_ccsr
& CCM_CCSR_PLL1_PFD_CLK_SEL_MASK
;
81 pll_pfd_sel
>>= CCM_CCSR_PLL1_PFD_CLK_SEL_OFFSET
;
83 freq
= PLL1_MAIN_FREQ
;
84 else if (pll_pfd_sel
== 1)
85 freq
= PLL1_PFD1_FREQ
;
86 else if (pll_pfd_sel
== 2)
87 freq
= PLL1_PFD2_FREQ
;
88 else if (pll_pfd_sel
== 3)
89 freq
= PLL1_PFD3_FREQ
;
90 else if (pll_pfd_sel
== 4)
91 freq
= PLL1_PFD4_FREQ
;
94 freq
= PLL3_MAIN_FREQ
;
97 printf("unsupported system clock select\n");
100 return freq
/ armclk_div
;
103 static u32
get_bus_clk(void)
105 struct ccm_reg
*ccm
= (struct ccm_reg
*)CCM_BASE_ADDR
;
106 u32 ccm_cacrr
, busclk_div
;
108 ccm_cacrr
= readl(&ccm
->cacrr
);
110 busclk_div
= ccm_cacrr
& CCM_CACRR_BUS_CLK_DIV_MASK
;
111 busclk_div
>>= CCM_CACRR_BUS_CLK_DIV_OFFSET
;
114 return get_mcu_main_clk() / busclk_div
;
117 static u32
get_ipg_clk(void)
119 struct ccm_reg
*ccm
= (struct ccm_reg
*)CCM_BASE_ADDR
;
120 u32 ccm_cacrr
, ipgclk_div
;
122 ccm_cacrr
= readl(&ccm
->cacrr
);
124 ipgclk_div
= ccm_cacrr
& CCM_CACRR_IPG_CLK_DIV_MASK
;
125 ipgclk_div
>>= CCM_CACRR_IPG_CLK_DIV_OFFSET
;
128 return get_bus_clk() / ipgclk_div
;
131 static u32
get_uart_clk(void)
133 return get_ipg_clk();
136 static u32
get_sdhc_clk(void)
138 struct ccm_reg
*ccm
= (struct ccm_reg
*)CCM_BASE_ADDR
;
139 u32 ccm_cscmr1
, ccm_cscdr2
, sdhc_clk_sel
, sdhc_clk_div
;
142 ccm_cscmr1
= readl(&ccm
->cscmr1
);
143 sdhc_clk_sel
= ccm_cscmr1
& CCM_CSCMR1_ESDHC1_CLK_SEL_MASK
;
144 sdhc_clk_sel
>>= CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET
;
146 ccm_cscdr2
= readl(&ccm
->cscdr2
);
147 sdhc_clk_div
= ccm_cscdr2
& CCM_CSCDR2_ESDHC1_CLK_DIV_MASK
;
148 sdhc_clk_div
>>= CCM_CSCDR2_ESDHC1_CLK_DIV_OFFSET
;
151 switch (sdhc_clk_sel
) {
153 freq
= PLL3_MAIN_FREQ
;
156 freq
= PLL3_PFD3_FREQ
;
159 freq
= PLL1_PFD3_FREQ
;
162 freq
= get_bus_clk();
166 return freq
/ sdhc_clk_div
;
169 u32
get_fec_clk(void)
171 struct ccm_reg
*ccm
= (struct ccm_reg
*)CCM_BASE_ADDR
;
172 u32 ccm_cscmr2
, rmii_clk_sel
;
175 ccm_cscmr2
= readl(&ccm
->cscmr2
);
176 rmii_clk_sel
= ccm_cscmr2
& CCM_CSCMR2_RMII_CLK_SEL_MASK
;
177 rmii_clk_sel
>>= CCM_CSCMR2_RMII_CLK_SEL_OFFSET
;
179 switch (rmii_clk_sel
) {
181 freq
= ENET_EXTERNAL_CLK
;
184 freq
= AUDIO_EXTERNAL_CLK
;
187 freq
= PLL5_MAIN_FREQ
;
190 freq
= PLL5_MAIN_FREQ
/ 2;
197 static u32
get_i2c_clk(void)
199 return get_ipg_clk();
202 static u32
get_dspi_clk(void)
204 return get_ipg_clk();
207 u32
get_lpuart_clk(void)
209 return get_uart_clk();
212 unsigned int mxc_get_clock(enum mxc_clock clk
)
216 return get_mcu_main_clk();
218 return get_bus_clk();
220 return get_ipg_clk();
222 return get_uart_clk();
224 return get_sdhc_clk();
226 return get_fec_clk();
228 return get_i2c_clk();
230 return get_dspi_clk();
237 /* Dump some core clocks */
238 int do_vf610_showclocks(cmd_tbl_t
*cmdtp
, int flag
, int argc
,
242 printf("cpu clock : %8d MHz\n", mxc_get_clock(MXC_ARM_CLK
) / 1000000);
243 printf("bus clock : %8d MHz\n", mxc_get_clock(MXC_BUS_CLK
) / 1000000);
244 printf("ipg clock : %8d MHz\n", mxc_get_clock(MXC_IPG_CLK
) / 1000000);
250 clocks
, CONFIG_SYS_MAXARGS
, 1, do_vf610_showclocks
,
255 #ifdef CONFIG_FEC_MXC
256 void imx_get_mac_from_fuse(int dev_id
, unsigned char *mac
)
258 struct ocotp_regs
*ocotp
= (struct ocotp_regs
*)OCOTP_BASE_ADDR
;
259 struct fuse_bank
*bank
= &ocotp
->bank
[4];
260 struct fuse_bank4_regs
*fuse
=
261 (struct fuse_bank4_regs
*)bank
->fuse_regs
;
263 u32 value
= readl(&fuse
->mac_addr0
);
264 mac
[0] = (value
>> 8);
267 value
= readl(&fuse
->mac_addr1
);
268 mac
[2] = value
>> 24;
269 mac
[3] = value
>> 16;
275 u32
get_cpu_rev(void)
277 return MXC_CPU_VF610
<< 12;
280 #if defined(CONFIG_DISPLAY_CPUINFO)
281 static char *get_reset_cause(void)
284 struct src
*src_regs
= (struct src
*)SRC_BASE_ADDR
;
286 cause
= readl(&src_regs
->srsr
);
287 writel(cause
, &src_regs
->srsr
);
289 if (cause
& SRC_SRSR_POR_RST
)
290 return "POWER ON RESET";
291 else if (cause
& SRC_SRSR_WDOG_A5
)
293 else if (cause
& SRC_SRSR_WDOG_M4
)
295 else if (cause
& SRC_SRSR_JTAG_RST
)
296 return "JTAG HIGH-Z";
297 else if (cause
& SRC_SRSR_SW_RST
)
299 else if (cause
& SRC_SRSR_RESETB
)
300 return "EXTERNAL RESET";
302 return "unknown reset";
305 int print_cpuinfo(void)
307 printf("CPU: Freescale Vybrid VF%s at %d MHz\n",
308 soc_type
, mxc_get_clock(MXC_ARM_CLK
) / 1000000);
309 printf("Reset cause: %s\n", get_reset_cause());
315 int arch_cpu_init(void)
317 struct mscm
*mscm
= (struct mscm
*)MSCM_BASE_ADDR
;
319 soc_type
[0] = mscm
->cpxcount
? '6' : '5'; /*Dual Core => VF6x0 */
320 soc_type
[1] = mscm
->cpxcfg1
? '1' : '0'; /* L2 Cache => VFx10 */
325 #ifdef CONFIG_ARCH_MISC_INIT
326 int arch_misc_init(void)
331 strcat(soc
, soc_type
);
338 int cpu_eth_init(bd_t
*bis
)
342 #if defined(CONFIG_FEC_MXC)
343 rc
= fecmxc_initialize(bis
);
349 #ifdef CONFIG_FSL_ESDHC
350 int cpu_mmc_init(bd_t
*bis
)
352 return fsl_esdhc_mmc_init(bis
);
358 #ifdef CONFIG_FSL_ESDHC
359 gd
->arch
.sdhc_clk
= mxc_get_clock(MXC_ESDHC_CLK
);
364 #ifndef CONFIG_SYS_DCACHE_OFF
365 void enable_caches(void)
367 #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
368 enum dcache_option option
= DCACHE_WRITETHROUGH
;
370 enum dcache_option option
= DCACHE_WRITEBACK
;
375 /* Enable caching on OCRAM */
376 mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR
, IRAM_SIZE
, option
);