xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-imx/mx7/clock.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2015 Freescale Semiconductor, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Author:
5*4882a593Smuzhiyun  *	Peng Fan <Peng.Fan@freescale.com>
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <div64.h>
12*4882a593Smuzhiyun #include <asm/io.h>
13*4882a593Smuzhiyun #include <linux/errno.h>
14*4882a593Smuzhiyun #include <asm/arch/imx-regs.h>
15*4882a593Smuzhiyun #include <asm/arch/crm_regs.h>
16*4882a593Smuzhiyun #include <asm/arch/clock.h>
17*4882a593Smuzhiyun #include <asm/arch/sys_proto.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *)
20*4882a593Smuzhiyun 					 ANATOP_BASE_ADDR;
21*4882a593Smuzhiyun struct mxc_ccm_reg *ccm_reg = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #ifdef CONFIG_FSL_ESDHC
24*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
25*4882a593Smuzhiyun #endif
26*4882a593Smuzhiyun 
get_clocks(void)27*4882a593Smuzhiyun int get_clocks(void)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun #ifdef CONFIG_FSL_ESDHC
30*4882a593Smuzhiyun #if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC2_BASE_ADDR
31*4882a593Smuzhiyun 	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
32*4882a593Smuzhiyun #elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC3_BASE_ADDR
33*4882a593Smuzhiyun 	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
34*4882a593Smuzhiyun #else
35*4882a593Smuzhiyun 	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 	return 0;
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun 
get_ahb_clk(void)41*4882a593Smuzhiyun u32 get_ahb_clk(void)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	return get_root_clk(AHB_CLK_ROOT);
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun 
get_ipg_clk(void)46*4882a593Smuzhiyun static u32 get_ipg_clk(void)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	/*
49*4882a593Smuzhiyun 	 * The AHB and IPG are fixed at 2:1 ratio, and synchronized to
50*4882a593Smuzhiyun 	 * each other.
51*4882a593Smuzhiyun 	 */
52*4882a593Smuzhiyun 	return get_ahb_clk() / 2;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
imx_get_uartclk(void)55*4882a593Smuzhiyun u32 imx_get_uartclk(void)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	return get_root_clk(UART1_CLK_ROOT);
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
imx_get_fecclk(void)60*4882a593Smuzhiyun u32 imx_get_fecclk(void)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun 	return get_root_clk(ENET_AXI_CLK_ROOT);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun #ifdef CONFIG_MXC_OCOTP
enable_ocotp_clk(unsigned char enable)66*4882a593Smuzhiyun void enable_ocotp_clk(unsigned char enable)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	clock_enable(CCGR_OCOTP, enable);
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
enable_thermal_clk(void)71*4882a593Smuzhiyun void enable_thermal_clk(void)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	enable_ocotp_clk(1);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun #endif
76*4882a593Smuzhiyun 
enable_usboh3_clk(unsigned char enable)77*4882a593Smuzhiyun void enable_usboh3_clk(unsigned char enable)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	u32 target;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	if (enable) {
82*4882a593Smuzhiyun 		/* disable the clock gate first */
83*4882a593Smuzhiyun 		clock_enable(CCGR_USB_HSIC, 0);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 		/* 120Mhz */
86*4882a593Smuzhiyun 		target = CLK_ROOT_ON |
87*4882a593Smuzhiyun 			 USB_HSIC_CLK_ROOT_FROM_PLL_SYS_MAIN_480M_CLK |
88*4882a593Smuzhiyun 			 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
89*4882a593Smuzhiyun 			 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
90*4882a593Smuzhiyun 		clock_set_target_val(USB_HSIC_CLK_ROOT, target);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 		/* enable the clock gate */
93*4882a593Smuzhiyun 		clock_enable(CCGR_USB_CTRL, 1);
94*4882a593Smuzhiyun 		clock_enable(CCGR_USB_HSIC, 1);
95*4882a593Smuzhiyun 		clock_enable(CCGR_USB_PHY1, 1);
96*4882a593Smuzhiyun 		clock_enable(CCGR_USB_PHY2, 1);
97*4882a593Smuzhiyun 	} else {
98*4882a593Smuzhiyun 		clock_enable(CCGR_USB_CTRL, 0);
99*4882a593Smuzhiyun 		clock_enable(CCGR_USB_HSIC, 0);
100*4882a593Smuzhiyun 		clock_enable(CCGR_USB_PHY1, 0);
101*4882a593Smuzhiyun 		clock_enable(CCGR_USB_PHY2, 0);
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun 
decode_pll(enum pll_clocks pll,u32 infreq)105*4882a593Smuzhiyun static u32 decode_pll(enum pll_clocks pll, u32 infreq)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun 	u32 reg, div_sel;
108*4882a593Smuzhiyun 	u32 num, denom;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	/*
111*4882a593Smuzhiyun 	 * Alought there are four choices for the bypass src,
112*4882a593Smuzhiyun 	 * we choose OSC_24M which is the default set in ROM.
113*4882a593Smuzhiyun 	 */
114*4882a593Smuzhiyun 	switch (pll) {
115*4882a593Smuzhiyun 	case PLL_CORE:
116*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pll_arm);
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ARM_POWERDOWN_MASK)
119*4882a593Smuzhiyun 			return 0;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ARM_BYPASS_MASK)
122*4882a593Smuzhiyun 			return MXC_HCLK;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 		div_sel = (reg & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >>
125*4882a593Smuzhiyun 			   CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 		return (infreq * div_sel) / 2;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	case PLL_SYS:
130*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pll_480);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_480_POWERDOWN_MASK)
133*4882a593Smuzhiyun 			return 0;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_480_BYPASS_MASK)
136*4882a593Smuzhiyun 			return MXC_HCLK;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 		if (((reg & CCM_ANALOG_PLL_480_DIV_SELECT_MASK) >>
139*4882a593Smuzhiyun 			CCM_ANALOG_PLL_480_DIV_SELECT_SHIFT) == 0)
140*4882a593Smuzhiyun 			return 480000000u;
141*4882a593Smuzhiyun 		else
142*4882a593Smuzhiyun 			return 528000000u;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	case PLL_ENET:
145*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pll_enet);
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_POWERDOWN_MASK)
148*4882a593Smuzhiyun 			return 0;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_BYPASS_MASK)
151*4882a593Smuzhiyun 			return MXC_HCLK;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 		return 1000000000u;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	case PLL_DDR:
156*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pll_ddr);
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_DDR_POWERDOWN_MASK)
159*4882a593Smuzhiyun 			return 0;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 		num = ccm_anatop->pll_ddr_num;
162*4882a593Smuzhiyun 		denom = ccm_anatop->pll_ddr_denom;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_DDR_BYPASS_MASK)
165*4882a593Smuzhiyun 			return MXC_HCLK;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 		div_sel = (reg & CCM_ANALOG_PLL_DDR_DIV_SELECT_MASK) >>
168*4882a593Smuzhiyun 			   CCM_ANALOG_PLL_DDR_DIV_SELECT_SHIFT;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 		return infreq * (div_sel + num / denom);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	case PLL_USB:
173*4882a593Smuzhiyun 		return 480000000u;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	default:
176*4882a593Smuzhiyun 		printf("Unsupported pll clocks %d\n", pll);
177*4882a593Smuzhiyun 		break;
178*4882a593Smuzhiyun 	}
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	return 0;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
mxc_get_pll_sys_derive(int derive)183*4882a593Smuzhiyun static u32 mxc_get_pll_sys_derive(int derive)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun 	u32 freq, div, frac;
186*4882a593Smuzhiyun 	u32 reg;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	div = 1;
189*4882a593Smuzhiyun 	reg = readl(&ccm_anatop->pll_480);
190*4882a593Smuzhiyun 	freq = decode_pll(PLL_SYS, MXC_HCLK);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	switch (derive) {
193*4882a593Smuzhiyun 	case PLL_SYS_MAIN_480M_CLK:
194*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_480_MAIN_DIV1_CLKGATE_MASK)
195*4882a593Smuzhiyun 			return 0;
196*4882a593Smuzhiyun 		else
197*4882a593Smuzhiyun 			return freq;
198*4882a593Smuzhiyun 	case PLL_SYS_MAIN_240M_CLK:
199*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_480_MAIN_DIV2_CLKGATE_MASK)
200*4882a593Smuzhiyun 			return 0;
201*4882a593Smuzhiyun 		else
202*4882a593Smuzhiyun 			return freq / 2;
203*4882a593Smuzhiyun 	case PLL_SYS_MAIN_120M_CLK:
204*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_480_MAIN_DIV4_CLKGATE_MASK)
205*4882a593Smuzhiyun 			return 0;
206*4882a593Smuzhiyun 		else
207*4882a593Smuzhiyun 			return freq / 4;
208*4882a593Smuzhiyun 	case PLL_SYS_PFD0_392M_CLK:
209*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480a);
210*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PFD_480A_PFD0_DIV1_CLKGATE_MASK)
211*4882a593Smuzhiyun 			return 0;
212*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480A_PFD0_FRAC_MASK) >>
213*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480A_PFD0_FRAC_SHIFT;
214*4882a593Smuzhiyun 		break;
215*4882a593Smuzhiyun 	case PLL_SYS_PFD0_196M_CLK:
216*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_480_PFD0_DIV2_CLKGATE_MASK)
217*4882a593Smuzhiyun 			return 0;
218*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480a);
219*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480A_PFD0_FRAC_MASK) >>
220*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480A_PFD0_FRAC_SHIFT;
221*4882a593Smuzhiyun 		div = 2;
222*4882a593Smuzhiyun 		break;
223*4882a593Smuzhiyun 	case PLL_SYS_PFD1_332M_CLK:
224*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480a);
225*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PFD_480A_PFD1_DIV1_CLKGATE_MASK)
226*4882a593Smuzhiyun 			return 0;
227*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480A_PFD1_FRAC_MASK) >>
228*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480A_PFD1_FRAC_SHIFT;
229*4882a593Smuzhiyun 		break;
230*4882a593Smuzhiyun 	case PLL_SYS_PFD1_166M_CLK:
231*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_480_PFD1_DIV2_CLKGATE_MASK)
232*4882a593Smuzhiyun 			return 0;
233*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480a);
234*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480A_PFD1_FRAC_MASK) >>
235*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480A_PFD1_FRAC_SHIFT;
236*4882a593Smuzhiyun 		div = 2;
237*4882a593Smuzhiyun 		break;
238*4882a593Smuzhiyun 	case PLL_SYS_PFD2_270M_CLK:
239*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480a);
240*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PFD_480A_PFD2_DIV1_CLKGATE_MASK)
241*4882a593Smuzhiyun 			return 0;
242*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480A_PFD2_FRAC_MASK) >>
243*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480A_PFD2_FRAC_SHIFT;
244*4882a593Smuzhiyun 		break;
245*4882a593Smuzhiyun 	case PLL_SYS_PFD2_135M_CLK:
246*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_480_PFD2_DIV2_CLKGATE_MASK)
247*4882a593Smuzhiyun 			return 0;
248*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480a);
249*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480A_PFD2_FRAC_MASK) >>
250*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480A_PFD2_FRAC_SHIFT;
251*4882a593Smuzhiyun 		div = 2;
252*4882a593Smuzhiyun 		break;
253*4882a593Smuzhiyun 	case PLL_SYS_PFD3_CLK:
254*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480a);
255*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PFD_480A_PFD3_DIV1_CLKGATE_MASK)
256*4882a593Smuzhiyun 			return 0;
257*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480A_PFD3_FRAC_MASK) >>
258*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480A_PFD3_FRAC_SHIFT;
259*4882a593Smuzhiyun 		break;
260*4882a593Smuzhiyun 	case PLL_SYS_PFD4_CLK:
261*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480b);
262*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PFD_480B_PFD4_DIV1_CLKGATE_MASK)
263*4882a593Smuzhiyun 			return 0;
264*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480B_PFD4_FRAC_MASK) >>
265*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480B_PFD4_FRAC_SHIFT;
266*4882a593Smuzhiyun 		break;
267*4882a593Smuzhiyun 	case PLL_SYS_PFD5_CLK:
268*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480b);
269*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PFD_480B_PFD5_DIV1_CLKGATE_MASK)
270*4882a593Smuzhiyun 			return 0;
271*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480B_PFD5_FRAC_MASK) >>
272*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480B_PFD5_FRAC_SHIFT;
273*4882a593Smuzhiyun 		break;
274*4882a593Smuzhiyun 	case PLL_SYS_PFD6_CLK:
275*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480b);
276*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PFD_480B_PFD6_DIV1_CLKGATE_MASK)
277*4882a593Smuzhiyun 			return 0;
278*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480B_PFD6_FRAC_MASK) >>
279*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480B_PFD6_FRAC_SHIFT;
280*4882a593Smuzhiyun 		break;
281*4882a593Smuzhiyun 	case PLL_SYS_PFD7_CLK:
282*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pfd_480b);
283*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PFD_480B_PFD7_DIV1_CLKGATE_MASK)
284*4882a593Smuzhiyun 			return 0;
285*4882a593Smuzhiyun 		frac = (reg & CCM_ANALOG_PFD_480B_PFD7_FRAC_MASK) >>
286*4882a593Smuzhiyun 			CCM_ANALOG_PFD_480B_PFD7_FRAC_SHIFT;
287*4882a593Smuzhiyun 		break;
288*4882a593Smuzhiyun 	default:
289*4882a593Smuzhiyun 		printf("Error derived pll_sys clock %d\n", derive);
290*4882a593Smuzhiyun 		return 0;
291*4882a593Smuzhiyun 	}
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	return ((freq / frac) * 18) / div;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun 
mxc_get_pll_enet_derive(int derive)296*4882a593Smuzhiyun static u32 mxc_get_pll_enet_derive(int derive)
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun 	u32 freq, reg;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	freq = decode_pll(PLL_ENET, MXC_HCLK);
301*4882a593Smuzhiyun 	reg = readl(&ccm_anatop->pll_enet);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	switch (derive) {
304*4882a593Smuzhiyun 	case PLL_ENET_MAIN_500M_CLK:
305*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ_MASK)
306*4882a593Smuzhiyun 			return freq / 2;
307*4882a593Smuzhiyun 		break;
308*4882a593Smuzhiyun 	case PLL_ENET_MAIN_250M_CLK:
309*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ_MASK)
310*4882a593Smuzhiyun 			return freq / 4;
311*4882a593Smuzhiyun 		break;
312*4882a593Smuzhiyun 	case PLL_ENET_MAIN_125M_CLK:
313*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ_MASK)
314*4882a593Smuzhiyun 			return freq / 8;
315*4882a593Smuzhiyun 		break;
316*4882a593Smuzhiyun 	case PLL_ENET_MAIN_100M_CLK:
317*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ_MASK)
318*4882a593Smuzhiyun 			return freq / 10;
319*4882a593Smuzhiyun 		break;
320*4882a593Smuzhiyun 	case PLL_ENET_MAIN_50M_CLK:
321*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ_MASK)
322*4882a593Smuzhiyun 			return freq / 20;
323*4882a593Smuzhiyun 		break;
324*4882a593Smuzhiyun 	case PLL_ENET_MAIN_40M_CLK:
325*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ_MASK)
326*4882a593Smuzhiyun 			return freq / 25;
327*4882a593Smuzhiyun 		break;
328*4882a593Smuzhiyun 	case PLL_ENET_MAIN_25M_CLK:
329*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ_MASK)
330*4882a593Smuzhiyun 			return freq / 40;
331*4882a593Smuzhiyun 		break;
332*4882a593Smuzhiyun 	default:
333*4882a593Smuzhiyun 		printf("Error derived pll_enet clock %d\n", derive);
334*4882a593Smuzhiyun 		break;
335*4882a593Smuzhiyun 	}
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	return 0;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun 
mxc_get_pll_ddr_derive(int derive)340*4882a593Smuzhiyun static u32 mxc_get_pll_ddr_derive(int derive)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun 	u32 freq, reg;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	freq = decode_pll(PLL_DDR, MXC_HCLK);
345*4882a593Smuzhiyun 	reg = readl(&ccm_anatop->pll_ddr);
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	switch (derive) {
348*4882a593Smuzhiyun 	case PLL_DRAM_MAIN_1066M_CLK:
349*4882a593Smuzhiyun 		return freq;
350*4882a593Smuzhiyun 	case PLL_DRAM_MAIN_533M_CLK:
351*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_DDR_DIV2_ENABLE_CLK_MASK)
352*4882a593Smuzhiyun 			return freq / 2;
353*4882a593Smuzhiyun 		break;
354*4882a593Smuzhiyun 	default:
355*4882a593Smuzhiyun 		printf("Error derived pll_ddr clock %d\n", derive);
356*4882a593Smuzhiyun 		break;
357*4882a593Smuzhiyun 	}
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	return 0;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
mxc_get_pll_derive(enum pll_clocks pll,int derive)362*4882a593Smuzhiyun static u32 mxc_get_pll_derive(enum pll_clocks pll, int derive)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun 	switch (pll) {
365*4882a593Smuzhiyun 	case PLL_SYS:
366*4882a593Smuzhiyun 		return mxc_get_pll_sys_derive(derive);
367*4882a593Smuzhiyun 	case PLL_ENET:
368*4882a593Smuzhiyun 		return mxc_get_pll_enet_derive(derive);
369*4882a593Smuzhiyun 	case PLL_DDR:
370*4882a593Smuzhiyun 		return mxc_get_pll_ddr_derive(derive);
371*4882a593Smuzhiyun 	default:
372*4882a593Smuzhiyun 		printf("Error pll.\n");
373*4882a593Smuzhiyun 		return 0;
374*4882a593Smuzhiyun 	}
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun 
get_root_src_clk(enum clk_root_src root_src)377*4882a593Smuzhiyun static u32 get_root_src_clk(enum clk_root_src root_src)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun 	switch (root_src) {
380*4882a593Smuzhiyun 	case OSC_24M_CLK:
381*4882a593Smuzhiyun 		return 24000000u;
382*4882a593Smuzhiyun 	case PLL_ARM_MAIN_800M_CLK:
383*4882a593Smuzhiyun 		return decode_pll(PLL_CORE, MXC_HCLK);
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	case PLL_SYS_MAIN_480M_CLK:
386*4882a593Smuzhiyun 	case PLL_SYS_MAIN_240M_CLK:
387*4882a593Smuzhiyun 	case PLL_SYS_MAIN_120M_CLK:
388*4882a593Smuzhiyun 	case PLL_SYS_PFD0_392M_CLK:
389*4882a593Smuzhiyun 	case PLL_SYS_PFD0_196M_CLK:
390*4882a593Smuzhiyun 	case PLL_SYS_PFD1_332M_CLK:
391*4882a593Smuzhiyun 	case PLL_SYS_PFD1_166M_CLK:
392*4882a593Smuzhiyun 	case PLL_SYS_PFD2_270M_CLK:
393*4882a593Smuzhiyun 	case PLL_SYS_PFD2_135M_CLK:
394*4882a593Smuzhiyun 	case PLL_SYS_PFD3_CLK:
395*4882a593Smuzhiyun 	case PLL_SYS_PFD4_CLK:
396*4882a593Smuzhiyun 	case PLL_SYS_PFD5_CLK:
397*4882a593Smuzhiyun 	case PLL_SYS_PFD6_CLK:
398*4882a593Smuzhiyun 	case PLL_SYS_PFD7_CLK:
399*4882a593Smuzhiyun 		return mxc_get_pll_derive(PLL_SYS, root_src);
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	case PLL_ENET_MAIN_500M_CLK:
402*4882a593Smuzhiyun 	case PLL_ENET_MAIN_250M_CLK:
403*4882a593Smuzhiyun 	case PLL_ENET_MAIN_125M_CLK:
404*4882a593Smuzhiyun 	case PLL_ENET_MAIN_100M_CLK:
405*4882a593Smuzhiyun 	case PLL_ENET_MAIN_50M_CLK:
406*4882a593Smuzhiyun 	case PLL_ENET_MAIN_40M_CLK:
407*4882a593Smuzhiyun 	case PLL_ENET_MAIN_25M_CLK:
408*4882a593Smuzhiyun 		return mxc_get_pll_derive(PLL_ENET, root_src);
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	case PLL_DRAM_MAIN_1066M_CLK:
411*4882a593Smuzhiyun 	case PLL_DRAM_MAIN_533M_CLK:
412*4882a593Smuzhiyun 		return mxc_get_pll_derive(PLL_DDR, root_src);
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	case PLL_AUDIO_MAIN_CLK:
415*4882a593Smuzhiyun 		return decode_pll(PLL_AUDIO, MXC_HCLK);
416*4882a593Smuzhiyun 	case PLL_VIDEO_MAIN_CLK:
417*4882a593Smuzhiyun 		return decode_pll(PLL_VIDEO, MXC_HCLK);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	case PLL_USB_MAIN_480M_CLK:
420*4882a593Smuzhiyun 		return decode_pll(PLL_USB, MXC_HCLK);
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	case REF_1M_CLK:
423*4882a593Smuzhiyun 		return 1000000;
424*4882a593Smuzhiyun 	case OSC_32K_CLK:
425*4882a593Smuzhiyun 		return MXC_CLK32;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	case EXT_CLK_1:
428*4882a593Smuzhiyun 	case EXT_CLK_2:
429*4882a593Smuzhiyun 	case EXT_CLK_3:
430*4882a593Smuzhiyun 	case EXT_CLK_4:
431*4882a593Smuzhiyun 		printf("No EXT CLK supported??\n");
432*4882a593Smuzhiyun 		break;
433*4882a593Smuzhiyun 	};
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	return 0;
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun 
get_root_clk(enum clk_root_index clock_id)438*4882a593Smuzhiyun u32 get_root_clk(enum clk_root_index clock_id)
439*4882a593Smuzhiyun {
440*4882a593Smuzhiyun 	enum clk_root_src root_src;
441*4882a593Smuzhiyun 	u32 post_podf, pre_podf, auto_podf, root_src_clk;
442*4882a593Smuzhiyun 	int auto_en;
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 	if (clock_root_enabled(clock_id) <= 0)
445*4882a593Smuzhiyun 		return 0;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	if (clock_get_prediv(clock_id, &pre_podf) < 0)
448*4882a593Smuzhiyun 		return 0;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	if (clock_get_postdiv(clock_id, &post_podf) < 0)
451*4882a593Smuzhiyun 		return 0;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	if (clock_get_autopostdiv(clock_id, &auto_podf, &auto_en) < 0)
454*4882a593Smuzhiyun 		return 0;
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	if (auto_en == 0)
457*4882a593Smuzhiyun 		auto_podf = 0;
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	if (clock_get_src(clock_id, &root_src) < 0)
460*4882a593Smuzhiyun 		return 0;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	root_src_clk = get_root_src_clk(root_src);
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	/*
465*4882a593Smuzhiyun 	 * bypass clk is ignored.
466*4882a593Smuzhiyun 	 */
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	return root_src_clk / (post_podf + 1) / (pre_podf + 1) /
469*4882a593Smuzhiyun 		(auto_podf + 1);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun 
get_ddrc_clk(void)472*4882a593Smuzhiyun static u32 get_ddrc_clk(void)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun 	u32 reg, freq;
475*4882a593Smuzhiyun 	enum root_post_div post_div;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	reg = readl(&ccm_reg->root[DRAM_CLK_ROOT].target_root);
478*4882a593Smuzhiyun 	if (reg & CLK_ROOT_MUX_MASK)
479*4882a593Smuzhiyun 		/* DRAM_ALT_CLK_ROOT */
480*4882a593Smuzhiyun 		freq = get_root_clk(DRAM_ALT_CLK_ROOT);
481*4882a593Smuzhiyun 	else
482*4882a593Smuzhiyun 		/* PLL_DRAM_MAIN_1066M_CLK */
483*4882a593Smuzhiyun 		freq = mxc_get_pll_derive(PLL_DDR, PLL_DRAM_MAIN_1066M_CLK);
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	post_div = reg & DRAM_CLK_ROOT_POST_DIV_MASK;
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	return freq / (post_div + 1) / 2;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun 
mxc_get_clock(enum mxc_clock clk)490*4882a593Smuzhiyun unsigned int mxc_get_clock(enum mxc_clock clk)
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun 	switch (clk) {
493*4882a593Smuzhiyun 	case MXC_ARM_CLK:
494*4882a593Smuzhiyun 		return get_root_clk(ARM_A7_CLK_ROOT);
495*4882a593Smuzhiyun 	case MXC_AXI_CLK:
496*4882a593Smuzhiyun 		return get_root_clk(MAIN_AXI_CLK_ROOT);
497*4882a593Smuzhiyun 	case MXC_AHB_CLK:
498*4882a593Smuzhiyun 		return get_root_clk(AHB_CLK_ROOT);
499*4882a593Smuzhiyun 	case MXC_IPG_CLK:
500*4882a593Smuzhiyun 		return get_ipg_clk();
501*4882a593Smuzhiyun 	case MXC_I2C_CLK:
502*4882a593Smuzhiyun 		return get_root_clk(I2C1_CLK_ROOT);
503*4882a593Smuzhiyun 	case MXC_UART_CLK:
504*4882a593Smuzhiyun 		return get_root_clk(UART1_CLK_ROOT);
505*4882a593Smuzhiyun 	case MXC_CSPI_CLK:
506*4882a593Smuzhiyun 		return get_root_clk(ECSPI1_CLK_ROOT);
507*4882a593Smuzhiyun 	case MXC_DDR_CLK:
508*4882a593Smuzhiyun 		return get_ddrc_clk();
509*4882a593Smuzhiyun 	case MXC_ESDHC_CLK:
510*4882a593Smuzhiyun 		return get_root_clk(USDHC1_CLK_ROOT);
511*4882a593Smuzhiyun 	case MXC_ESDHC2_CLK:
512*4882a593Smuzhiyun 		return get_root_clk(USDHC2_CLK_ROOT);
513*4882a593Smuzhiyun 	case MXC_ESDHC3_CLK:
514*4882a593Smuzhiyun 		return get_root_clk(USDHC3_CLK_ROOT);
515*4882a593Smuzhiyun 	default:
516*4882a593Smuzhiyun 		printf("Unsupported mxc_clock %d\n", clk);
517*4882a593Smuzhiyun 		break;
518*4882a593Smuzhiyun 	}
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	return 0;
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun #ifdef CONFIG_SYS_I2C_MXC
524*4882a593Smuzhiyun /* i2c_num can be 0 - 3 */
enable_i2c_clk(unsigned char enable,unsigned i2c_num)525*4882a593Smuzhiyun int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
526*4882a593Smuzhiyun {
527*4882a593Smuzhiyun 	u32 target;
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	if (i2c_num >= 4)
530*4882a593Smuzhiyun 		return -EINVAL;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	if (enable) {
533*4882a593Smuzhiyun 		clock_enable(CCGR_I2C1 + i2c_num, 0);
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 		/* Set i2c root clock to PLL_SYS_MAIN_120M_CLK */
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 		target = CLK_ROOT_ON |
538*4882a593Smuzhiyun 			 I2C1_CLK_ROOT_FROM_PLL_SYS_MAIN_120M_CLK |
539*4882a593Smuzhiyun 			 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
540*4882a593Smuzhiyun 			 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2);
541*4882a593Smuzhiyun 		clock_set_target_val(I2C1_CLK_ROOT + i2c_num, target);
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 		clock_enable(CCGR_I2C1 + i2c_num, 1);
544*4882a593Smuzhiyun 	} else {
545*4882a593Smuzhiyun 		clock_enable(CCGR_I2C1 + i2c_num, 0);
546*4882a593Smuzhiyun 	}
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	return 0;
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun #endif
551*4882a593Smuzhiyun 
init_clk_esdhc(void)552*4882a593Smuzhiyun static void init_clk_esdhc(void)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun 	u32 target;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	/* disable the clock gate first */
557*4882a593Smuzhiyun 	clock_enable(CCGR_USDHC1, 0);
558*4882a593Smuzhiyun 	clock_enable(CCGR_USDHC2, 0);
559*4882a593Smuzhiyun 	clock_enable(CCGR_USDHC3, 0);
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	/* 196: 392/2 */
562*4882a593Smuzhiyun 	target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK |
563*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
564*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2);
565*4882a593Smuzhiyun 	clock_set_target_val(USDHC1_CLK_ROOT, target);
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK |
568*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
569*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2);
570*4882a593Smuzhiyun 	clock_set_target_val(USDHC2_CLK_ROOT, target);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK |
573*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
574*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2);
575*4882a593Smuzhiyun 	clock_set_target_val(USDHC3_CLK_ROOT, target);
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	/* enable the clock gate */
578*4882a593Smuzhiyun 	clock_enable(CCGR_USDHC1, 1);
579*4882a593Smuzhiyun 	clock_enable(CCGR_USDHC2, 1);
580*4882a593Smuzhiyun 	clock_enable(CCGR_USDHC3, 1);
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
init_clk_uart(void)583*4882a593Smuzhiyun static void init_clk_uart(void)
584*4882a593Smuzhiyun {
585*4882a593Smuzhiyun 	u32 target;
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 	/* disable the clock gate first */
588*4882a593Smuzhiyun 	clock_enable(CCGR_UART1, 0);
589*4882a593Smuzhiyun 	clock_enable(CCGR_UART2, 0);
590*4882a593Smuzhiyun 	clock_enable(CCGR_UART3, 0);
591*4882a593Smuzhiyun 	clock_enable(CCGR_UART4, 0);
592*4882a593Smuzhiyun 	clock_enable(CCGR_UART5, 0);
593*4882a593Smuzhiyun 	clock_enable(CCGR_UART6, 0);
594*4882a593Smuzhiyun 	clock_enable(CCGR_UART7, 0);
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	/* 24Mhz */
597*4882a593Smuzhiyun 	target = CLK_ROOT_ON | UART1_CLK_ROOT_FROM_OSC_24M_CLK |
598*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
599*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
600*4882a593Smuzhiyun 	clock_set_target_val(UART1_CLK_ROOT, target);
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	target = CLK_ROOT_ON | UART2_CLK_ROOT_FROM_OSC_24M_CLK |
603*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
604*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
605*4882a593Smuzhiyun 	clock_set_target_val(UART2_CLK_ROOT, target);
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 	target = CLK_ROOT_ON | UART3_CLK_ROOT_FROM_OSC_24M_CLK |
608*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
609*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
610*4882a593Smuzhiyun 	clock_set_target_val(UART3_CLK_ROOT, target);
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	target = CLK_ROOT_ON | UART4_CLK_ROOT_FROM_OSC_24M_CLK |
613*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
614*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
615*4882a593Smuzhiyun 	clock_set_target_val(UART4_CLK_ROOT, target);
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	target = CLK_ROOT_ON | UART5_CLK_ROOT_FROM_OSC_24M_CLK |
618*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
619*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
620*4882a593Smuzhiyun 	clock_set_target_val(UART5_CLK_ROOT, target);
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	target = CLK_ROOT_ON | UART6_CLK_ROOT_FROM_OSC_24M_CLK |
623*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
624*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
625*4882a593Smuzhiyun 	clock_set_target_val(UART6_CLK_ROOT, target);
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	target = CLK_ROOT_ON | UART7_CLK_ROOT_FROM_OSC_24M_CLK |
628*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
629*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
630*4882a593Smuzhiyun 	clock_set_target_val(UART7_CLK_ROOT, target);
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	/* enable the clock gate */
633*4882a593Smuzhiyun 	clock_enable(CCGR_UART1, 1);
634*4882a593Smuzhiyun 	clock_enable(CCGR_UART2, 1);
635*4882a593Smuzhiyun 	clock_enable(CCGR_UART3, 1);
636*4882a593Smuzhiyun 	clock_enable(CCGR_UART4, 1);
637*4882a593Smuzhiyun 	clock_enable(CCGR_UART5, 1);
638*4882a593Smuzhiyun 	clock_enable(CCGR_UART6, 1);
639*4882a593Smuzhiyun 	clock_enable(CCGR_UART7, 1);
640*4882a593Smuzhiyun }
641*4882a593Smuzhiyun 
init_clk_weim(void)642*4882a593Smuzhiyun static void init_clk_weim(void)
643*4882a593Smuzhiyun {
644*4882a593Smuzhiyun 	u32 target;
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	/* disable the clock gate first */
647*4882a593Smuzhiyun 	clock_enable(CCGR_WEIM, 0);
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 	/* 120Mhz */
650*4882a593Smuzhiyun 	target = CLK_ROOT_ON | EIM_CLK_ROOT_FROM_PLL_SYS_MAIN_120M_CLK |
651*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
652*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
653*4882a593Smuzhiyun 	clock_set_target_val(EIM_CLK_ROOT, target);
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	/* enable the clock gate */
656*4882a593Smuzhiyun 	clock_enable(CCGR_WEIM, 1);
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun 
init_clk_ecspi(void)659*4882a593Smuzhiyun static void init_clk_ecspi(void)
660*4882a593Smuzhiyun {
661*4882a593Smuzhiyun 	u32 target;
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	/* disable the clock gate first */
664*4882a593Smuzhiyun 	clock_enable(CCGR_ECSPI1, 0);
665*4882a593Smuzhiyun 	clock_enable(CCGR_ECSPI2, 0);
666*4882a593Smuzhiyun 	clock_enable(CCGR_ECSPI3, 0);
667*4882a593Smuzhiyun 	clock_enable(CCGR_ECSPI4, 0);
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 	/* 60Mhz: 240/4 */
670*4882a593Smuzhiyun 	target = CLK_ROOT_ON | ECSPI1_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK |
671*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
672*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
673*4882a593Smuzhiyun 	clock_set_target_val(ECSPI1_CLK_ROOT, target);
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	target = CLK_ROOT_ON | ECSPI2_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK |
676*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
677*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
678*4882a593Smuzhiyun 	clock_set_target_val(ECSPI2_CLK_ROOT, target);
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	target = CLK_ROOT_ON | ECSPI3_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK |
681*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
682*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
683*4882a593Smuzhiyun 	clock_set_target_val(ECSPI3_CLK_ROOT, target);
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	target = CLK_ROOT_ON | ECSPI4_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK |
686*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
687*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
688*4882a593Smuzhiyun 	clock_set_target_val(ECSPI4_CLK_ROOT, target);
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	/* enable the clock gate */
691*4882a593Smuzhiyun 	clock_enable(CCGR_ECSPI1, 1);
692*4882a593Smuzhiyun 	clock_enable(CCGR_ECSPI2, 1);
693*4882a593Smuzhiyun 	clock_enable(CCGR_ECSPI3, 1);
694*4882a593Smuzhiyun 	clock_enable(CCGR_ECSPI4, 1);
695*4882a593Smuzhiyun }
696*4882a593Smuzhiyun 
init_clk_wdog(void)697*4882a593Smuzhiyun static void init_clk_wdog(void)
698*4882a593Smuzhiyun {
699*4882a593Smuzhiyun 	u32 target;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	/* disable the clock gate first */
702*4882a593Smuzhiyun 	clock_enable(CCGR_WDOG1, 0);
703*4882a593Smuzhiyun 	clock_enable(CCGR_WDOG2, 0);
704*4882a593Smuzhiyun 	clock_enable(CCGR_WDOG3, 0);
705*4882a593Smuzhiyun 	clock_enable(CCGR_WDOG4, 0);
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	/* 24Mhz */
708*4882a593Smuzhiyun 	target = CLK_ROOT_ON | WDOG_CLK_ROOT_FROM_OSC_24M_CLK |
709*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
710*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
711*4882a593Smuzhiyun 	clock_set_target_val(WDOG_CLK_ROOT, target);
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun 	/* enable the clock gate */
714*4882a593Smuzhiyun 	clock_enable(CCGR_WDOG1, 1);
715*4882a593Smuzhiyun 	clock_enable(CCGR_WDOG2, 1);
716*4882a593Smuzhiyun 	clock_enable(CCGR_WDOG3, 1);
717*4882a593Smuzhiyun 	clock_enable(CCGR_WDOG4, 1);
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun #ifdef CONFIG_MXC_EPDC
init_clk_epdc(void)721*4882a593Smuzhiyun static void init_clk_epdc(void)
722*4882a593Smuzhiyun {
723*4882a593Smuzhiyun 	u32 target;
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 	/* disable the clock gate first */
726*4882a593Smuzhiyun 	clock_enable(CCGR_EPDC, 0);
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	/* 24Mhz */
729*4882a593Smuzhiyun 	target = CLK_ROOT_ON | EPDC_PIXEL_CLK_ROOT_FROM_PLL_SYS_MAIN_480M_CLK |
730*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
731*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV12);
732*4882a593Smuzhiyun 	clock_set_target_val(EPDC_PIXEL_CLK_ROOT, target);
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun 	/* enable the clock gate */
735*4882a593Smuzhiyun 	clock_enable(CCGR_EPDC, 1);
736*4882a593Smuzhiyun }
737*4882a593Smuzhiyun #endif
738*4882a593Smuzhiyun 
enable_pll_enet(void)739*4882a593Smuzhiyun static int enable_pll_enet(void)
740*4882a593Smuzhiyun {
741*4882a593Smuzhiyun 	u32 reg;
742*4882a593Smuzhiyun 	s32 timeout = 100000;
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun 	reg = readl(&ccm_anatop->pll_enet);
745*4882a593Smuzhiyun 	/* If pll_enet powered up, no need to set it again */
746*4882a593Smuzhiyun 	if (reg & ANADIG_PLL_ENET_PWDN_MASK) {
747*4882a593Smuzhiyun 		reg &= ~ANADIG_PLL_ENET_PWDN_MASK;
748*4882a593Smuzhiyun 		writel(reg, &ccm_anatop->pll_enet);
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun 		while (timeout--) {
751*4882a593Smuzhiyun 			if (readl(&ccm_anatop->pll_enet) & ANADIG_PLL_LOCK)
752*4882a593Smuzhiyun 				break;
753*4882a593Smuzhiyun 		}
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun 		if (timeout <= 0) {
756*4882a593Smuzhiyun 			/* If timeout, we set pwdn for pll_enet. */
757*4882a593Smuzhiyun 			reg |= ANADIG_PLL_ENET_PWDN_MASK;
758*4882a593Smuzhiyun 			return -ETIME;
759*4882a593Smuzhiyun 		}
760*4882a593Smuzhiyun 	}
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	/* Clear bypass */
763*4882a593Smuzhiyun 	writel(CCM_ANALOG_PLL_ENET_BYPASS_MASK, &ccm_anatop->pll_enet_clr);
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	writel((CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ_MASK
766*4882a593Smuzhiyun 		| CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ_MASK
767*4882a593Smuzhiyun 		| CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ_MASK
768*4882a593Smuzhiyun 		| CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ_MASK
769*4882a593Smuzhiyun 		| CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ_MASK
770*4882a593Smuzhiyun 		| CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ_MASK
771*4882a593Smuzhiyun 		| CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ_MASK),
772*4882a593Smuzhiyun 	       &ccm_anatop->pll_enet_set);
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun 	return 0;
775*4882a593Smuzhiyun }
enable_pll_video(u32 pll_div,u32 pll_num,u32 pll_denom,u32 post_div)776*4882a593Smuzhiyun static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom,
777*4882a593Smuzhiyun 	u32 post_div)
778*4882a593Smuzhiyun {
779*4882a593Smuzhiyun 	u32 reg = 0;
780*4882a593Smuzhiyun 	ulong start;
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	debug("pll5 div = %d, num = %d, denom = %d\n",
783*4882a593Smuzhiyun 		pll_div, pll_num, pll_denom);
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	/* Power up PLL5 video and disable its output */
786*4882a593Smuzhiyun 	writel(CCM_ANALOG_PLL_VIDEO_CLR_ENABLE_CLK_MASK |
787*4882a593Smuzhiyun 		CCM_ANALOG_PLL_VIDEO_CLR_POWERDOWN_MASK |
788*4882a593Smuzhiyun 		CCM_ANALOG_PLL_VIDEO_CLR_BYPASS_MASK |
789*4882a593Smuzhiyun 		CCM_ANALOG_PLL_VIDEO_CLR_DIV_SELECT_MASK |
790*4882a593Smuzhiyun 		CCM_ANALOG_PLL_VIDEO_CLR_POST_DIV_SEL_MASK |
791*4882a593Smuzhiyun 		CCM_ANALOG_PLL_VIDEO_CLR_TEST_DIV_SELECT_MASK,
792*4882a593Smuzhiyun 		&ccm_anatop->pll_video_clr);
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	/* Set div, num and denom */
795*4882a593Smuzhiyun 	switch (post_div) {
796*4882a593Smuzhiyun 	case 1:
797*4882a593Smuzhiyun 		writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) |
798*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x1) |
799*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0),
800*4882a593Smuzhiyun 			&ccm_anatop->pll_video_set);
801*4882a593Smuzhiyun 		break;
802*4882a593Smuzhiyun 	case 2:
803*4882a593Smuzhiyun 		writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) |
804*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) |
805*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0),
806*4882a593Smuzhiyun 			&ccm_anatop->pll_video_set);
807*4882a593Smuzhiyun 		break;
808*4882a593Smuzhiyun 	case 3:
809*4882a593Smuzhiyun 		writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) |
810*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) |
811*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x1),
812*4882a593Smuzhiyun 			&ccm_anatop->pll_video_set);
813*4882a593Smuzhiyun 		break;
814*4882a593Smuzhiyun 	case 4:
815*4882a593Smuzhiyun 		writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) |
816*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) |
817*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x3),
818*4882a593Smuzhiyun 			&ccm_anatop->pll_video_set);
819*4882a593Smuzhiyun 		break;
820*4882a593Smuzhiyun 	case 0:
821*4882a593Smuzhiyun 	default:
822*4882a593Smuzhiyun 		writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) |
823*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x2) |
824*4882a593Smuzhiyun 			CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0),
825*4882a593Smuzhiyun 			&ccm_anatop->pll_video_set);
826*4882a593Smuzhiyun 		break;
827*4882a593Smuzhiyun 	}
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	writel(CCM_ANALOG_PLL_VIDEO_NUM_A(pll_num),
830*4882a593Smuzhiyun 		&ccm_anatop->pll_video_num);
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun 	writel(CCM_ANALOG_PLL_VIDEO_DENOM_B(pll_denom),
833*4882a593Smuzhiyun 		&ccm_anatop->pll_video_denom);
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun 	/* Wait PLL5 lock */
836*4882a593Smuzhiyun 	start = get_timer(0);	/* Get current timestamp */
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun 	do {
839*4882a593Smuzhiyun 		reg = readl(&ccm_anatop->pll_video);
840*4882a593Smuzhiyun 		if (reg & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) {
841*4882a593Smuzhiyun 			/* Enable PLL out */
842*4882a593Smuzhiyun 			writel(CCM_ANALOG_PLL_VIDEO_CLR_ENABLE_CLK_MASK,
843*4882a593Smuzhiyun 					&ccm_anatop->pll_video_set);
844*4882a593Smuzhiyun 			return 0;
845*4882a593Smuzhiyun 		}
846*4882a593Smuzhiyun 	} while (get_timer(0) < (start + 10)); /* Wait 10ms */
847*4882a593Smuzhiyun 
848*4882a593Smuzhiyun 	printf("Lock PLL5 timeout\n");
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 	return 1;
851*4882a593Smuzhiyun }
852*4882a593Smuzhiyun 
set_clk_qspi(void)853*4882a593Smuzhiyun int set_clk_qspi(void)
854*4882a593Smuzhiyun {
855*4882a593Smuzhiyun 	u32 target;
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun 	/* disable the clock gate first */
858*4882a593Smuzhiyun 	clock_enable(CCGR_QSPI, 0);
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	/* 49M: 392/2/4 */
861*4882a593Smuzhiyun 	target = CLK_ROOT_ON | QSPI_CLK_ROOT_FROM_PLL_SYS_PFD4_CLK |
862*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
863*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2);
864*4882a593Smuzhiyun 	clock_set_target_val(QSPI_CLK_ROOT, target);
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun 	/* enable the clock gate */
867*4882a593Smuzhiyun 	clock_enable(CCGR_QSPI, 1);
868*4882a593Smuzhiyun 
869*4882a593Smuzhiyun 	return 0;
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun 
set_clk_nand(void)872*4882a593Smuzhiyun int set_clk_nand(void)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun 	u32 target;
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 	/* disable the clock gate first */
877*4882a593Smuzhiyun 	clock_enable(CCGR_RAWNAND, 0);
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun 	enable_pll_enet();
880*4882a593Smuzhiyun 	/* 100: 500/5 */
881*4882a593Smuzhiyun 	target = CLK_ROOT_ON | NAND_CLK_ROOT_FROM_PLL_ENET_MAIN_500M_CLK |
882*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
883*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV5);
884*4882a593Smuzhiyun 	clock_set_target_val(NAND_CLK_ROOT, target);
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	/* enable the clock gate */
887*4882a593Smuzhiyun 	clock_enable(CCGR_RAWNAND, 1);
888*4882a593Smuzhiyun 
889*4882a593Smuzhiyun 	return 0;
890*4882a593Smuzhiyun }
891*4882a593Smuzhiyun 
mxs_set_lcdclk(uint32_t base_addr,uint32_t freq)892*4882a593Smuzhiyun void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq)
893*4882a593Smuzhiyun {
894*4882a593Smuzhiyun 	u32 hck = MXC_HCLK/1000;
895*4882a593Smuzhiyun 	u32 min = hck * 27;
896*4882a593Smuzhiyun 	u32 max = hck * 54;
897*4882a593Smuzhiyun 	u32 temp, best = 0;
898*4882a593Smuzhiyun 	u32 i, j, pred = 1, postd = 1;
899*4882a593Smuzhiyun 	u32 pll_div, pll_num, pll_denom, post_div = 0;
900*4882a593Smuzhiyun 	u32 target;
901*4882a593Smuzhiyun 
902*4882a593Smuzhiyun 	debug("mxs_set_lcdclk, freq = %d\n", freq);
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	clock_enable(CCGR_LCDIF, 0);
905*4882a593Smuzhiyun 
906*4882a593Smuzhiyun 	temp = (freq * 8 * 8);
907*4882a593Smuzhiyun 	if (temp < min) {
908*4882a593Smuzhiyun 		for (i = 1; i <= 4; i++) {
909*4882a593Smuzhiyun 			if ((temp * (1 << i)) > min) {
910*4882a593Smuzhiyun 				post_div = i;
911*4882a593Smuzhiyun 				freq = (freq * (1 << i));
912*4882a593Smuzhiyun 				break;
913*4882a593Smuzhiyun 			}
914*4882a593Smuzhiyun 		}
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 		if (5 == i) {
917*4882a593Smuzhiyun 			printf("Fail to set rate to %dkhz", freq);
918*4882a593Smuzhiyun 			return;
919*4882a593Smuzhiyun 		}
920*4882a593Smuzhiyun 	}
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun 	for (i = 1; i <= 8; i++) {
923*4882a593Smuzhiyun 		for (j = 1; j <= 8; j++) {
924*4882a593Smuzhiyun 			temp = freq * i * j;
925*4882a593Smuzhiyun 			if (temp > max || temp < min)
926*4882a593Smuzhiyun 				continue;
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun 			if (best == 0 || temp < best) {
929*4882a593Smuzhiyun 				best = temp;
930*4882a593Smuzhiyun 				pred = i;
931*4882a593Smuzhiyun 				postd = j;
932*4882a593Smuzhiyun 			}
933*4882a593Smuzhiyun 		}
934*4882a593Smuzhiyun 	}
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	if (best == 0) {
937*4882a593Smuzhiyun 		printf("Fail to set rate to %dkhz", freq);
938*4882a593Smuzhiyun 		return;
939*4882a593Smuzhiyun 	}
940*4882a593Smuzhiyun 
941*4882a593Smuzhiyun 	debug("best %d, pred = %d, postd = %d\n", best, pred, postd);
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	pll_div = best / hck;
944*4882a593Smuzhiyun 	pll_denom = 1000000;
945*4882a593Smuzhiyun 	pll_num = (best - hck * pll_div) * pll_denom / hck;
946*4882a593Smuzhiyun 
947*4882a593Smuzhiyun 	if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
948*4882a593Smuzhiyun 		return;
949*4882a593Smuzhiyun 
950*4882a593Smuzhiyun 	target = CLK_ROOT_ON | LCDIF_PIXEL_CLK_ROOT_FROM_PLL_VIDEO_MAIN_CLK |
951*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV((pred - 1)) | CLK_ROOT_POST_DIV((postd - 1));
952*4882a593Smuzhiyun 	clock_set_target_val(LCDIF_PIXEL_CLK_ROOT, target);
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 	clock_enable(CCGR_LCDIF, 1);
955*4882a593Smuzhiyun }
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun #ifdef CONFIG_FEC_MXC
set_clk_enet(enum enet_freq type)958*4882a593Smuzhiyun int set_clk_enet(enum enet_freq type)
959*4882a593Smuzhiyun {
960*4882a593Smuzhiyun 	u32 target;
961*4882a593Smuzhiyun 	int ret;
962*4882a593Smuzhiyun 	u32 enet1_ref, enet2_ref;
963*4882a593Smuzhiyun 
964*4882a593Smuzhiyun 	/* disable the clock first */
965*4882a593Smuzhiyun 	clock_enable(CCGR_ENET1, 0);
966*4882a593Smuzhiyun 	clock_enable(CCGR_ENET2, 0);
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun 	switch (type) {
969*4882a593Smuzhiyun 	case ENET_125MHz:
970*4882a593Smuzhiyun 		enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK;
971*4882a593Smuzhiyun 		enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK;
972*4882a593Smuzhiyun 		break;
973*4882a593Smuzhiyun 	case ENET_50MHz:
974*4882a593Smuzhiyun 		enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK;
975*4882a593Smuzhiyun 		enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK;
976*4882a593Smuzhiyun 		break;
977*4882a593Smuzhiyun 	case ENET_25MHz:
978*4882a593Smuzhiyun 		enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK;
979*4882a593Smuzhiyun 		enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK;
980*4882a593Smuzhiyun 		break;
981*4882a593Smuzhiyun 	default:
982*4882a593Smuzhiyun 		return -EINVAL;
983*4882a593Smuzhiyun 	}
984*4882a593Smuzhiyun 
985*4882a593Smuzhiyun 	ret = enable_pll_enet();
986*4882a593Smuzhiyun 	if (ret != 0)
987*4882a593Smuzhiyun 		return ret;
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 	/* set enet axi clock 196M: 392/2 */
990*4882a593Smuzhiyun 	target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_PLL_SYS_PFD4_CLK |
991*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
992*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2);
993*4882a593Smuzhiyun 	clock_set_target_val(ENET_AXI_CLK_ROOT, target);
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun 	target = CLK_ROOT_ON | enet1_ref |
996*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
997*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
998*4882a593Smuzhiyun 	clock_set_target_val(ENET1_REF_CLK_ROOT, target);
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	target = CLK_ROOT_ON | ENET1_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK |
1001*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
1002*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
1003*4882a593Smuzhiyun 	clock_set_target_val(ENET1_TIME_CLK_ROOT, target);
1004*4882a593Smuzhiyun 
1005*4882a593Smuzhiyun 	target = CLK_ROOT_ON | enet2_ref |
1006*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
1007*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
1008*4882a593Smuzhiyun 	clock_set_target_val(ENET2_REF_CLK_ROOT, target);
1009*4882a593Smuzhiyun 
1010*4882a593Smuzhiyun 	target = CLK_ROOT_ON | ENET2_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK |
1011*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
1012*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
1013*4882a593Smuzhiyun 	clock_set_target_val(ENET2_TIME_CLK_ROOT, target);
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun #ifdef CONFIG_FEC_MXC_25M_REF_CLK
1016*4882a593Smuzhiyun 	target = CLK_ROOT_ON |
1017*4882a593Smuzhiyun 		 ENET_PHY_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK |
1018*4882a593Smuzhiyun 		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
1019*4882a593Smuzhiyun 		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
1020*4882a593Smuzhiyun 	clock_set_target_val(ENET_PHY_REF_CLK_ROOT, target);
1021*4882a593Smuzhiyun #endif
1022*4882a593Smuzhiyun 	/* enable clock */
1023*4882a593Smuzhiyun 	clock_enable(CCGR_ENET1, 1);
1024*4882a593Smuzhiyun 	clock_enable(CCGR_ENET2, 1);
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 	return 0;
1027*4882a593Smuzhiyun }
1028*4882a593Smuzhiyun #endif
1029*4882a593Smuzhiyun 
1030*4882a593Smuzhiyun /* Configure PLL/PFD freq */
clock_init(void)1031*4882a593Smuzhiyun void clock_init(void)
1032*4882a593Smuzhiyun {
1033*4882a593Smuzhiyun /* Rom has enabled PLL_ARM, PLL_DDR, PLL_SYS, PLL_ENET
1034*4882a593Smuzhiyun  *   In u-boot, we have to:
1035*4882a593Smuzhiyun  *   1. Configure PFD3- PFD7 for freq we needed in u-boot
1036*4882a593Smuzhiyun  *   2. Set clock root for peripherals (ip channel) used in u-boot but without set rate
1037*4882a593Smuzhiyun  *       interface.  The clocks for these peripherals are enabled after this intialization.
1038*4882a593Smuzhiyun  *   3. Other peripherals with set clock rate interface does not be set in this function.
1039*4882a593Smuzhiyun  */
1040*4882a593Smuzhiyun 	u32 reg;
1041*4882a593Smuzhiyun 
1042*4882a593Smuzhiyun 	/*
1043*4882a593Smuzhiyun 	 * Configure PFD4 to 392M
1044*4882a593Smuzhiyun 	 * 480M * 18 / 0x16 = 392M
1045*4882a593Smuzhiyun 	 */
1046*4882a593Smuzhiyun 	reg = readl(&ccm_anatop->pfd_480b);
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun 	reg &= ~(ANATOP_PFD480B_PFD4_FRAC_MASK |
1049*4882a593Smuzhiyun 		 CCM_ANALOG_PFD_480B_PFD4_DIV1_CLKGATE_MASK);
1050*4882a593Smuzhiyun 	reg |= ANATOP_PFD480B_PFD4_FRAC_392M_VAL;
1051*4882a593Smuzhiyun 
1052*4882a593Smuzhiyun 	writel(reg, &ccm_anatop->pfd_480b);
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun 	init_clk_esdhc();
1055*4882a593Smuzhiyun 	init_clk_uart();
1056*4882a593Smuzhiyun 	init_clk_weim();
1057*4882a593Smuzhiyun 	init_clk_ecspi();
1058*4882a593Smuzhiyun 	init_clk_wdog();
1059*4882a593Smuzhiyun #ifdef CONFIG_MXC_EPDC
1060*4882a593Smuzhiyun 	init_clk_epdc();
1061*4882a593Smuzhiyun #endif
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 	enable_usboh3_clk(1);
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun 	clock_enable(CCGR_SNVS, 1);
1066*4882a593Smuzhiyun 
1067*4882a593Smuzhiyun #ifdef CONFIG_NAND_MXS
1068*4882a593Smuzhiyun 	clock_enable(CCGR_RAWNAND, 1);
1069*4882a593Smuzhiyun #endif
1070*4882a593Smuzhiyun 
1071*4882a593Smuzhiyun 	if (IS_ENABLED(CONFIG_IMX_RDC)) {
1072*4882a593Smuzhiyun 		clock_enable(CCGR_RDC, 1);
1073*4882a593Smuzhiyun 		clock_enable(CCGR_SEMA1, 1);
1074*4882a593Smuzhiyun 		clock_enable(CCGR_SEMA2, 1);
1075*4882a593Smuzhiyun 	}
1076*4882a593Smuzhiyun }
1077*4882a593Smuzhiyun 
1078*4882a593Smuzhiyun #ifdef CONFIG_SECURE_BOOT
hab_caam_clock_enable(unsigned char enable)1079*4882a593Smuzhiyun void hab_caam_clock_enable(unsigned char enable)
1080*4882a593Smuzhiyun {
1081*4882a593Smuzhiyun 	if (enable)
1082*4882a593Smuzhiyun 		clock_enable(CCGR_CAAM, 1);
1083*4882a593Smuzhiyun 	else
1084*4882a593Smuzhiyun 		clock_enable(CCGR_CAAM, 0);
1085*4882a593Smuzhiyun }
1086*4882a593Smuzhiyun #endif
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun #ifdef CONFIG_MXC_EPDC
epdc_clock_enable(void)1089*4882a593Smuzhiyun void epdc_clock_enable(void)
1090*4882a593Smuzhiyun {
1091*4882a593Smuzhiyun 	clock_enable(CCGR_EPDC, 1);
1092*4882a593Smuzhiyun }
epdc_clock_disable(void)1093*4882a593Smuzhiyun void epdc_clock_disable(void)
1094*4882a593Smuzhiyun {
1095*4882a593Smuzhiyun 	clock_enable(CCGR_EPDC, 0);
1096*4882a593Smuzhiyun }
1097*4882a593Smuzhiyun #endif
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun /*
1100*4882a593Smuzhiyun  * Dump some core clockes.
1101*4882a593Smuzhiyun  */
do_mx7_showclocks(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])1102*4882a593Smuzhiyun int do_mx7_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1103*4882a593Smuzhiyun {
1104*4882a593Smuzhiyun 	u32 freq;
1105*4882a593Smuzhiyun 	freq = decode_pll(PLL_CORE, MXC_HCLK);
1106*4882a593Smuzhiyun 	printf("PLL_CORE    %8d MHz\n", freq / 1000000);
1107*4882a593Smuzhiyun 	freq = decode_pll(PLL_SYS, MXC_HCLK);
1108*4882a593Smuzhiyun 	printf("PLL_SYS    %8d MHz\n", freq / 1000000);
1109*4882a593Smuzhiyun 	freq = decode_pll(PLL_ENET, MXC_HCLK);
1110*4882a593Smuzhiyun 	printf("PLL_NET    %8d MHz\n", freq / 1000000);
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun 	printf("\n");
1113*4882a593Smuzhiyun 
1114*4882a593Smuzhiyun 	printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
1115*4882a593Smuzhiyun 	printf("UART       %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000);
1116*4882a593Smuzhiyun #ifdef CONFIG_MXC_SPI
1117*4882a593Smuzhiyun 	printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
1118*4882a593Smuzhiyun #endif
1119*4882a593Smuzhiyun 	printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
1120*4882a593Smuzhiyun 	printf("AXI        %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000);
1121*4882a593Smuzhiyun 	printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
1122*4882a593Smuzhiyun 	printf("USDHC1     %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000);
1123*4882a593Smuzhiyun 	printf("USDHC2     %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000);
1124*4882a593Smuzhiyun 	printf("USDHC3     %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000);
1125*4882a593Smuzhiyun 
1126*4882a593Smuzhiyun 	return 0;
1127*4882a593Smuzhiyun }
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun U_BOOT_CMD(
1130*4882a593Smuzhiyun 	clocks,	CONFIG_SYS_MAXARGS, 1, do_mx7_showclocks,
1131*4882a593Smuzhiyun 	"display clocks",
1132*4882a593Smuzhiyun 	""
1133*4882a593Smuzhiyun );
1134