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