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