blob: 1aa7c2c86e26e395fee3e7b03b16bfd3a17bdd8b [file] [log] [blame]
Angus Ainslie7ab22a82022-03-29 07:02:39 -07001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2019 NXP
4 * Copyright 2022 Purism
5 * Peng Fan <peng.fan@nxp.com>
6 */
7
8#include <common.h>
9#include <clk.h>
10#include <clk-uclass.h>
11#include <dm.h>
12#include <log.h>
13#include <asm/arch/clock.h>
14#include <asm/arch/imx-regs.h>
15#include <dt-bindings/clock/imx8mq-clock.h>
16
17#include "clk.h"
18
19#define PLL_1416X_RATE(_rate, _m, _p, _s) \
20 { \
21 .rate = (_rate), \
22 .mdiv = (_m), \
23 .pdiv = (_p), \
24 .sdiv = (_s), \
25 }
26
27#define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
28 { \
29 .rate = (_rate), \
30 .mdiv = (_m), \
31 .pdiv = (_p), \
32 .sdiv = (_s), \
33 .kdiv = (_k), \
34 }
35
36static const struct imx_pll14xx_rate_table imx8mq_pll1416x_tbl[] = {
37 PLL_1416X_RATE(1800000000U, 225, 3, 0),
38 PLL_1416X_RATE(1600000000U, 200, 3, 0),
39 PLL_1416X_RATE(1200000000U, 300, 3, 1),
40 PLL_1416X_RATE(1000000000U, 250, 3, 1),
41 PLL_1416X_RATE(800000000U, 200, 3, 1),
42 PLL_1416X_RATE(750000000U, 250, 2, 2),
43 PLL_1416X_RATE(700000000U, 350, 3, 2),
44 PLL_1416X_RATE(600000000U, 300, 3, 2),
45};
46
47const struct imx_pll14xx_rate_table imx8mq_pll1443x_tbl[] = {
48 PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
49 PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
50 PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
51 PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
52};
53
54static struct imx_pll14xx_clk imx8mq_1416x_pll __initdata = {
55 .type = PLL_1416X,
56 .rate_table = imx8mq_pll1416x_tbl,
57 .rate_count = ARRAY_SIZE(imx8mq_pll1416x_tbl),
58};
59
60static struct imx_pll14xx_clk imx8mq_1443x_pll __initdata = {
61 .type = PLL_1443X,
62 .rate_table = imx8mq_pll1443x_tbl,
63 .rate_count = ARRAY_SIZE(imx8mq_pll1443x_tbl),
64};
65
66static const char *const pll_ref_sels[] = { "clock-osc-25m", "clock-osc-27m", "clock-phy-27m", "dummy", };
67static const char *const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
68static const char *const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
69static const char *const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
70static const char *const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
71static const char *const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
72static const char *const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
73
74static const char *const imx8mq_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
75static const char *const imx8mq_a53_sels[] = {"clock-osc-25m", "arm_pll_out", "sys_pll2_500m",
76 "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
77 "audio_pll1_out", "sys_pll3_out", };
78
79static const char *const imx8mq_ahb_sels[] = {"clock-osc-25m", "sys_pll1_133m", "sys_pll1_800m",
80 "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
81 "audio_pll1_out", "video_pll1_out", };
82
83static const char *const imx8mq_dram_alt_sels[] = {"osc_25m", "sys_pll1_800m", "sys_pll1_100m",
84 "sys_pll2_500m", "sys_pll2_250m",
85 "sys_pll1_400m", "audio_pll1_out", "sys_pll1_266m", } ;
86
87static const char * const imx8mq_dram_apb_sels[] = {"osc_25m", "sys_pll2_200m", "sys_pll1_40m",
88 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
89 "sys_pll2_250m", "audio_pll2_out", };
90
91static const char *const imx8mq_enet_axi_sels[] = {"clock-osc-25m", "sys_pll1_266m", "sys_pll1_800m",
92 "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
93 "video_pll1_out", "sys_pll3_out", };
94
95static const char *const imx8mq_enet_ref_sels[] = {"clock-osc-25m", "sys_pll2_125m", "sys_pll2_50m",
96 "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
97 "video_pll1_out", "clk_ext4", };
98
99static const char *const imx8mq_enet_timer_sels[] = {"clock-osc-25m", "sys_pll2_100m", "audio_pll1_out",
100 "clk_ext1", "clk_ext2", "clk_ext3", "clk_ext4",
101 "video_pll1_out", };
102
103static const char *const imx8mq_enet_phy_sels[] = {"clock-osc-25m", "sys_pll2_50m", "sys_pll2_125m",
104 "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out",
105 "audio_pll2_out", };
106
107static const char *const imx8mq_nand_usdhc_sels[] = {"clock-osc-25m", "sys_pll1_266m", "sys_pll1_800m",
108 "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
109 "sys_pll2_250m", "audio_pll1_out", };
110
111static const char *const imx8mq_usb_bus_sels[] = {"clock-osc-25m", "sys_pll2_500m", "sys_pll1_800m",
112 "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
113 "clk_ext4", "audio_pll2_out", };
114
115static const char *const imx8mq_usdhc1_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll1_800m",
116 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
117 "audio_pll2_out", "sys_pll1_100m", };
118
119static const char *const imx8mq_usdhc2_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll1_800m",
120 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
121 "audio_pll2_out", "sys_pll1_100m", };
122
123static const char *const imx8mq_i2c1_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
124 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
125 "audio_pll2_out", "sys_pll1_133m", };
126
127static const char *const imx8mq_i2c2_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
128 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
129 "audio_pll2_out", "sys_pll1_133m", };
130
131static const char *const imx8mq_i2c3_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
132 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
133 "audio_pll2_out", "sys_pll1_133m", };
134
135static const char *const imx8mq_i2c4_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
136 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
137 "audio_pll2_out", "sys_pll1_133m", };
138
139static const char *const imx8mq_uart1_sels[] = {"clock-osc-25m", "sys_pll1_80m", "sys_pll2_200m",
140 "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
141 "clk_ext4", "audio_pll2_out", };
142
143static const char *const imx8mq_uart2_sels[] = {"clock-osc-25m", "sys_pll1_80m", "sys_pll2_200m",
144 "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
145 "clk_ext3", "audio_pll2_out", };
146
147static const char *const imx8mq_uart3_sels[] = {"clock-osc-25m", "sys_pll1_80m", "sys_pll2_200m",
148 "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
149 "clk_ext4", "audio_pll2_out", };
150
151static const char *const imx8mq_uart4_sels[] = {"clock-osc-25m", "sys_pll1_80m", "sys_pll2_200m",
152 "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
153 "clk_ext3", "audio_pll2_out", };
154
155static const char *const imx8mq_wdog_sels[] = {"clock-osc-25m", "sys_pll1_133m", "sys_pll1_160m",
156 "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
157 "sys_pll1_80m", "sys_pll2_166m", };
158
159static const char *const imx8mq_qspi_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll2_333m",
160 "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
161 "sys_pll3_out", "sys_pll1_100m", };
162
163static const char *const imx8mq_usb_core_sels[] = {"clock-osc-25m", "sys_pll1_100m", "sys_pll1_40m",
164 "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
165 "clk_ext3", "audio_pll2_out", };
166
167static const char *const imx8mq_usb_phy_sels[] = {"clock-osc-25m", "sys_pll1_100m", "sys_pll1_40m",
168 "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
169 "clk_ext3", "audio_pll2_out", };
170
171static const char *const imx8mq_ecspi1_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
172 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
173 "sys_pll2_250m", "audio_pll2_out", };
174
175static const char *const imx8mq_ecspi2_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
176 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
177 "sys_pll2_250m", "audio_pll2_out", };
178
179static const char *const imx8mq_ecspi3_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
180 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
181 "sys_pll2_250m", "audio_pll2_out", };
182
183static const char *const imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
184
185static const char *const pllout_monitor_sels[] = {"clock-osc-25m", "clock-osc-27m", "clock-phy-27m",
186 "dummy", "clock-ckil", "audio_pll1_out_monitor",
187 "audio_pll2_out_monitor", "gpu_pll_out_monitor",
188 "vpu_pll_out_monitor", "video_pll1_out_monitor",
189 "arm_pll_out_monitor", "sys_pll1_out_monitor",
190 "sys_pll2_out_monitor", "sys_pll3_out_monitor",
191 "video_pll2_out_monitor", "dram_pll_out_monitor", };
192
193static int imx8mq_clk_probe(struct udevice *dev)
194{
195 void __iomem *base;
196
197 base = (void *)ANATOP_BASE_ADDR;
198
199 clk_dm(IMX8MQ_CLK_32K, clk_register_fixed_rate(NULL, "ckil", 32768));
200 clk_dm(IMX8MQ_CLK_27M, clk_register_fixed_rate(NULL, "clock-osc-27m", 27000000));
201
202 clk_dm(IMX8MQ_DRAM_PLL1_REF_SEL,
203 imx_clk_mux("dram_pll_ref_sel", base + 0x60, 0, 2,
204 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
205 clk_dm(IMX8MQ_ARM_PLL_REF_SEL,
206 imx_clk_mux("arm_pll_ref_sel", base + 0x28, 0, 2,
207 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
208 clk_dm(IMX8MQ_GPU_PLL_REF_SEL,
209 imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 0, 2,
210 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
211 clk_dm(IMX8MQ_VPU_PLL_REF_SEL,
212 imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 0, 2,
213 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
214 clk_dm(IMX8MQ_SYS3_PLL1_REF_SEL,
215 imx_clk_mux("sys3_pll_ref_sel", base + 0x48, 0, 2,
216 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
217 clk_dm(IMX8MQ_AUDIO_PLL1_REF_SEL,
218 imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2,
219 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
220 clk_dm(IMX8MQ_AUDIO_PLL2_REF_SEL,
221 imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 0, 2,
222 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
223 clk_dm(IMX8MQ_VIDEO_PLL1_REF_SEL,
224 imx_clk_mux("video_pll1_ref_sel", base + 0x10, 0, 2,
225 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
226 clk_dm(IMX8MQ_VIDEO2_PLL1_REF_SEL,
227 imx_clk_mux("video_pll2_ref_sel", base + 0x54, 0, 2,
228 pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
229
230 clk_dm(IMX8MQ_ARM_PLL,
231 imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
232 base + 0x28, &imx8mq_1416x_pll));
233 clk_dm(IMX8MQ_GPU_PLL,
234 imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel",
235 base + 0x18, &imx8mq_1416x_pll));
236 clk_dm(IMX8MQ_VPU_PLL,
237 imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel",
238 base + 0x20, &imx8mq_1416x_pll));
239
240 clk_dm(IMX8MQ_SYS1_PLL1,
241 clk_register_fixed_rate(NULL, "sys1_pll", 800000000));
242 clk_dm(IMX8MQ_SYS2_PLL1,
243 clk_register_fixed_rate(NULL, "sys2_pll", 1000000000));
244 clk_dm(IMX8MQ_SYS2_PLL1,
245 clk_register_fixed_rate(NULL, "sys3_pll", 1000000000));
246 clk_dm(IMX8MQ_AUDIO_PLL1,
247 imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel",
248 base + 0x0, &imx8mq_1443x_pll));
249 clk_dm(IMX8MQ_AUDIO_PLL2,
250 imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel",
251 base + 0x8, &imx8mq_1443x_pll));
252 clk_dm(IMX8MQ_VIDEO_PLL1,
253 imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel",
254 base + 0x10, &imx8mq_1443x_pll));
255
256 /* PLL bypass out */
257 clk_dm(IMX8MQ_ARM_PLL_BYPASS,
258 imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 4, 1,
259 arm_pll_bypass_sels,
260 ARRAY_SIZE(arm_pll_bypass_sels),
261 CLK_SET_RATE_PARENT));
262 clk_dm(IMX8MQ_GPU_PLL_BYPASS,
263 imx_clk_mux_flags("gpu_pll_bypass", base + 0x18, 4, 1,
264 gpu_pll_bypass_sels,
265 ARRAY_SIZE(gpu_pll_bypass_sels),
266 CLK_SET_RATE_PARENT));
267 clk_dm(IMX8MQ_VPU_PLL_BYPASS,
268 imx_clk_mux_flags("vpu_pll_bypass", base + 0x20, 4, 1,
269 vpu_pll_bypass_sels,
270 ARRAY_SIZE(vpu_pll_bypass_sels),
271 CLK_SET_RATE_PARENT));
272 clk_dm(IMX8MQ_AUDIO_PLL1_BYPASS,
273 imx_clk_mux_flags("audio_pll1_bypass", base + 0x0, 4, 1,
274 audio_pll1_bypass_sels,
275 ARRAY_SIZE(audio_pll1_bypass_sels),
276 CLK_SET_RATE_PARENT));
277 clk_dm(IMX8MQ_AUDIO_PLL2_BYPASS,
278 imx_clk_mux_flags("audio_pll2_bypass", base + 0x8, 4, 1,
279 audio_pll2_bypass_sels,
280 ARRAY_SIZE(audio_pll2_bypass_sels),
281 CLK_SET_RATE_PARENT));
282 clk_dm(IMX8MQ_VIDEO_PLL1_BYPASS,
283 imx_clk_mux_flags("video_pll1_bypass", base + 0x10, 4, 1,
284 video_pll1_bypass_sels,
285 ARRAY_SIZE(video_pll1_bypass_sels),
286 CLK_SET_RATE_PARENT));
287
288 /* PLL out gate */
289 clk_dm(IMX8MQ_DRAM_PLL_OUT,
290 imx_clk_gate("dram_pll_out", "dram_pll_ref_sel",
291 base + 0x60, 13));
292 clk_dm(IMX8MQ_ARM_PLL_OUT,
293 imx_clk_gate("arm_pll_out", "arm_pll_bypass",
294 base + 0x28, 11));
295 clk_dm(IMX8MQ_GPU_PLL_OUT,
296 imx_clk_gate("gpu_pll_out", "gpu_pll_bypass",
297 base + 0x18, 11));
298 clk_dm(IMX8MQ_VPU_PLL_OUT,
299 imx_clk_gate("vpu_pll_out", "vpu_pll_bypass",
300 base + 0x20, 11));
301 clk_dm(IMX8MQ_AUDIO_PLL1_OUT,
302 imx_clk_gate("audio_pll1_out", "audio_pll1_bypass",
303 base + 0x0, 11));
304 clk_dm(IMX8MQ_AUDIO_PLL2_OUT,
305 imx_clk_gate("audio_pll2_out", "audio_pll2_bypass",
306 base + 0x8, 11));
307 clk_dm(IMX8MQ_VIDEO_PLL1_OUT,
308 imx_clk_gate("video_pll1_out", "video_pll1_bypass",
309 base + 0x10, 11));
310
311 clk_dm(IMX8MQ_SYS1_PLL_OUT,
312 imx_clk_gate("sys_pll1_out", "sys1_pll",
313 base + 0x30, 11));
314 clk_dm(IMX8MQ_SYS2_PLL_OUT,
315 imx_clk_gate("sys_pll2_out", "sys2_pll",
316 base + 0x3c, 11));
317 clk_dm(IMX8MQ_SYS3_PLL_OUT,
318 imx_clk_gate("sys_pll3_out", "sys3_pll",
319 base + 0x48, 11));
320 clk_dm(IMX8MQ_VIDEO2_PLL_OUT,
321 imx_clk_gate("video_pll2_out", "video_pll2_ref_sel",
322 base + 0x54, 11));
323
324 /* SYS PLL fixed output */
325 clk_dm(IMX8MQ_SYS1_PLL_40M,
326 imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20));
327 clk_dm(IMX8MQ_SYS1_PLL_80M,
328 imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10));
329 clk_dm(IMX8MQ_SYS1_PLL_100M,
330 imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8));
331 clk_dm(IMX8MQ_SYS1_PLL_133M,
332 imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6));
333 clk_dm(IMX8MQ_SYS1_PLL_160M,
334 imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5));
335 clk_dm(IMX8MQ_SYS1_PLL_200M,
336 imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4));
337 clk_dm(IMX8MQ_SYS1_PLL_266M,
338 imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3));
339 clk_dm(IMX8MQ_SYS1_PLL_400M,
340 imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2));
341 clk_dm(IMX8MQ_SYS1_PLL_800M,
342 imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1));
343
344 clk_dm(IMX8MQ_SYS2_PLL_50M,
345 imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20));
346 clk_dm(IMX8MQ_SYS2_PLL_100M,
347 imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10));
348 clk_dm(IMX8MQ_SYS2_PLL_125M,
349 imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8));
350 clk_dm(IMX8MQ_SYS2_PLL_166M,
351 imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6));
352 clk_dm(IMX8MQ_SYS2_PLL_200M,
353 imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5));
354 clk_dm(IMX8MQ_SYS2_PLL_250M,
355 imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4));
356 clk_dm(IMX8MQ_SYS2_PLL_333M,
357 imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3));
358 clk_dm(IMX8MQ_SYS2_PLL_500M,
359 imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2));
360 clk_dm(IMX8MQ_SYS2_PLL_1000M,
361 imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1));
362
363 clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL1_DIV,
364 imx_clk_divider("audio_pll1_out_monitor", "audio_pll1_bypass", base + 0x78, 0, 3));
365 clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL2_DIV,
366 imx_clk_divider("audio_pll2_out_monitor", "audio_pll2_bypass", base + 0x78, 4, 3));
367 clk_dm(IMX8MQ_CLK_MON_VIDEO_PLL1_DIV,
368 imx_clk_divider("video_pll1_out_monitor", "video_pll1_bypass", base + 0x78, 8, 3));
369 clk_dm(IMX8MQ_CLK_MON_GPU_PLL_DIV,
370 imx_clk_divider("gpu_pll_out_monitor", "gpu_pll_bypass", base + 0x78, 12, 3));
371 clk_dm(IMX8MQ_CLK_MON_VPU_PLL_DIV,
372 imx_clk_divider("vpu_pll_out_monitor", "vpu_pll_bypass", base + 0x78, 16, 3));
373 clk_dm(IMX8MQ_CLK_MON_ARM_PLL_DIV,
374 imx_clk_divider("arm_pll_out_monitor", "arm_pll_bypass", base + 0x78, 20, 3));
375 clk_dm(IMX8MQ_CLK_MON_SYS_PLL1_DIV,
376 imx_clk_divider("sys_pll1_out_monitor", "sys_pll1_out", base + 0x7c, 0, 3));
377 clk_dm(IMX8MQ_CLK_MON_SYS_PLL2_DIV,
378 imx_clk_divider("sys_pll2_out_monitor", "sys_pll2_out", base + 0x7c, 4, 3));
379 clk_dm(IMX8MQ_CLK_MON_SYS_PLL3_DIV,
380 imx_clk_divider("sys_pll3_out_monitor", "sys_pll3_out", base + 0x7c, 8, 3));
381 clk_dm(IMX8MQ_CLK_MON_DRAM_PLL_DIV,
382 imx_clk_divider("dram_pll_out_monitor", "dram_pll_out", base + 0x7c, 12, 3));
383 clk_dm(IMX8MQ_CLK_MON_VIDEO_PLL2_DIV,
384 imx_clk_divider("video_pll2_out_monitor", "video_pll2_out", base + 0x7c, 16, 3));
385 clk_dm(IMX8MQ_CLK_MON_SEL,
386 imx_clk_mux_flags("pllout_monitor_sel", base + 0x74, 0, 4,
387 pllout_monitor_sels,
388 ARRAY_SIZE(pllout_monitor_sels),
389 CLK_SET_RATE_PARENT));
390 clk_dm(IMX8MQ_CLK_MON_CLK2_OUT,
391 imx_clk_gate4("pllout_monitor_clk2", "pllout_monitor_sel", base + 0x74, 4));
392
393 base = dev_read_addr_ptr(dev);
394 if (!base) {
395 printf("%s : base failed\n", __func__);
396 return -EINVAL;
397 }
398
399 clk_dm(IMX8MQ_CLK_A53_SRC,
400 imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3,
401 imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)));
402 clk_dm(IMX8MQ_CLK_A53_CG,
403 imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28));
404 clk_dm(IMX8MQ_CLK_A53_DIV,
405 imx_clk_divider2("arm_a53_div", "arm_a53_cg",
406 base + 0x8000, 0, 3));
407 clk_dm(IMX8MQ_CLK_A53_CORE,
408 imx_clk_mux2("arm_a53_src", base + 0x9880, 24, 1,
409 imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels)));
410
411 clk_dm(IMX8MQ_CLK_AHB,
412 imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels,
413 base + 0x9000));
414 clk_dm(IMX8MQ_CLK_IPG_ROOT,
415 imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1));
416
417 clk_dm(IMX8MQ_CLK_ENET_AXI,
418 imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels,
419 base + 0x8880));
420 clk_dm(IMX8MQ_CLK_NAND_USDHC_BUS,
421 imx8m_clk_composite_critical("nand_usdhc_bus",
422 imx8mq_nand_usdhc_sels,
423 base + 0x8900));
424 clk_dm(IMX8MQ_CLK_USB_BUS,
425 imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80));
426
427 /* DRAM */
428 clk_dm(IMX8MQ_CLK_DRAM_CORE,
429 imx_clk_mux2("dram_core_clk", base + 0x9800, 24, 1,
430 imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels)));
431 clk_dm(IMX8MQ_CLK_DRAM_ALT,
432 imx8m_clk_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000));
433 clk_dm(IMX8MQ_CLK_DRAM_APB,
434 imx8m_clk_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080));
435
436 /* IP */
437 clk_dm(IMX8MQ_CLK_USDHC1,
438 imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels,
439 base + 0xac00));
440 clk_dm(IMX8MQ_CLK_USDHC2,
441 imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels,
442 base + 0xac80));
443 clk_dm(IMX8MQ_CLK_I2C1,
444 imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00));
445 clk_dm(IMX8MQ_CLK_I2C2,
446 imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80));
447 clk_dm(IMX8MQ_CLK_I2C3,
448 imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00));
449 clk_dm(IMX8MQ_CLK_I2C4,
450 imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80));
451 clk_dm(IMX8MQ_CLK_WDOG,
452 imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900));
453 clk_dm(IMX8MQ_CLK_UART1,
454 imx8m_clk_composite("uart1", imx8mq_uart1_sels, base + 0xaf00));
455 clk_dm(IMX8MQ_CLK_UART2,
456 imx8m_clk_composite("uart2", imx8mq_uart2_sels, base + 0xaf80));
457 clk_dm(IMX8MQ_CLK_UART3,
458 imx8m_clk_composite("uart3", imx8mq_uart3_sels, base + 0xb000));
459 clk_dm(IMX8MQ_CLK_UART4,
460 imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080));
461 clk_dm(IMX8MQ_CLK_QSPI,
462 imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80));
463 clk_dm(IMX8MQ_CLK_USB_CORE_REF,
464 imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100));
465 clk_dm(IMX8MQ_CLK_USB_PHY_REF,
466 imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180));
467 clk_dm(IMX8MQ_CLK_ECSPI1,
468 imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280));
469 clk_dm(IMX8MQ_CLK_ECSPI2,
470 imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300));
471 clk_dm(IMX8MQ_CLK_ECSPI3,
472 imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180));
473
474 clk_dm(IMX8MQ_CLK_ECSPI1_ROOT,
475 imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0));
476 clk_dm(IMX8MQ_CLK_ECSPI2_ROOT,
477 imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0));
478 clk_dm(IMX8MQ_CLK_ECSPI3_ROOT,
479 imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0));
480 clk_dm(IMX8MQ_CLK_I2C1_ROOT,
481 imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0));
482 clk_dm(IMX8MQ_CLK_I2C2_ROOT,
483 imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0));
484 clk_dm(IMX8MQ_CLK_I2C3_ROOT,
485 imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0));
486 clk_dm(IMX8MQ_CLK_I2C4_ROOT,
487 imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0));
488 clk_dm(IMX8MQ_CLK_UART1_ROOT,
489 imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0));
490 clk_dm(IMX8MQ_CLK_UART2_ROOT,
491 imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0));
492 clk_dm(IMX8MQ_CLK_UART3_ROOT,
493 imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0));
494 clk_dm(IMX8MQ_CLK_UART4_ROOT,
495 imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0));
496 clk_dm(IMX8MQ_CLK_OCOTP_ROOT,
497 imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0));
498 clk_dm(IMX8MQ_CLK_USDHC1_ROOT,
499 imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0));
500 clk_dm(IMX8MQ_CLK_USDHC2_ROOT,
501 imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0));
502 clk_dm(IMX8MQ_CLK_WDOG1_ROOT,
503 imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0));
504 clk_dm(IMX8MQ_CLK_WDOG2_ROOT,
505 imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0));
506 clk_dm(IMX8MQ_CLK_WDOG3_ROOT,
507 imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0));
508 clk_dm(IMX8MQ_CLK_QSPI_ROOT,
509 imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
510 clk_dm(IMX8MQ_CLK_USB1_CTRL_ROOT,
511 imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0));
512 clk_dm(IMX8MQ_CLK_USB2_CTRL_ROOT,
513 imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0));
514 clk_dm(IMX8MQ_CLK_USB1_PHY_ROOT,
515 imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0));
516 clk_dm(IMX8MQ_CLK_USB2_PHY_ROOT,
517 imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0));
518
519 clk_dm(IMX8MQ_CLK_ENET_REF,
520 imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels,
521 base + 0xa980));
522 clk_dm(IMX8MQ_CLK_ENET_TIMER,
523 imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels,
524 base + 0xaa00));
525 clk_dm(IMX8MQ_CLK_ENET_PHY_REF,
526 imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels,
527 base + 0xaa80));
528 clk_dm(IMX8MQ_CLK_ENET1_ROOT,
529 imx_clk_gate4("enet1_root_clk", "enet_axi",
530 base + 0x40a0, 0));
531
532 clk_dm(IMX8MQ_CLK_DRAM_ALT_ROOT,
533 imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4));
534
535 return 0;
536}
537
538static const struct udevice_id imx8mq_clk_ids[] = {
539 { .compatible = "fsl,imx8mq-ccm" },
540 { },
541};
542
543U_BOOT_DRIVER(imx8mq_clk) = {
544 .name = "clk_imx8mq",
545 .id = UCLASS_CLK,
546 .of_match = imx8mq_clk_ids,
547 .ops = &ccf_clk_ops,
548 .probe = imx8mq_clk_probe,
549 .flags = DM_FLAG_PRE_RELOC,
550};