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