xref: /rk3399_rockchip-uboot/arch/arm/mach-imx/mx7/clock_slice.c (revision 39632b4a01210e329333d787d828157dcd2c7328)
1*552a848eSStefano Babic /*
2*552a848eSStefano Babic  * Copyright (C) 2015 Freescale Semiconductor, Inc.
3*552a848eSStefano Babic  *
4*552a848eSStefano Babic  * Author:
5*552a848eSStefano Babic  *	Peng Fan <Peng.Fan@freescale.com>
6*552a848eSStefano Babic  *
7*552a848eSStefano Babic  * SPDX-License-Identifier:	GPL-2.0+
8*552a848eSStefano Babic  */
9*552a848eSStefano Babic 
10*552a848eSStefano Babic #include <common.h>
11*552a848eSStefano Babic #include <div64.h>
12*552a848eSStefano Babic #include <asm/io.h>
13*552a848eSStefano Babic #include <linux/errno.h>
14*552a848eSStefano Babic #include <asm/arch/imx-regs.h>
15*552a848eSStefano Babic #include <asm/arch/crm_regs.h>
16*552a848eSStefano Babic #include <asm/arch/clock.h>
17*552a848eSStefano Babic #include <asm/arch/sys_proto.h>
18*552a848eSStefano Babic 
19*552a848eSStefano Babic struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
20*552a848eSStefano Babic 
21*552a848eSStefano Babic static struct clk_root_map root_array[] = {
22*552a848eSStefano Babic 	{ARM_A7_CLK_ROOT, CCM_CORE_CHANNEL,
23*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ARM_MAIN_800M_CLK, PLL_ENET_MAIN_500M_CLK,
24*552a848eSStefano Babic 	  PLL_DRAM_MAIN_1066M_CLK, PLL_SYS_MAIN_480M_CLK,
25*552a848eSStefano Babic 	  PLL_SYS_PFD0_392M_CLK, PLL_AUDIO_MAIN_CLK, PLL_USB_MAIN_480M_CLK}
26*552a848eSStefano Babic 	},
27*552a848eSStefano Babic 	{ARM_M4_CLK_ROOT, CCM_BUS_CHANNEL,
28*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_250M_CLK,
29*552a848eSStefano Babic 	  PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK,
30*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK}
31*552a848eSStefano Babic 	},
32*552a848eSStefano Babic 	{ARM_M0_CLK_ROOT, CCM_BUS_CHANNEL,
33*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_125M_CLK,
34*552a848eSStefano Babic 	  PLL_SYS_PFD2_135M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK,
35*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK}
36*552a848eSStefano Babic 	},
37*552a848eSStefano Babic 	{MAIN_AXI_CLK_ROOT, CCM_BUS_CHANNEL,
38*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK,
39*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_SYS_PFD5_CLK, PLL_AUDIO_MAIN_CLK,
40*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD7_CLK}
41*552a848eSStefano Babic 	},
42*552a848eSStefano Babic 	{DISP_AXI_CLK_ROOT, CCM_BUS_CHANNEL,
43*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK,
44*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK,
45*552a848eSStefano Babic 	  PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK}
46*552a848eSStefano Babic 	},
47*552a848eSStefano Babic 	{ENET_AXI_CLK_ROOT, CCM_IP_CHANNEL,
48*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK,
49*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_AUDIO_MAIN_CLK,
50*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK}
51*552a848eSStefano Babic 	},
52*552a848eSStefano Babic 	{NAND_USDHC_BUS_CLK_ROOT, CCM_IP_CHANNEL,
53*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK,
54*552a848eSStefano Babic 	  PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_PFD6_CLK,
55*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_AUDIO_MAIN_CLK}
56*552a848eSStefano Babic 	},
57*552a848eSStefano Babic 	{AHB_CLK_ROOT, CCM_AHB_CHANNEL,
58*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK,
59*552a848eSStefano Babic 	  PLL_SYS_PFD0_392M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK,
60*552a848eSStefano Babic 	  PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK}
61*552a848eSStefano Babic 	},
62*552a848eSStefano Babic 	{DRAM_PHYM_CLK_ROOT, CCM_DRAM_PHYM_CHANNEL,
63*552a848eSStefano Babic 	 {PLL_DRAM_MAIN_1066M_CLK, DRAM_PHYM_ALT_CLK_ROOT}
64*552a848eSStefano Babic 	},
65*552a848eSStefano Babic 	{DRAM_CLK_ROOT, CCM_DRAM_CHANNEL,
66*552a848eSStefano Babic 	 {PLL_DRAM_MAIN_1066M_CLK, DRAM_ALT_CLK_ROOT}
67*552a848eSStefano Babic 	},
68*552a848eSStefano Babic 	{DRAM_PHYM_ALT_CLK_ROOT, CCM_IP_CHANNEL,
69*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_SYS_MAIN_480M_CLK,
70*552a848eSStefano Babic 	  PLL_ENET_MAIN_500M_CLK, PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD7_CLK,
71*552a848eSStefano Babic 	  PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK}
72*552a848eSStefano Babic 	},
73*552a848eSStefano Babic 	{DRAM_ALT_CLK_ROOT, CCM_IP_CHANNEL,
74*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_SYS_MAIN_480M_CLK,
75*552a848eSStefano Babic 	  PLL_ENET_MAIN_500M_CLK, PLL_ENET_MAIN_250M_CLK,
76*552a848eSStefano Babic 	  PLL_SYS_PFD0_392M_CLK, PLL_AUDIO_MAIN_CLK, PLL_SYS_PFD2_270M_CLK}
77*552a848eSStefano Babic 	},
78*552a848eSStefano Babic 	{USB_HSIC_CLK_ROOT, CCM_IP_CHANNEL,
79*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_USB_MAIN_480M_CLK,
80*552a848eSStefano Babic 	  PLL_SYS_PFD3_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD5_CLK,
81*552a848eSStefano Babic 	  PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK}
82*552a848eSStefano Babic 	},
83*552a848eSStefano Babic 	{PCIE_CTRL_CLK_ROOT, CCM_IP_CHANNEL,
84*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_250M_CLK, PLL_SYS_MAIN_240M_CLK,
85*552a848eSStefano Babic 	  PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK,
86*552a848eSStefano Babic 	  PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_SYS_PFD6_CLK}
87*552a848eSStefano Babic 	},
88*552a848eSStefano Babic 	{PCIE_PHY_CLK_ROOT, CCM_IP_CHANNEL,
89*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_ENET_MAIN_500M_CLK,
90*552a848eSStefano Babic 	  EXT_CLK_1, EXT_CLK_2, EXT_CLK_3,
91*552a848eSStefano Babic 	  EXT_CLK_4, PLL_SYS_PFD0_392M_CLK}
92*552a848eSStefano Babic 	},
93*552a848eSStefano Babic 	{EPDC_PIXEL_CLK_ROOT, CCM_IP_CHANNEL,
94*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK,
95*552a848eSStefano Babic 	  PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD5_CLK, PLL_SYS_PFD6_CLK,
96*552a848eSStefano Babic 	  PLL_SYS_PFD7_CLK, PLL_VIDEO_MAIN_CLK}
97*552a848eSStefano Babic 	},
98*552a848eSStefano Babic 	{LCDIF_PIXEL_CLK_ROOT, CCM_IP_CHANNEL,
99*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD5_CLK, PLL_DRAM_MAIN_533M_CLK,
100*552a848eSStefano Babic 	  EXT_CLK_3, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK,
101*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK}
102*552a848eSStefano Babic 	},
103*552a848eSStefano Babic 	{MIPI_DSI_EXTSER_CLK_ROOT, CCM_IP_CHANNEL,
104*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD5_CLK, PLL_SYS_PFD3_CLK,
105*552a848eSStefano Babic 	  PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD0_196M_CLK, PLL_DRAM_MAIN_533M_CLK,
106*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_AUDIO_MAIN_CLK}
107*552a848eSStefano Babic 	},
108*552a848eSStefano Babic 	{MIPI_CSI_WARP_CLK_ROOT, CCM_IP_CHANNEL,
109*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD3_CLK,
110*552a848eSStefano Babic 	  PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD0_196M_CLK, PLL_DRAM_MAIN_533M_CLK,
111*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_AUDIO_MAIN_CLK}
112*552a848eSStefano Babic 	},
113*552a848eSStefano Babic 	{MIPI_DPHY_REF_CLK_ROOT, CCM_IP_CHANNEL,
114*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK,
115*552a848eSStefano Babic 	  PLL_SYS_PFD5_CLK, REF_1M_CLK, EXT_CLK_2,
116*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, EXT_CLK_3}
117*552a848eSStefano Babic 	},
118*552a848eSStefano Babic 	{SAI1_CLK_ROOT, CCM_IP_CHANNEL,
119*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK,
120*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK,
121*552a848eSStefano Babic 	  PLL_ENET_MAIN_125M_CLK, EXT_CLK_2}
122*552a848eSStefano Babic 	},
123*552a848eSStefano Babic 	{SAI2_CLK_ROOT, CCM_IP_CHANNEL,
124*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK,
125*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK,
126*552a848eSStefano Babic 	  PLL_ENET_MAIN_125M_CLK, EXT_CLK_2}
127*552a848eSStefano Babic 	},
128*552a848eSStefano Babic 	{SAI3_CLK_ROOT, CCM_IP_CHANNEL,
129*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK,
130*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK,
131*552a848eSStefano Babic 	  PLL_ENET_MAIN_125M_CLK, EXT_CLK_3}
132*552a848eSStefano Babic 	},
133*552a848eSStefano Babic 	{SPDIF_CLK_ROOT, CCM_IP_CHANNEL,
134*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK,
135*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK,
136*552a848eSStefano Babic 	  PLL_ENET_MAIN_125M_CLK, EXT_CLK_3}
137*552a848eSStefano Babic 	},
138*552a848eSStefano Babic 	{ENET1_REF_CLK_ROOT, CCM_IP_CHANNEL,
139*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_ENET_MAIN_50M_CLK,
140*552a848eSStefano Babic 	  PLL_ENET_MAIN_25M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_AUDIO_MAIN_CLK,
141*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, EXT_CLK_4}
142*552a848eSStefano Babic 	},
143*552a848eSStefano Babic 	{ENET1_TIME_CLK_ROOT, CCM_IP_CHANNEL,
144*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_AUDIO_MAIN_CLK,
145*552a848eSStefano Babic 	  EXT_CLK_1, EXT_CLK_2, EXT_CLK_3,
146*552a848eSStefano Babic 	  EXT_CLK_4, PLL_VIDEO_MAIN_CLK}
147*552a848eSStefano Babic 	},
148*552a848eSStefano Babic 	{ENET2_REF_CLK_ROOT, CCM_IP_CHANNEL,
149*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_ENET_MAIN_50M_CLK,
150*552a848eSStefano Babic 	  PLL_ENET_MAIN_25M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_AUDIO_MAIN_CLK,
151*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, EXT_CLK_4}
152*552a848eSStefano Babic 	},
153*552a848eSStefano Babic 	{ENET2_TIME_CLK_ROOT, CCM_IP_CHANNEL,
154*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_AUDIO_MAIN_CLK,
155*552a848eSStefano Babic 	  EXT_CLK_1, EXT_CLK_2, EXT_CLK_3,
156*552a848eSStefano Babic 	  EXT_CLK_4, PLL_VIDEO_MAIN_CLK}
157*552a848eSStefano Babic 	},
158*552a848eSStefano Babic 	{ENET_PHY_REF_CLK_ROOT, CCM_IP_CHANNEL,
159*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_25M_CLK, PLL_ENET_MAIN_50M_CLK,
160*552a848eSStefano Babic 	  PLL_ENET_MAIN_125M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK,
161*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD3_CLK}
162*552a848eSStefano Babic 	},
163*552a848eSStefano Babic 	{EIM_CLK_ROOT, CCM_IP_CHANNEL,
164*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK,
165*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_SYS_PFD3_CLK,
166*552a848eSStefano Babic 	  PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK}
167*552a848eSStefano Babic 	},
168*552a848eSStefano Babic 	{NAND_CLK_ROOT, CCM_IP_CHANNEL,
169*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_DRAM_MAIN_533M_CLK,
170*552a848eSStefano Babic 	  PLL_SYS_PFD0_392M_CLK, PLL_SYS_PFD3_CLK, PLL_ENET_MAIN_500M_CLK,
171*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_VIDEO_MAIN_CLK}
172*552a848eSStefano Babic 	},
173*552a848eSStefano Babic 	{QSPI_CLK_ROOT, CCM_IP_CHANNEL,
174*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD4_CLK, PLL_DRAM_MAIN_533M_CLK,
175*552a848eSStefano Babic 	  PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD3_CLK, PLL_SYS_PFD2_270M_CLK,
176*552a848eSStefano Babic 	  PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK}
177*552a848eSStefano Babic 	},
178*552a848eSStefano Babic 	{USDHC1_CLK_ROOT, CCM_IP_CHANNEL,
179*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK,
180*552a848eSStefano Babic 	  PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK,
181*552a848eSStefano Babic 	  PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK}
182*552a848eSStefano Babic 	},
183*552a848eSStefano Babic 	{USDHC2_CLK_ROOT, CCM_IP_CHANNEL,
184*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK,
185*552a848eSStefano Babic 	  PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK,
186*552a848eSStefano Babic 	  PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK}
187*552a848eSStefano Babic 	},
188*552a848eSStefano Babic 	{USDHC3_CLK_ROOT, CCM_IP_CHANNEL,
189*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK,
190*552a848eSStefano Babic 	  PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK,
191*552a848eSStefano Babic 	  PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK}
192*552a848eSStefano Babic 	},
193*552a848eSStefano Babic 	{CAN1_CLK_ROOT, CCM_IP_CHANNEL,
194*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK,
195*552a848eSStefano Babic 	  PLL_SYS_MAIN_480M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_USB_MAIN_480M_CLK,
196*552a848eSStefano Babic 	  EXT_CLK_1, EXT_CLK_4}
197*552a848eSStefano Babic 	},
198*552a848eSStefano Babic 	{CAN2_CLK_ROOT, CCM_IP_CHANNEL,
199*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK,
200*552a848eSStefano Babic 	  PLL_SYS_MAIN_480M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_USB_MAIN_480M_CLK,
201*552a848eSStefano Babic 	  EXT_CLK_1, EXT_CLK_3}
202*552a848eSStefano Babic 	},
203*552a848eSStefano Babic 	{I2C1_CLK_ROOT, CCM_IP_CHANNEL,
204*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK,
205*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK,
206*552a848eSStefano Babic 	  PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK}
207*552a848eSStefano Babic 	},
208*552a848eSStefano Babic 	{I2C2_CLK_ROOT, CCM_IP_CHANNEL,
209*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK,
210*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK,
211*552a848eSStefano Babic 	  PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK}
212*552a848eSStefano Babic 	},
213*552a848eSStefano Babic 	{I2C3_CLK_ROOT, CCM_IP_CHANNEL,
214*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK,
215*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK,
216*552a848eSStefano Babic 	  PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK}
217*552a848eSStefano Babic 	},
218*552a848eSStefano Babic 	{I2C4_CLK_ROOT, CCM_IP_CHANNEL,
219*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK,
220*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK,
221*552a848eSStefano Babic 	  PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK}
222*552a848eSStefano Babic 	},
223*552a848eSStefano Babic 	{UART1_CLK_ROOT, CCM_IP_CHANNEL,
224*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
225*552a848eSStefano Babic 	  PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2,
226*552a848eSStefano Babic 	  EXT_CLK_4, PLL_USB_MAIN_480M_CLK}
227*552a848eSStefano Babic 	},
228*552a848eSStefano Babic 	{UART2_CLK_ROOT, CCM_IP_CHANNEL,
229*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
230*552a848eSStefano Babic 	  PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2,
231*552a848eSStefano Babic 	  EXT_CLK_3, PLL_USB_MAIN_480M_CLK}
232*552a848eSStefano Babic 	},
233*552a848eSStefano Babic 	{UART3_CLK_ROOT, CCM_IP_CHANNEL,
234*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
235*552a848eSStefano Babic 	  PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2,
236*552a848eSStefano Babic 	  EXT_CLK_4, PLL_USB_MAIN_480M_CLK}
237*552a848eSStefano Babic 	},
238*552a848eSStefano Babic 	{UART4_CLK_ROOT, CCM_IP_CHANNEL,
239*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
240*552a848eSStefano Babic 	  PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2,
241*552a848eSStefano Babic 	  EXT_CLK_3, PLL_USB_MAIN_480M_CLK}
242*552a848eSStefano Babic 	},
243*552a848eSStefano Babic 	{UART5_CLK_ROOT, CCM_IP_CHANNEL,
244*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
245*552a848eSStefano Babic 	  PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2,
246*552a848eSStefano Babic 	  EXT_CLK_4, PLL_USB_MAIN_480M_CLK}
247*552a848eSStefano Babic 	},
248*552a848eSStefano Babic 	{UART6_CLK_ROOT, CCM_IP_CHANNEL,
249*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
250*552a848eSStefano Babic 	  PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2,
251*552a848eSStefano Babic 	  EXT_CLK_3, PLL_USB_MAIN_480M_CLK}
252*552a848eSStefano Babic 	},
253*552a848eSStefano Babic 	{UART7_CLK_ROOT, CCM_IP_CHANNEL,
254*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
255*552a848eSStefano Babic 	  PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2,
256*552a848eSStefano Babic 	  EXT_CLK_4, PLL_USB_MAIN_480M_CLK}
257*552a848eSStefano Babic 	},
258*552a848eSStefano Babic 	{ECSPI1_CLK_ROOT, CCM_IP_CHANNEL,
259*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
260*552a848eSStefano Babic 	  PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK,
261*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK}
262*552a848eSStefano Babic 	},
263*552a848eSStefano Babic 	{ECSPI2_CLK_ROOT, CCM_IP_CHANNEL,
264*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
265*552a848eSStefano Babic 	  PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK,
266*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK}
267*552a848eSStefano Babic 	},
268*552a848eSStefano Babic 	{ECSPI3_CLK_ROOT, CCM_IP_CHANNEL,
269*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
270*552a848eSStefano Babic 	  PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK,
271*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK}
272*552a848eSStefano Babic 	},
273*552a848eSStefano Babic 	{ECSPI4_CLK_ROOT, CCM_IP_CHANNEL,
274*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK,
275*552a848eSStefano Babic 	  PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK,
276*552a848eSStefano Babic 	  PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK}
277*552a848eSStefano Babic 	},
278*552a848eSStefano Babic 	{PWM1_CLK_ROOT, CCM_IP_CHANNEL,
279*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK,
280*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_1,
281*552a848eSStefano Babic 	  REF_1M_CLK, PLL_VIDEO_MAIN_CLK}
282*552a848eSStefano Babic 	},
283*552a848eSStefano Babic 	{PWM2_CLK_ROOT, CCM_IP_CHANNEL,
284*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK,
285*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_1,
286*552a848eSStefano Babic 	  REF_1M_CLK, PLL_VIDEO_MAIN_CLK}
287*552a848eSStefano Babic 	},
288*552a848eSStefano Babic 	{PWM3_CLK_ROOT, CCM_IP_CHANNEL,
289*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK,
290*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_2,
291*552a848eSStefano Babic 	  REF_1M_CLK, PLL_VIDEO_MAIN_CLK}
292*552a848eSStefano Babic 	},
293*552a848eSStefano Babic 	{PWM4_CLK_ROOT, CCM_IP_CHANNEL,
294*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK,
295*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_2,
296*552a848eSStefano Babic 	  REF_1M_CLK, PLL_VIDEO_MAIN_CLK}
297*552a848eSStefano Babic 	},
298*552a848eSStefano Babic 	{FLEXTIMER1_CLK_ROOT, CCM_IP_CHANNEL,
299*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK,
300*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_3,
301*552a848eSStefano Babic 	  REF_1M_CLK, PLL_VIDEO_MAIN_CLK}
302*552a848eSStefano Babic 	},
303*552a848eSStefano Babic 	{FLEXTIMER2_CLK_ROOT, CCM_IP_CHANNEL,
304*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK,
305*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_3,
306*552a848eSStefano Babic 	  REF_1M_CLK, PLL_VIDEO_MAIN_CLK}
307*552a848eSStefano Babic 	},
308*552a848eSStefano Babic 	{SIM1_CLK_ROOT, CCM_IP_CHANNEL,
309*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK,
310*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_USB_MAIN_480M_CLK, PLL_AUDIO_MAIN_CLK,
311*552a848eSStefano Babic 	  PLL_ENET_MAIN_125M_CLK, PLL_SYS_PFD7_CLK}
312*552a848eSStefano Babic 	},
313*552a848eSStefano Babic 	{SIM2_CLK_ROOT, CCM_IP_CHANNEL,
314*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK,
315*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_USB_MAIN_480M_CLK, PLL_VIDEO_MAIN_CLK,
316*552a848eSStefano Babic 	  PLL_ENET_MAIN_125M_CLK, PLL_SYS_PFD7_CLK}
317*552a848eSStefano Babic 	},
318*552a848eSStefano Babic 	{GPT1_CLK_ROOT, CCM_IP_CHANNEL,
319*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK,
320*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK,
321*552a848eSStefano Babic 	  PLL_AUDIO_MAIN_CLK, EXT_CLK_1}
322*552a848eSStefano Babic 	},
323*552a848eSStefano Babic 	{GPT2_CLK_ROOT, CCM_IP_CHANNEL,
324*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK,
325*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK,
326*552a848eSStefano Babic 	  PLL_AUDIO_MAIN_CLK, EXT_CLK_2}
327*552a848eSStefano Babic 	},
328*552a848eSStefano Babic 	{GPT3_CLK_ROOT, CCM_IP_CHANNEL,
329*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK,
330*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK,
331*552a848eSStefano Babic 	  PLL_AUDIO_MAIN_CLK, EXT_CLK_3}
332*552a848eSStefano Babic 	},
333*552a848eSStefano Babic 	{GPT4_CLK_ROOT, CCM_IP_CHANNEL,
334*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK,
335*552a848eSStefano Babic 	  PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK,
336*552a848eSStefano Babic 	  PLL_AUDIO_MAIN_CLK, EXT_CLK_4}
337*552a848eSStefano Babic 	},
338*552a848eSStefano Babic 	{TRACE_CLK_ROOT, CCM_IP_CHANNEL,
339*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK,
340*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK,
341*552a848eSStefano Babic 	  EXT_CLK_1, EXT_CLK_3}
342*552a848eSStefano Babic 	},
343*552a848eSStefano Babic 	{WDOG_CLK_ROOT, CCM_IP_CHANNEL,
344*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK,
345*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK,
346*552a848eSStefano Babic 	  REF_1M_CLK, PLL_SYS_PFD1_166M_CLK}
347*552a848eSStefano Babic 	},
348*552a848eSStefano Babic 	{CSI_MCLK_CLK_ROOT, CCM_IP_CHANNEL,
349*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK,
350*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_AUDIO_MAIN_CLK,
351*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK}
352*552a848eSStefano Babic 	},
353*552a848eSStefano Babic 	{AUDIO_MCLK_CLK_ROOT, CCM_IP_CHANNEL,
354*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK,
355*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_AUDIO_MAIN_CLK,
356*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK}
357*552a848eSStefano Babic 	},
358*552a848eSStefano Babic 	{WRCLK_CLK_ROOT, CCM_IP_CHANNEL,
359*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_DRAM_MAIN_533M_CLK,
360*552a848eSStefano Babic 	  PLL_USB_MAIN_480M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD2_270M_CLK,
361*552a848eSStefano Babic 	  PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD7_CLK}
362*552a848eSStefano Babic 	},
363*552a848eSStefano Babic 	{IPP_DO_CLKO1, CCM_IP_CHANNEL,
364*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_MAIN_240M_CLK,
365*552a848eSStefano Babic 	  PLL_SYS_PFD0_196M_CLK, PLL_SYS_PFD3_CLK, PLL_ENET_MAIN_500M_CLK,
366*552a848eSStefano Babic 	  PLL_DRAM_MAIN_533M_CLK, REF_1M_CLK}
367*552a848eSStefano Babic 	},
368*552a848eSStefano Babic 	{IPP_DO_CLKO2, CCM_IP_CHANNEL,
369*552a848eSStefano Babic 	 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD0_392M_CLK,
370*552a848eSStefano Babic 	  PLL_SYS_PFD1_166M_CLK, PLL_SYS_PFD4_CLK, PLL_AUDIO_MAIN_CLK,
371*552a848eSStefano Babic 	  PLL_VIDEO_MAIN_CLK, OSC_32K_CLK}
372*552a848eSStefano Babic 	},
373*552a848eSStefano Babic };
374*552a848eSStefano Babic 
375*552a848eSStefano Babic /* select which entry of root_array */
select(enum clk_root_index clock_id)376*552a848eSStefano Babic static int select(enum clk_root_index clock_id)
377*552a848eSStefano Babic {
378*552a848eSStefano Babic 	int i, size;
379*552a848eSStefano Babic 	struct clk_root_map *p = root_array;
380*552a848eSStefano Babic 
381*552a848eSStefano Babic 	size = ARRAY_SIZE(root_array);
382*552a848eSStefano Babic 
383*552a848eSStefano Babic 	for (i = 0; i < size; i++, p++) {
384*552a848eSStefano Babic 		if (clock_id == p->entry)
385*552a848eSStefano Babic 			return i;
386*552a848eSStefano Babic 	}
387*552a848eSStefano Babic 
388*552a848eSStefano Babic 	return -EINVAL;
389*552a848eSStefano Babic }
390*552a848eSStefano Babic 
src_supported(int entry,enum clk_root_src clock_src)391*552a848eSStefano Babic static int src_supported(int entry, enum clk_root_src clock_src)
392*552a848eSStefano Babic {
393*552a848eSStefano Babic 	int i, size;
394*552a848eSStefano Babic 	struct clk_root_map *p = &root_array[entry];
395*552a848eSStefano Babic 
396*552a848eSStefano Babic 	if ((p->type == CCM_DRAM_PHYM_CHANNEL) || (p->type == CCM_DRAM_CHANNEL))
397*552a848eSStefano Babic 		size = 2;
398*552a848eSStefano Babic 	else
399*552a848eSStefano Babic 		size = 8;
400*552a848eSStefano Babic 
401*552a848eSStefano Babic 	for (i = 0; i < size; i++) {
402*552a848eSStefano Babic 		if (p->src_mux[i] == clock_src)
403*552a848eSStefano Babic 			return i;
404*552a848eSStefano Babic 	}
405*552a848eSStefano Babic 
406*552a848eSStefano Babic 	return -EINVAL;
407*552a848eSStefano Babic }
408*552a848eSStefano Babic 
409*552a848eSStefano Babic /* Set src for clock root slice. */
clock_set_src(enum clk_root_index clock_id,enum clk_root_src clock_src)410*552a848eSStefano Babic int clock_set_src(enum clk_root_index clock_id, enum clk_root_src clock_src)
411*552a848eSStefano Babic {
412*552a848eSStefano Babic 	int root_entry, src_entry;
413*552a848eSStefano Babic 	u32 reg;
414*552a848eSStefano Babic 
415*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
416*552a848eSStefano Babic 		return -EINVAL;
417*552a848eSStefano Babic 
418*552a848eSStefano Babic 	root_entry = select(clock_id);
419*552a848eSStefano Babic 	if (root_entry < 0)
420*552a848eSStefano Babic 		return -EINVAL;
421*552a848eSStefano Babic 
422*552a848eSStefano Babic 	src_entry = src_supported(root_entry, clock_src);
423*552a848eSStefano Babic 	if (src_entry < 0)
424*552a848eSStefano Babic 		return -EINVAL;
425*552a848eSStefano Babic 
426*552a848eSStefano Babic 	reg = __raw_readl(&imx_ccm->root[clock_id].target_root);
427*552a848eSStefano Babic 	reg &= ~CLK_ROOT_MUX_MASK;
428*552a848eSStefano Babic 	reg |= src_entry << CLK_ROOT_MUX_SHIFT;
429*552a848eSStefano Babic 	__raw_writel(reg, &imx_ccm->root[clock_id].target_root);
430*552a848eSStefano Babic 
431*552a848eSStefano Babic 	return 0;
432*552a848eSStefano Babic }
433*552a848eSStefano Babic 
434*552a848eSStefano Babic /* Get src of a clock root slice. */
clock_get_src(enum clk_root_index clock_id,enum clk_root_src * p_clock_src)435*552a848eSStefano Babic int clock_get_src(enum clk_root_index clock_id, enum clk_root_src *p_clock_src)
436*552a848eSStefano Babic {
437*552a848eSStefano Babic 	u32 val;
438*552a848eSStefano Babic 	int root_entry;
439*552a848eSStefano Babic 	struct clk_root_map *p;
440*552a848eSStefano Babic 
441*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
442*552a848eSStefano Babic 		return -EINVAL;
443*552a848eSStefano Babic 
444*552a848eSStefano Babic 	val = __raw_readl(&imx_ccm->root[clock_id].target_root);
445*552a848eSStefano Babic 	val &= CLK_ROOT_MUX_MASK;
446*552a848eSStefano Babic 	val >>= CLK_ROOT_MUX_SHIFT;
447*552a848eSStefano Babic 
448*552a848eSStefano Babic 	root_entry = select(clock_id);
449*552a848eSStefano Babic 	if (root_entry < 0)
450*552a848eSStefano Babic 		return -EINVAL;
451*552a848eSStefano Babic 
452*552a848eSStefano Babic 	p = &root_array[root_entry];
453*552a848eSStefano Babic 	*p_clock_src = p->src_mux[val];
454*552a848eSStefano Babic 
455*552a848eSStefano Babic 	return 0;
456*552a848eSStefano Babic }
457*552a848eSStefano Babic 
clock_set_prediv(enum clk_root_index clock_id,enum root_pre_div pre_div)458*552a848eSStefano Babic int clock_set_prediv(enum clk_root_index clock_id, enum root_pre_div pre_div)
459*552a848eSStefano Babic {
460*552a848eSStefano Babic 	int root_entry;
461*552a848eSStefano Babic 	struct clk_root_map *p;
462*552a848eSStefano Babic 	u32 reg;
463*552a848eSStefano Babic 
464*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
465*552a848eSStefano Babic 		return -EINVAL;
466*552a848eSStefano Babic 
467*552a848eSStefano Babic 	root_entry = select(clock_id);
468*552a848eSStefano Babic 	if (root_entry < 0)
469*552a848eSStefano Babic 		return -EINVAL;
470*552a848eSStefano Babic 
471*552a848eSStefano Babic 	p = &root_array[root_entry];
472*552a848eSStefano Babic 
473*552a848eSStefano Babic 	if ((p->type == CCM_CORE_CHANNEL) ||
474*552a848eSStefano Babic 	    (p->type == CCM_DRAM_PHYM_CHANNEL) ||
475*552a848eSStefano Babic 	    (p->type == CCM_DRAM_CHANNEL)) {
476*552a848eSStefano Babic 		if (pre_div != CLK_ROOT_PRE_DIV1) {
477*552a848eSStefano Babic 			printf("Error pre div!\n");
478*552a848eSStefano Babic 			return -EINVAL;
479*552a848eSStefano Babic 		}
480*552a848eSStefano Babic 	}
481*552a848eSStefano Babic 
482*552a848eSStefano Babic 	reg = __raw_readl(&imx_ccm->root[clock_id].target_root);
483*552a848eSStefano Babic 	reg &= ~CLK_ROOT_PRE_DIV_MASK;
484*552a848eSStefano Babic 	reg |= pre_div << CLK_ROOT_PRE_DIV_SHIFT;
485*552a848eSStefano Babic 	__raw_writel(reg, &imx_ccm->root[clock_id].target_root);
486*552a848eSStefano Babic 
487*552a848eSStefano Babic 	return 0;
488*552a848eSStefano Babic }
489*552a848eSStefano Babic 
clock_get_prediv(enum clk_root_index clock_id,enum root_pre_div * pre_div)490*552a848eSStefano Babic int clock_get_prediv(enum clk_root_index clock_id, enum root_pre_div *pre_div)
491*552a848eSStefano Babic {
492*552a848eSStefano Babic 	u32 val;
493*552a848eSStefano Babic 	int root_entry;
494*552a848eSStefano Babic 	struct clk_root_map *p;
495*552a848eSStefano Babic 
496*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
497*552a848eSStefano Babic 		return -EINVAL;
498*552a848eSStefano Babic 
499*552a848eSStefano Babic 	root_entry = select(clock_id);
500*552a848eSStefano Babic 	if (root_entry < 0)
501*552a848eSStefano Babic 		return -EINVAL;
502*552a848eSStefano Babic 
503*552a848eSStefano Babic 	p = &root_array[root_entry];
504*552a848eSStefano Babic 
505*552a848eSStefano Babic 	if ((p->type == CCM_CORE_CHANNEL) ||
506*552a848eSStefano Babic 	    (p->type == CCM_DRAM_PHYM_CHANNEL) ||
507*552a848eSStefano Babic 	    (p->type == CCM_DRAM_CHANNEL)) {
508*552a848eSStefano Babic 		*pre_div = 0;
509*552a848eSStefano Babic 		return 0;
510*552a848eSStefano Babic 	}
511*552a848eSStefano Babic 
512*552a848eSStefano Babic 	val = __raw_readl(&imx_ccm->root[clock_id].target_root);
513*552a848eSStefano Babic 	val &= CLK_ROOT_PRE_DIV_MASK;
514*552a848eSStefano Babic 	val >>= CLK_ROOT_PRE_DIV_SHIFT;
515*552a848eSStefano Babic 
516*552a848eSStefano Babic 	*pre_div = val;
517*552a848eSStefano Babic 
518*552a848eSStefano Babic 	return 0;
519*552a848eSStefano Babic }
520*552a848eSStefano Babic 
clock_set_postdiv(enum clk_root_index clock_id,enum root_post_div div)521*552a848eSStefano Babic int clock_set_postdiv(enum clk_root_index clock_id, enum root_post_div div)
522*552a848eSStefano Babic {
523*552a848eSStefano Babic 	u32 reg;
524*552a848eSStefano Babic 
525*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
526*552a848eSStefano Babic 		return -EINVAL;
527*552a848eSStefano Babic 
528*552a848eSStefano Babic 	if (clock_id == DRAM_PHYM_CLK_ROOT) {
529*552a848eSStefano Babic 		if (div != CLK_ROOT_POST_DIV1) {
530*552a848eSStefano Babic 			printf("Error post div!\n");
531*552a848eSStefano Babic 			return -EINVAL;
532*552a848eSStefano Babic 		}
533*552a848eSStefano Babic 	}
534*552a848eSStefano Babic 
535*552a848eSStefano Babic 	/* Only 3 bit post div. */
536*552a848eSStefano Babic 	if ((clock_id == DRAM_CLK_ROOT) && (div > CLK_ROOT_POST_DIV7)) {
537*552a848eSStefano Babic 		printf("Error post div!\n");
538*552a848eSStefano Babic 		return -EINVAL;
539*552a848eSStefano Babic 	}
540*552a848eSStefano Babic 
541*552a848eSStefano Babic 	reg = __raw_readl(&imx_ccm->root[clock_id].target_root);
542*552a848eSStefano Babic 	reg &= ~CLK_ROOT_POST_DIV_MASK;
543*552a848eSStefano Babic 	reg |= div << CLK_ROOT_POST_DIV_SHIFT;
544*552a848eSStefano Babic 	__raw_writel(reg, &imx_ccm->root[clock_id].target_root);
545*552a848eSStefano Babic 
546*552a848eSStefano Babic 	return 0;
547*552a848eSStefano Babic }
548*552a848eSStefano Babic 
clock_get_postdiv(enum clk_root_index clock_id,enum root_post_div * div)549*552a848eSStefano Babic int clock_get_postdiv(enum clk_root_index clock_id, enum root_post_div *div)
550*552a848eSStefano Babic {
551*552a848eSStefano Babic 	u32 val;
552*552a848eSStefano Babic 
553*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
554*552a848eSStefano Babic 		return -EINVAL;
555*552a848eSStefano Babic 
556*552a848eSStefano Babic 	if (clock_id == DRAM_PHYM_CLK_ROOT) {
557*552a848eSStefano Babic 		*div = 0;
558*552a848eSStefano Babic 		return 0;
559*552a848eSStefano Babic 	}
560*552a848eSStefano Babic 
561*552a848eSStefano Babic 	val = __raw_readl(&imx_ccm->root[clock_id].target_root);
562*552a848eSStefano Babic 	if (clock_id == DRAM_CLK_ROOT)
563*552a848eSStefano Babic 		val &= DRAM_CLK_ROOT_POST_DIV_MASK;
564*552a848eSStefano Babic 	else
565*552a848eSStefano Babic 		val &= CLK_ROOT_POST_DIV_MASK;
566*552a848eSStefano Babic 	val >>= CLK_ROOT_POST_DIV_SHIFT;
567*552a848eSStefano Babic 
568*552a848eSStefano Babic 	*div = val;
569*552a848eSStefano Babic 
570*552a848eSStefano Babic 	return 0;
571*552a848eSStefano Babic }
572*552a848eSStefano Babic 
clock_set_autopostdiv(enum clk_root_index clock_id,enum root_auto_div div,int auto_en)573*552a848eSStefano Babic int clock_set_autopostdiv(enum clk_root_index clock_id, enum root_auto_div div,
574*552a848eSStefano Babic 			  int auto_en)
575*552a848eSStefano Babic {
576*552a848eSStefano Babic 	u32 val;
577*552a848eSStefano Babic 	int root_entry;
578*552a848eSStefano Babic 	struct clk_root_map *p;
579*552a848eSStefano Babic 
580*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
581*552a848eSStefano Babic 		return -EINVAL;
582*552a848eSStefano Babic 
583*552a848eSStefano Babic 	root_entry = select(clock_id);
584*552a848eSStefano Babic 	if (root_entry < 0)
585*552a848eSStefano Babic 		return -EINVAL;
586*552a848eSStefano Babic 
587*552a848eSStefano Babic 	p = &root_array[root_entry];
588*552a848eSStefano Babic 
589*552a848eSStefano Babic 	if ((p->type != CCM_BUS_CHANNEL) && (p->type != CCM_AHB_CHANNEL)) {
590*552a848eSStefano Babic 		printf("Auto postdiv not supported.!\n");
591*552a848eSStefano Babic 		return -EINVAL;
592*552a848eSStefano Babic 	}
593*552a848eSStefano Babic 
594*552a848eSStefano Babic 	/*
595*552a848eSStefano Babic 	 * Each time only one filed can be changed, no use target_root_set.
596*552a848eSStefano Babic 	 */
597*552a848eSStefano Babic 	val = __raw_readl(&imx_ccm->root[clock_id].target_root);
598*552a848eSStefano Babic 	val &= ~CLK_ROOT_AUTO_DIV_MASK;
599*552a848eSStefano Babic 	val |= (div << CLK_ROOT_AUTO_DIV_SHIFT);
600*552a848eSStefano Babic 
601*552a848eSStefano Babic 	if (auto_en)
602*552a848eSStefano Babic 		val |= CLK_ROOT_AUTO_EN;
603*552a848eSStefano Babic 	else
604*552a848eSStefano Babic 		val &= ~CLK_ROOT_AUTO_EN;
605*552a848eSStefano Babic 
606*552a848eSStefano Babic 	__raw_writel(val, &imx_ccm->root[clock_id].target_root);
607*552a848eSStefano Babic 
608*552a848eSStefano Babic 	return 0;
609*552a848eSStefano Babic }
610*552a848eSStefano Babic 
clock_get_autopostdiv(enum clk_root_index clock_id,enum root_auto_div * div,int * auto_en)611*552a848eSStefano Babic int clock_get_autopostdiv(enum clk_root_index clock_id, enum root_auto_div *div,
612*552a848eSStefano Babic 			  int *auto_en)
613*552a848eSStefano Babic {
614*552a848eSStefano Babic 	u32 val;
615*552a848eSStefano Babic 	int root_entry;
616*552a848eSStefano Babic 	struct clk_root_map *p;
617*552a848eSStefano Babic 
618*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
619*552a848eSStefano Babic 		return -EINVAL;
620*552a848eSStefano Babic 
621*552a848eSStefano Babic 	root_entry = select(clock_id);
622*552a848eSStefano Babic 	if (root_entry < 0)
623*552a848eSStefano Babic 		return -EINVAL;
624*552a848eSStefano Babic 
625*552a848eSStefano Babic 	p = &root_array[root_entry];
626*552a848eSStefano Babic 
627*552a848eSStefano Babic 	/*
628*552a848eSStefano Babic 	 * Only bus/ahb channel supports auto div.
629*552a848eSStefano Babic 	 * If unsupported, just set auto_en and div with 0.
630*552a848eSStefano Babic 	 */
631*552a848eSStefano Babic 	if ((p->type != CCM_BUS_CHANNEL) && (p->type != CCM_AHB_CHANNEL)) {
632*552a848eSStefano Babic 		*auto_en = 0;
633*552a848eSStefano Babic 		*div = 0;
634*552a848eSStefano Babic 		return 0;
635*552a848eSStefano Babic 	}
636*552a848eSStefano Babic 
637*552a848eSStefano Babic 	val = __raw_readl(&imx_ccm->root[clock_id].target_root);
638*552a848eSStefano Babic 	if ((val & CLK_ROOT_AUTO_EN_MASK) == 0)
639*552a848eSStefano Babic 		*auto_en = 0;
640*552a848eSStefano Babic 	else
641*552a848eSStefano Babic 		*auto_en = 1;
642*552a848eSStefano Babic 
643*552a848eSStefano Babic 	val &= CLK_ROOT_AUTO_DIV_MASK;
644*552a848eSStefano Babic 	val >>= CLK_ROOT_AUTO_DIV_SHIFT;
645*552a848eSStefano Babic 
646*552a848eSStefano Babic 	*div = val;
647*552a848eSStefano Babic 
648*552a848eSStefano Babic 	return 0;
649*552a848eSStefano Babic }
650*552a848eSStefano Babic 
clock_get_target_val(enum clk_root_index clock_id,u32 * val)651*552a848eSStefano Babic int clock_get_target_val(enum clk_root_index clock_id, u32 *val)
652*552a848eSStefano Babic {
653*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
654*552a848eSStefano Babic 		return -EINVAL;
655*552a848eSStefano Babic 
656*552a848eSStefano Babic 	*val = __raw_readl(&imx_ccm->root[clock_id].target_root);
657*552a848eSStefano Babic 
658*552a848eSStefano Babic 	return 0;
659*552a848eSStefano Babic }
660*552a848eSStefano Babic 
clock_set_target_val(enum clk_root_index clock_id,u32 val)661*552a848eSStefano Babic int clock_set_target_val(enum clk_root_index clock_id, u32 val)
662*552a848eSStefano Babic {
663*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
664*552a848eSStefano Babic 		return -EINVAL;
665*552a848eSStefano Babic 
666*552a848eSStefano Babic 	__raw_writel(val, &imx_ccm->root[clock_id].target_root);
667*552a848eSStefano Babic 
668*552a848eSStefano Babic 	return 0;
669*552a848eSStefano Babic }
670*552a848eSStefano Babic 
671*552a848eSStefano Babic /* Auto_div and auto_en is ignored, they are rarely used. */
clock_root_cfg(enum clk_root_index clock_id,enum root_pre_div pre_div,enum root_post_div post_div,enum clk_root_src clock_src)672*552a848eSStefano Babic int clock_root_cfg(enum clk_root_index clock_id, enum root_pre_div pre_div,
673*552a848eSStefano Babic 		   enum root_post_div post_div, enum clk_root_src clock_src)
674*552a848eSStefano Babic {
675*552a848eSStefano Babic 	u32 val;
676*552a848eSStefano Babic 	int root_entry, src_entry;
677*552a848eSStefano Babic 	struct clk_root_map *p;
678*552a848eSStefano Babic 
679*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
680*552a848eSStefano Babic 		return -EINVAL;
681*552a848eSStefano Babic 
682*552a848eSStefano Babic 	root_entry = select(clock_id);
683*552a848eSStefano Babic 	if (root_entry < 0)
684*552a848eSStefano Babic 		return -EINVAL;
685*552a848eSStefano Babic 
686*552a848eSStefano Babic 	p = &root_array[root_entry];
687*552a848eSStefano Babic 
688*552a848eSStefano Babic 	if ((p->type == CCM_CORE_CHANNEL) ||
689*552a848eSStefano Babic 	    (p->type == CCM_DRAM_PHYM_CHANNEL) ||
690*552a848eSStefano Babic 	    (p->type == CCM_DRAM_CHANNEL)) {
691*552a848eSStefano Babic 		if (pre_div != CLK_ROOT_PRE_DIV1) {
692*552a848eSStefano Babic 			printf("Error pre div!\n");
693*552a848eSStefano Babic 			return -EINVAL;
694*552a848eSStefano Babic 		}
695*552a848eSStefano Babic 	}
696*552a848eSStefano Babic 
697*552a848eSStefano Babic 	/* Only 3 bit post div. */
698*552a848eSStefano Babic 	if (p->type == CCM_DRAM_CHANNEL) {
699*552a848eSStefano Babic 		if (post_div > CLK_ROOT_POST_DIV7) {
700*552a848eSStefano Babic 			printf("Error post div!\n");
701*552a848eSStefano Babic 			return -EINVAL;
702*552a848eSStefano Babic 		}
703*552a848eSStefano Babic 	}
704*552a848eSStefano Babic 
705*552a848eSStefano Babic 	if (p->type == CCM_DRAM_PHYM_CHANNEL) {
706*552a848eSStefano Babic 		if (post_div != CLK_ROOT_POST_DIV1) {
707*552a848eSStefano Babic 			printf("Error post div!\n");
708*552a848eSStefano Babic 			return -EINVAL;
709*552a848eSStefano Babic 		}
710*552a848eSStefano Babic 	}
711*552a848eSStefano Babic 
712*552a848eSStefano Babic 	src_entry = src_supported(root_entry, clock_src);
713*552a848eSStefano Babic 	if (src_entry < 0)
714*552a848eSStefano Babic 		return -EINVAL;
715*552a848eSStefano Babic 
716*552a848eSStefano Babic 	val = CLK_ROOT_ON | pre_div << CLK_ROOT_PRE_DIV_SHIFT |
717*552a848eSStefano Babic 	      post_div << CLK_ROOT_POST_DIV_SHIFT |
718*552a848eSStefano Babic 	      src_entry << CLK_ROOT_MUX_SHIFT;
719*552a848eSStefano Babic 
720*552a848eSStefano Babic 	__raw_writel(val, &imx_ccm->root[clock_id].target_root);
721*552a848eSStefano Babic 
722*552a848eSStefano Babic 	return 0;
723*552a848eSStefano Babic }
724*552a848eSStefano Babic 
clock_root_enabled(enum clk_root_index clock_id)725*552a848eSStefano Babic int clock_root_enabled(enum clk_root_index clock_id)
726*552a848eSStefano Babic {
727*552a848eSStefano Babic 	u32 val;
728*552a848eSStefano Babic 
729*552a848eSStefano Babic 	if (clock_id >= CLK_ROOT_MAX)
730*552a848eSStefano Babic 		return -EINVAL;
731*552a848eSStefano Babic 
732*552a848eSStefano Babic 	/*
733*552a848eSStefano Babic 	 * No enable bit for DRAM controller and PHY. Just return enabled.
734*552a848eSStefano Babic 	 */
735*552a848eSStefano Babic 	if ((clock_id == DRAM_PHYM_CLK_ROOT) || (clock_id == DRAM_CLK_ROOT))
736*552a848eSStefano Babic 		return 1;
737*552a848eSStefano Babic 
738*552a848eSStefano Babic 	val = __raw_readl(&imx_ccm->root[clock_id].target_root);
739*552a848eSStefano Babic 
740*552a848eSStefano Babic 	return (val & CLK_ROOT_ENABLE_MASK) ? 1 : 0;
741*552a848eSStefano Babic }
742*552a848eSStefano Babic 
743*552a848eSStefano Babic /* CCGR gate operation */
clock_enable(enum clk_ccgr_index index,bool enable)744*552a848eSStefano Babic int clock_enable(enum clk_ccgr_index index, bool enable)
745*552a848eSStefano Babic {
746*552a848eSStefano Babic 	if (index >= CCGR_MAX)
747*552a848eSStefano Babic 		return -EINVAL;
748*552a848eSStefano Babic 
749*552a848eSStefano Babic 	if (enable)
750*552a848eSStefano Babic 		__raw_writel(CCM_CLK_ON_MSK,
751*552a848eSStefano Babic 			     &imx_ccm->ccgr_array[index].ccgr_set);
752*552a848eSStefano Babic 	else
753*552a848eSStefano Babic 		__raw_writel(CCM_CLK_ON_MSK,
754*552a848eSStefano Babic 			     &imx_ccm->ccgr_array[index].ccgr_clr);
755*552a848eSStefano Babic 
756*552a848eSStefano Babic 	return 0;
757*552a848eSStefano Babic }
758