1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | // |
3 | // Copyright (c) 2022 MediaTek Inc. |
4 | // Author: Chun-Jie Chen <chun-jie.chen@mediatek.com> |
5 | |
6 | #include <linux/clk-provider.h> |
7 | #include <linux/platform_device.h> |
8 | #include <dt-bindings/clock/mt8186-clk.h> |
9 | |
10 | #include "clk-mtk.h" |
11 | #include "clk-mux.h" |
12 | |
13 | static DEFINE_SPINLOCK(mt8186_clk_lock); |
14 | |
15 | static const struct mtk_fixed_clk top_fixed_clks[] = { |
16 | FIXED_CLK(CLK_TOP_ULPOSC1, "ulposc1" , NULL, 250000000), |
17 | FIXED_CLK(CLK_TOP_466M_FMEM, "hd_466m_fmem_ck" , NULL, 466000000), |
18 | FIXED_CLK(CLK_TOP_MPLL, "mpll" , NULL, 208000000), |
19 | }; |
20 | |
21 | static const struct mtk_fixed_factor top_divs[] = { |
22 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D2, "mainpll_d2" , "mainpll" , 1, 2, 0), |
23 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D2_D2, "mainpll_d2_d2" , "mainpll_d2" , 1, 2, 0), |
24 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D2_D4, "mainpll_d2_d4" , "mainpll_d2" , 1, 4, 0), |
25 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D2_D16, "mainpll_d2_d16" , "mainpll_d2" , 1, 16, 0), |
26 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D3, "mainpll_d3" , "mainpll" , 1, 3, 0), |
27 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D3_D2, "mainpll_d3_d2" , "mainpll_d3" , 1, 2, 0), |
28 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D3_D4, "mainpll_d3_d4" , "mainpll_d3" , 1, 4, 0), |
29 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D5, "mainpll_d5" , "mainpll" , 1, 5, 0), |
30 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D5_D2, "mainpll_d5_d2" , "mainpll_d5" , 1, 2, 0), |
31 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D5_D4, "mainpll_d5_d4" , "mainpll_d5" , 1, 4, 0), |
32 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D7, "mainpll_d7" , "mainpll" , 1, 7, 0), |
33 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D7_D2, "mainpll_d7_d2" , "mainpll_d7" , 1, 2, 0), |
34 | FACTOR_FLAGS(CLK_TOP_MAINPLL_D7_D4, "mainpll_d7_d4" , "mainpll_d7" , 1, 4, 0), |
35 | FACTOR_FLAGS(CLK_TOP_UNIVPLL, "univpll" , "univ2pll" , 1, 2, 0), |
36 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D2, "univpll_d2" , "univpll" , 1, 2, 0), |
37 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D2_D2, "univpll_d2_d2" , "univpll_d2" , 1, 2, 0), |
38 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D2_D4, "univpll_d2_d4" , "univpll_d2" , 1, 4, 0), |
39 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D3, "univpll_d3" , "univpll" , 1, 3, 0), |
40 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D3_D2, "univpll_d3_d2" , "univpll_d3" , 1, 2, 0), |
41 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D3_D4, "univpll_d3_d4" , "univpll_d3" , 1, 4, 0), |
42 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D3_D8, "univpll_d3_d8" , "univpll_d3" , 1, 8, 0), |
43 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D3_D32, "univpll_d3_d32" , "univpll_d3" , 1, 32, 0), |
44 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D5, "univpll_d5" , "univpll" , 1, 5, 0), |
45 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2" , "univpll_d5" , 1, 2, 0), |
46 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4" , "univpll_d5" , 1, 4, 0), |
47 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_D7, "univpll_d7" , "univpll" , 1, 7, 0), |
48 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_192M, "univpll_192m" , "univ2pll" , 1, 13, 0), |
49 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_192M_D4, "univpll_192m_d4" , "univpll_192m" , 1, 4, 0), |
50 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_192M_D8, "univpll_192m_d8" , "univpll_192m" , 1, 8, 0), |
51 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_192M_D16, "univpll_192m_d16" , "univpll_192m" , 1, 16, 0), |
52 | FACTOR_FLAGS(CLK_TOP_UNIVPLL_192M_D32, "univpll_192m_d32" , "univpll_192m" , 1, 32, 0), |
53 | FACTOR(CLK_TOP_APLL1_D2, "apll1_d2" , "apll1" , 1, 2), |
54 | FACTOR(CLK_TOP_APLL1_D4, "apll1_d4" , "apll1" , 1, 4), |
55 | FACTOR(CLK_TOP_APLL1_D8, "apll1_d8" , "apll1" , 1, 8), |
56 | FACTOR(CLK_TOP_APLL2_D2, "apll2_d2" , "apll2" , 1, 2), |
57 | FACTOR(CLK_TOP_APLL2_D4, "apll2_d4" , "apll2" , 1, 4), |
58 | FACTOR(CLK_TOP_APLL2_D8, "apll2_d8" , "apll2" , 1, 8), |
59 | FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2" , "mmpll" , 1, 2), |
60 | FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2" , "tvdpll" , 1, 2), |
61 | FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4" , "tvdpll" , 1, 4), |
62 | FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8" , "tvdpll" , 1, 8), |
63 | FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16" , "tvdpll" , 1, 16), |
64 | FACTOR(CLK_TOP_TVDPLL_D32, "tvdpll_d32" , "tvdpll" , 1, 32), |
65 | FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2" , "msdcpll" , 1, 2), |
66 | FACTOR(CLK_TOP_ULPOSC1_D2, "ulposc1_d2" , "ulposc1" , 1, 2), |
67 | FACTOR(CLK_TOP_ULPOSC1_D4, "ulposc1_d4" , "ulposc1" , 1, 4), |
68 | FACTOR(CLK_TOP_ULPOSC1_D8, "ulposc1_d8" , "ulposc1" , 1, 8), |
69 | FACTOR(CLK_TOP_ULPOSC1_D10, "ulposc1_d10" , "ulposc1" , 1, 10), |
70 | FACTOR(CLK_TOP_ULPOSC1_D16, "ulposc1_d16" , "ulposc1" , 1, 16), |
71 | FACTOR(CLK_TOP_ULPOSC1_D32, "ulposc1_d32" , "ulposc1" , 1, 32), |
72 | FACTOR(CLK_TOP_ADSPPLL_D2, "adsppll_d2" , "adsppll" , 1, 2), |
73 | FACTOR(CLK_TOP_ADSPPLL_D4, "adsppll_d4" , "adsppll" , 1, 4), |
74 | FACTOR(CLK_TOP_ADSPPLL_D8, "adsppll_d8" , "adsppll" , 1, 8), |
75 | FACTOR(CLK_TOP_NNAPLL_D2, "nnapll_d2" , "nnapll" , 1, 2), |
76 | FACTOR(CLK_TOP_NNAPLL_D4, "nnapll_d4" , "nnapll" , 1, 4), |
77 | FACTOR(CLK_TOP_NNAPLL_D8, "nnapll_d8" , "nnapll" , 1, 8), |
78 | FACTOR(CLK_TOP_NNA2PLL_D2, "nna2pll_d2" , "nna2pll" , 1, 2), |
79 | FACTOR(CLK_TOP_NNA2PLL_D4, "nna2pll_d4" , "nna2pll" , 1, 4), |
80 | FACTOR(CLK_TOP_NNA2PLL_D8, "nna2pll_d8" , "nna2pll" , 1, 8), |
81 | FACTOR(CLK_TOP_F_BIST2FPC, "f_bist2fpc_ck" , "univpll_d3_d2" , 1, 1), |
82 | }; |
83 | |
84 | static const char * const axi_parents[] = { |
85 | "clk26m" , |
86 | "mainpll_d7" , |
87 | "mainpll_d2_d4" , |
88 | "univpll_d7" |
89 | }; |
90 | |
91 | static const char * const scp_parents[] = { |
92 | "clk26m" , |
93 | "mainpll_d2_d4" , |
94 | "mainpll_d5" , |
95 | "mainpll_d2_d2" , |
96 | "mainpll_d3" , |
97 | "univpll_d3" |
98 | }; |
99 | |
100 | static const char * const mfg_parents[] = { |
101 | "clk26m" , |
102 | "mfgpll" , |
103 | "mainpll_d3" , |
104 | "mainpll_d5" |
105 | }; |
106 | |
107 | static const char * const camtg_parents[] = { |
108 | "clk26m" , |
109 | "univpll_192m_d8" , |
110 | "univpll_d3_d8" , |
111 | "univpll_192m_d4" , |
112 | "univpll_d3_d32" , |
113 | "univpll_192m_d16" , |
114 | "univpll_192m_d32" |
115 | }; |
116 | |
117 | static const char * const uart_parents[] = { |
118 | "clk26m" , |
119 | "univpll_d3_d8" |
120 | }; |
121 | |
122 | static const char * const spi_parents[] = { |
123 | "clk26m" , |
124 | "mainpll_d5_d4" , |
125 | "mainpll_d3_d4" , |
126 | "mainpll_d5_d2" , |
127 | "mainpll_d2_d4" , |
128 | "mainpll_d7" , |
129 | "mainpll_d3_d2" , |
130 | "mainpll_d5" |
131 | }; |
132 | |
133 | static const char * const msdc5hclk_parents[] = { |
134 | "clk26m" , |
135 | "mainpll_d2_d2" , |
136 | "mainpll_d7" , |
137 | "mainpll_d3_d2" |
138 | }; |
139 | |
140 | static const char * const msdc50_0_parents[] = { |
141 | "clk26m" , |
142 | "msdcpll" , |
143 | "univpll_d3" , |
144 | "msdcpll_d2" , |
145 | "mainpll_d7" , |
146 | "mainpll_d3_d2" , |
147 | "univpll_d2_d2" |
148 | }; |
149 | |
150 | static const char * const msdc30_1_parents[] = { |
151 | "clk26m" , |
152 | "msdcpll_d2" , |
153 | "univpll_d3_d2" , |
154 | "mainpll_d3_d2" , |
155 | "mainpll_d7" |
156 | }; |
157 | |
158 | static const char * const audio_parents[] = { |
159 | "clk26m" , |
160 | "mainpll_d5_d4" , |
161 | "mainpll_d7_d4" , |
162 | "mainpll_d2_d16" |
163 | }; |
164 | |
165 | static const char * const aud_intbus_parents[] = { |
166 | "clk26m" , |
167 | "mainpll_d2_d4" , |
168 | "mainpll_d7_d2" |
169 | }; |
170 | |
171 | static const char * const aud_1_parents[] = { |
172 | "clk26m" , |
173 | "apll1" |
174 | }; |
175 | |
176 | static const char * const aud_2_parents[] = { |
177 | "clk26m" , |
178 | "apll2" |
179 | }; |
180 | |
181 | static const char * const aud_engen1_parents[] = { |
182 | "clk26m" , |
183 | "apll1_d2" , |
184 | "apll1_d4" , |
185 | "apll1_d8" |
186 | }; |
187 | |
188 | static const char * const aud_engen2_parents[] = { |
189 | "clk26m" , |
190 | "apll2_d2" , |
191 | "apll2_d4" , |
192 | "apll2_d8" |
193 | }; |
194 | |
195 | static const char * const disp_pwm_parents[] = { |
196 | "clk26m" , |
197 | "univpll_d5_d2" , |
198 | "univpll_d3_d4" , |
199 | "ulposc1_d2" , |
200 | "ulposc1_d8" |
201 | }; |
202 | |
203 | static const char * const sspm_parents[] = { |
204 | "clk26m" , |
205 | "mainpll_d2_d2" , |
206 | "mainpll_d3_d2" , |
207 | "mainpll_d5" , |
208 | "mainpll_d3" |
209 | }; |
210 | |
211 | static const char * const dxcc_parents[] = { |
212 | "clk26m" , |
213 | "mainpll_d2_d2" , |
214 | "mainpll_d2_d4" |
215 | }; |
216 | |
217 | static const char * const usb_parents[] = { |
218 | "clk26m" , |
219 | "univpll_d5_d4" , |
220 | "univpll_d5_d2" |
221 | }; |
222 | |
223 | static const char * const srck_parents[] = { |
224 | "clk32k" , |
225 | "clk26m" , |
226 | "ulposc1_d10" |
227 | }; |
228 | |
229 | static const char * const spm_parents[] = { |
230 | "clk32k" , |
231 | "ulposc1_d10" , |
232 | "clk26m" , |
233 | "mainpll_d7_d2" |
234 | }; |
235 | |
236 | static const char * const i2c_parents[] = { |
237 | "clk26m" , |
238 | "univpll_d5_d4" , |
239 | "univpll_d3_d4" , |
240 | "univpll_d5_d2" |
241 | }; |
242 | |
243 | static const char * const pwm_parents[] = { |
244 | "clk26m" , |
245 | "univpll_d3_d8" , |
246 | "univpll_d3_d4" , |
247 | "univpll_d2_d4" |
248 | }; |
249 | |
250 | static const char * const seninf_parents[] = { |
251 | "clk26m" , |
252 | "univpll_d2_d4" , |
253 | "univpll_d2_d2" , |
254 | "univpll_d3_d2" |
255 | }; |
256 | |
257 | static const char * const aes_msdcfde_parents[] = { |
258 | "clk26m" , |
259 | "univpll_d3" , |
260 | "mainpll_d3" , |
261 | "univpll_d2_d2" , |
262 | "mainpll_d2_d2" , |
263 | "mainpll_d2_d4" |
264 | }; |
265 | |
266 | static const char * const pwrap_ulposc_parents[] = { |
267 | "clk26m" , |
268 | "univpll_d5_d4" , |
269 | "ulposc1_d4" , |
270 | "ulposc1_d8" , |
271 | "ulposc1_d10" , |
272 | "ulposc1_d16" , |
273 | "ulposc1_d32" |
274 | }; |
275 | |
276 | static const char * const camtm_parents[] = { |
277 | "clk26m" , |
278 | "univpll_d2_d4" , |
279 | "univpll_d3_d2" |
280 | }; |
281 | |
282 | static const char * const venc_parents[] = { |
283 | "clk26m" , |
284 | "mmpll" , |
285 | "mainpll_d2_d2" , |
286 | "mainpll_d2" , |
287 | "univpll_d3" , |
288 | "univpll_d2_d2" , |
289 | "mainpll_d3" , |
290 | "mmpll" |
291 | }; |
292 | |
293 | static const char * const isp_parents[] = { |
294 | "clk26m" , |
295 | "mainpll_d2" , |
296 | "mainpll_d2_d2" , |
297 | "univpll_d3" , |
298 | "mainpll_d3" , |
299 | "mmpll" , |
300 | "univpll_d5" , |
301 | "univpll_d2_d2" , |
302 | "mmpll_d2" |
303 | }; |
304 | |
305 | static const char * const dpmaif_parents[] = { |
306 | "clk26m" , |
307 | "univpll_d2_d2" , |
308 | "mainpll_d3" , |
309 | "mainpll_d2_d2" , |
310 | "univpll_d3_d2" |
311 | }; |
312 | |
313 | static const char * const vdec_parents[] = { |
314 | "clk26m" , |
315 | "mainpll_d3" , |
316 | "mainpll_d2_d2" , |
317 | "univpll_d5" , |
318 | "mainpll_d2" , |
319 | "univpll_d3" , |
320 | "univpll_d2_d2" |
321 | }; |
322 | |
323 | static const char * const disp_parents[] = { |
324 | "clk26m" , |
325 | "univpll_d3_d2" , |
326 | "mainpll_d5" , |
327 | "univpll_d5" , |
328 | "univpll_d2_d2" , |
329 | "mainpll_d3" , |
330 | "univpll_d3" , |
331 | "mainpll_d2" , |
332 | "mmpll" |
333 | }; |
334 | |
335 | static const char * const mdp_parents[] = { |
336 | "clk26m" , |
337 | "mainpll_d5" , |
338 | "univpll_d5" , |
339 | "mainpll_d2_d2" , |
340 | "univpll_d2_d2" , |
341 | "mainpll_d3" , |
342 | "univpll_d3" , |
343 | "mainpll_d2" , |
344 | "mmpll" |
345 | }; |
346 | |
347 | static const char * const audio_h_parents[] = { |
348 | "clk26m" , |
349 | "univpll_d7" , |
350 | "apll1" , |
351 | "apll2" |
352 | }; |
353 | |
354 | static const char * const ufs_parents[] = { |
355 | "clk26m" , |
356 | "mainpll_d7" , |
357 | "univpll_d2_d4" , |
358 | "mainpll_d2_d4" |
359 | }; |
360 | |
361 | static const char * const aes_fde_parents[] = { |
362 | "clk26m" , |
363 | "univpll_d3" , |
364 | "mainpll_d2_d2" , |
365 | "univpll_d5" |
366 | }; |
367 | |
368 | static const char * const audiodsp_parents[] = { |
369 | "clk26m" , |
370 | "ulposc1_d10" , |
371 | "adsppll" , |
372 | "adsppll_d2" , |
373 | "adsppll_d4" , |
374 | "adsppll_d8" |
375 | }; |
376 | |
377 | static const char * const dvfsrc_parents[] = { |
378 | "clk26m" , |
379 | "ulposc1_d10" , |
380 | }; |
381 | |
382 | static const char * const dsi_occ_parents[] = { |
383 | "clk26m" , |
384 | "univpll_d3_d2" , |
385 | "mpll" , |
386 | "mainpll_d5" |
387 | }; |
388 | |
389 | static const char * const spmi_mst_parents[] = { |
390 | "clk26m" , |
391 | "univpll_d5_d4" , |
392 | "ulposc1_d4" , |
393 | "ulposc1_d8" , |
394 | "ulposc1_d10" , |
395 | "ulposc1_d16" , |
396 | "ulposc1_d32" |
397 | }; |
398 | |
399 | static const char * const spinor_parents[] = { |
400 | "clk26m" , |
401 | "clk13m" , |
402 | "mainpll_d7_d4" , |
403 | "univpll_d3_d8" , |
404 | "univpll_d5_d4" , |
405 | "mainpll_d7_d2" |
406 | }; |
407 | |
408 | static const char * const nna_parents[] = { |
409 | "clk26m" , |
410 | "univpll_d3_d8" , |
411 | "mainpll_d2_d4" , |
412 | "univpll_d3_d2" , |
413 | "mainpll_d2_d2" , |
414 | "univpll_d2_d2" , |
415 | "mainpll_d3" , |
416 | "univpll_d3" , |
417 | "mmpll" , |
418 | "mainpll_d2" , |
419 | "univpll_d2" , |
420 | "nnapll_d2" , |
421 | "nnapll_d4" , |
422 | "nnapll_d8" , |
423 | "nnapll" , |
424 | "nna2pll" |
425 | }; |
426 | |
427 | static const char * const nna2_parents[] = { |
428 | "clk26m" , |
429 | "univpll_d3_d8" , |
430 | "mainpll_d2_d4" , |
431 | "univpll_d3_d2" , |
432 | "mainpll_d2_d2" , |
433 | "univpll_d2_d2" , |
434 | "mainpll_d3" , |
435 | "univpll_d3" , |
436 | "mmpll" , |
437 | "mainpll_d2" , |
438 | "univpll_d2" , |
439 | "nna2pll_d2" , |
440 | "nna2pll_d4" , |
441 | "nna2pll_d8" , |
442 | "nnapll" , |
443 | "nna2pll" |
444 | }; |
445 | |
446 | static const char * const ssusb_parents[] = { |
447 | "clk26m" , |
448 | "univpll_d5_d4" , |
449 | "univpll_d5_d2" |
450 | }; |
451 | |
452 | static const char * const wpe_parents[] = { |
453 | "clk26m" , |
454 | "univpll_d3_d2" , |
455 | "mainpll_d5" , |
456 | "univpll_d5" , |
457 | "univpll_d2_d2" , |
458 | "mainpll_d3" , |
459 | "univpll_d3" , |
460 | "mainpll_d2" , |
461 | "mmpll" |
462 | }; |
463 | |
464 | static const char * const dpi_parents[] = { |
465 | "clk26m" , |
466 | "tvdpll" , |
467 | "tvdpll_d2" , |
468 | "tvdpll_d4" , |
469 | "tvdpll_d8" , |
470 | "tvdpll_d16" , |
471 | "tvdpll_d32" |
472 | }; |
473 | |
474 | static const char * const u3_occ_250m_parents[] = { |
475 | "clk26m" , |
476 | "univpll_d5" |
477 | }; |
478 | |
479 | static const char * const u3_occ_500m_parents[] = { |
480 | "clk26m" , |
481 | "nna2pll_d2" |
482 | }; |
483 | |
484 | static const char * const adsp_bus_parents[] = { |
485 | "clk26m" , |
486 | "ulposc1_d2" , |
487 | "mainpll_d5" , |
488 | "mainpll_d2_d2" , |
489 | "mainpll_d3" , |
490 | "mainpll_d2" , |
491 | "univpll_d3" |
492 | }; |
493 | |
494 | static const char * const apll_mck_parents[] = { |
495 | "top_aud_1" , |
496 | "top_aud_2" |
497 | }; |
498 | |
499 | static const struct mtk_mux top_mtk_muxes[] = { |
500 | /* |
501 | * CLK_CFG_0 |
502 | * top_axi is bus clock, should not be closed by Linux. |
503 | * top_scp is main clock in always-on co-processor. |
504 | */ |
505 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI, "top_axi" , axi_parents, |
506 | 0x0040, 0x0044, 0x0048, 0, 2, 7, 0x0004, 0, |
507 | CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
508 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SCP, "top_scp" , scp_parents, |
509 | 0x0040, 0x0044, 0x0048, 8, 3, 15, 0x0004, 1, |
510 | CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
511 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG, "top_mfg" , |
512 | mfg_parents, 0x0040, 0x0044, 0x0048, 16, 2, 23, 0x0004, 2), |
513 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG, "top_camtg" , |
514 | camtg_parents, 0x0040, 0x0044, 0x0048, 24, 3, 31, 0x0004, 3), |
515 | /* CLK_CFG_1 */ |
516 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG1, "top_camtg1" , |
517 | camtg_parents, 0x0050, 0x0054, 0x0058, 0, 3, 7, 0x0004, 4), |
518 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2, "top_camtg2" , |
519 | camtg_parents, 0x0050, 0x0054, 0x0058, 8, 3, 15, 0x0004, 5), |
520 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3, "top_camtg3" , |
521 | camtg_parents, 0x0050, 0x0054, 0x0058, 16, 3, 23, 0x0004, 6), |
522 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG4, "top_camtg4" , |
523 | camtg_parents, 0x0050, 0x0054, 0x0058, 24, 3, 31, 0x0004, 7), |
524 | /* CLK_CFG_2 */ |
525 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG5, "top_camtg5" , |
526 | camtg_parents, 0x0060, 0x0064, 0x0068, 0, 3, 7, 0x0004, 8), |
527 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG6, "top_camtg6" , |
528 | camtg_parents, 0x0060, 0x0064, 0x0068, 8, 3, 15, 0x0004, 9), |
529 | MUX_GATE_CLR_SET_UPD(CLK_TOP_UART, "top_uart" , |
530 | uart_parents, 0x0060, 0x0064, 0x0068, 16, 1, 23, 0x0004, 10), |
531 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI, "top_spi" , |
532 | spi_parents, 0x0060, 0x0064, 0x0068, 24, 3, 31, 0x0004, 11), |
533 | /* CLK_CFG_3 */ |
534 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MSDC50_0_HCLK, "top_msdc5hclk" , |
535 | msdc5hclk_parents, 0x0070, 0x0074, 0x0078, 0, 2, 7, 0x0004, 12, 0), |
536 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MSDC50_0, "top_msdc50_0" , |
537 | msdc50_0_parents, 0x0070, 0x0074, 0x0078, 8, 3, 15, 0x0004, 13, 0), |
538 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MSDC30_1, "top_msdc30_1" , |
539 | msdc30_1_parents, 0x0070, 0x0074, 0x0078, 16, 3, 23, 0x0004, 14, 0), |
540 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO, "top_audio" , |
541 | audio_parents, 0x0070, 0x0074, 0x0078, 24, 2, 31, 0x0004, 15), |
542 | /* CLK_CFG_4 */ |
543 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS, "top_aud_intbus" , |
544 | aud_intbus_parents, 0x0080, 0x0084, 0x0088, 0, 2, 7, 0x0004, 16), |
545 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1, "top_aud_1" , |
546 | aud_1_parents, 0x0080, 0x0084, 0x0088, 8, 1, 15, 0x0004, 17), |
547 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_2, "top_aud_2" , |
548 | aud_2_parents, 0x0080, 0x0084, 0x0088, 16, 1, 23, 0x0004, 18), |
549 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN1, "top_aud_engen1" , |
550 | aud_engen1_parents, 0x0080, 0x0084, 0x0088, 24, 2, 31, 0x0004, 19), |
551 | /* |
552 | * CLK_CFG_5 |
553 | * top_sspm is main clock in always-on co-processor, should not be closed |
554 | * in Linux. |
555 | */ |
556 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN2, "top_aud_engen2" , |
557 | aud_engen2_parents, 0x0090, 0x0094, 0x0098, 0, 2, 7, 0x0004, 20), |
558 | MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM, "top_disp_pwm" , |
559 | disp_pwm_parents, 0x0090, 0x0094, 0x0098, 8, 3, 15, 0x0004, 21), |
560 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SSPM, "top_sspm" , sspm_parents, |
561 | 0x0090, 0x0094, 0x0098, 16, 3, 23, 0x0004, 22, |
562 | CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
563 | MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC, "top_dxcc" , |
564 | dxcc_parents, 0x0090, 0x0094, 0x0098, 24, 2, 31, 0x0004, 23), |
565 | /* |
566 | * CLK_CFG_6 |
567 | * top_spm and top_srck are main clocks in always-on co-processor. |
568 | */ |
569 | MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP, "top_usb" , |
570 | usb_parents, 0x00a0, 0x00a4, 0x00a8, 0, 2, 7, 0x0004, 24), |
571 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SRCK, "top_srck" , srck_parents, |
572 | 0x00a0, 0x00a4, 0x00a8, 8, 2, 15, 0x0004, 25, |
573 | CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
574 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM, "top_spm" , spm_parents, |
575 | 0x00a0, 0x00a4, 0x00a8, 16, 2, 23, 0x0004, 26, |
576 | CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
577 | MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C, "top_i2c" , |
578 | i2c_parents, 0x00a0, 0x00a4, 0x00a8, 24, 2, 31, 0x0004, 27), |
579 | /* CLK_CFG_7 */ |
580 | MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM, "top_pwm" , |
581 | pwm_parents, 0x00b0, 0x00b4, 0x00b8, 0, 2, 7, 0x0004, 28), |
582 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF, "top_seninf" , |
583 | seninf_parents, 0x00b0, 0x00b4, 0x00b8, 8, 2, 15, 0x0004, 29), |
584 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1, "top_seninf1" , |
585 | seninf_parents, 0x00b0, 0x00b4, 0x00b8, 16, 2, 23, 0x0004, 30), |
586 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2, "top_seninf2" , |
587 | seninf_parents, 0x00b0, 0x00b4, 0x00b8, 24, 2, 31, 0x0008, 0), |
588 | /* CLK_CFG_8 */ |
589 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF3, "top_seninf3" , |
590 | seninf_parents, 0x00c0, 0x00c4, 0x00c8, 0, 2, 7, 0x0008, 1), |
591 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_MSDCFDE, "top_aes_msdcfde" , |
592 | aes_msdcfde_parents, 0x00c0, 0x00c4, 0x00c8, 8, 3, 15, 0x0008, 2), |
593 | MUX_GATE_CLR_SET_UPD(CLK_TOP_PWRAP_ULPOSC, "top_pwrap_ulposc" , |
594 | pwrap_ulposc_parents, 0x00c0, 0x00c4, 0x00c8, 16, 3, 23, 0x0008, 3), |
595 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM, "top_camtm" , |
596 | camtm_parents, 0x00c0, 0x00c4, 0x00c8, 24, 2, 31, 0x0008, 4), |
597 | /* CLK_CFG_9 */ |
598 | MUX_GATE_CLR_SET_UPD(CLK_TOP_VENC, "top_venc" , |
599 | venc_parents, 0x00d0, 0x00d4, 0x00d8, 0, 3, 7, 0x0008, 5), |
600 | MUX_GATE_CLR_SET_UPD(CLK_TOP_CAM, "top_cam" , |
601 | isp_parents, 0x00d0, 0x00d4, 0x00d8, 8, 4, 15, 0x0008, 6), |
602 | MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG1, "top_img1" , |
603 | isp_parents, 0x00d0, 0x00d4, 0x00d8, 16, 4, 23, 0x0008, 7), |
604 | MUX_GATE_CLR_SET_UPD(CLK_TOP_IPE, "top_ipe" , |
605 | isp_parents, 0x00d0, 0x00d4, 0x00d8, 24, 4, 31, 0x0008, 8), |
606 | /* CLK_CFG_10 */ |
607 | MUX_GATE_CLR_SET_UPD(CLK_TOP_DPMAIF, "top_dpmaif" , |
608 | dpmaif_parents, 0x00e0, 0x00e4, 0x00e8, 0, 3, 7, 0x0008, 9), |
609 | MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC, "top_vdec" , |
610 | vdec_parents, 0x00e0, 0x00e4, 0x00e8, 8, 3, 15, 0x0008, 10), |
611 | MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP, "top_disp" , |
612 | disp_parents, 0x00e0, 0x00e4, 0x00e8, 16, 4, 23, 0x0008, 11), |
613 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MDP, "top_mdp" , |
614 | mdp_parents, 0x00e0, 0x00e4, 0x00e8, 24, 4, 31, 0x0008, 12), |
615 | /* CLK_CFG_11 */ |
616 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_H, "top_audio_h" , |
617 | audio_h_parents, 0x00ec, 0x00f0, 0x00f4, 0, 2, 7, 0x0008, 13), |
618 | MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS, "top_ufs" , |
619 | ufs_parents, 0x00ec, 0x00f0, 0x00f4, 8, 2, 15, 0x0008, 14), |
620 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_FDE, "top_aes_fde" , |
621 | aes_fde_parents, 0x00ec, 0x00f0, 0x00f4, 16, 2, 23, 0x0008, 15), |
622 | MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIODSP, "top_audiodsp" , |
623 | audiodsp_parents, 0x00ec, 0x00f0, 0x00f4, 24, 3, 31, 0x0008, 16), |
624 | /* |
625 | * CLK_CFG_12 |
626 | * dvfsrc is for internal DVFS usage, should not be closed in Linux. |
627 | */ |
628 | MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DVFSRC, "top_dvfsrc" , dvfsrc_parents, |
629 | 0x0100, 0x0104, 0x0108, 0, 1, 7, 0x0008, 17, |
630 | CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
631 | MUX_GATE_CLR_SET_UPD(CLK_TOP_DSI_OCC, "top_dsi_occ" , |
632 | dsi_occ_parents, 0x0100, 0x0104, 0x0108, 8, 2, 15, 0x0008, 18), |
633 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_MST, "top_spmi_mst" , |
634 | spmi_mst_parents, 0x0100, 0x0104, 0x0108, 16, 3, 23, 0x0008, 19), |
635 | /* CLK_CFG_13 */ |
636 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINOR, "top_spinor" , |
637 | spinor_parents, 0x0110, 0x0114, 0x0118, 0, 3, 6, 0x0008, 20), |
638 | MUX_GATE_CLR_SET_UPD(CLK_TOP_NNA, "top_nna" , |
639 | nna_parents, 0x0110, 0x0114, 0x0118, 7, 4, 14, 0x0008, 21), |
640 | MUX_GATE_CLR_SET_UPD(CLK_TOP_NNA1, "top_nna1" , |
641 | nna_parents, 0x0110, 0x0114, 0x0118, 15, 4, 22, 0x0008, 22), |
642 | MUX_GATE_CLR_SET_UPD(CLK_TOP_NNA2, "top_nna2" , |
643 | nna2_parents, 0x0110, 0x0114, 0x0118, 23, 4, 30, 0x0008, 23), |
644 | /* CLK_CFG_14 */ |
645 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI, "top_ssusb_xhci" , |
646 | ssusb_parents, 0x0120, 0x0124, 0x0128, 0, 2, 5, 0x0008, 24), |
647 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_TOP_1P, "top_ssusb_1p" , |
648 | ssusb_parents, 0x0120, 0x0124, 0x0128, 6, 2, 11, 0x0008, 25), |
649 | MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_1P, "top_ssusb_xhci_1p" , |
650 | ssusb_parents, 0x0120, 0x0124, 0x0128, 12, 2, 17, 0x0008, 26), |
651 | MUX_GATE_CLR_SET_UPD(CLK_TOP_WPE, "top_wpe" , |
652 | wpe_parents, 0x0120, 0x0124, 0x0128, 18, 4, 25, 0x0008, 27), |
653 | /* CLK_CFG_15 */ |
654 | MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI, "top_dpi" , |
655 | dpi_parents, 0x0180, 0x0184, 0x0188, 0, 3, 6, 0x0008, 28), |
656 | MUX_GATE_CLR_SET_UPD(CLK_TOP_U3_OCC_250M, "top_u3_occ_250m" , |
657 | u3_occ_250m_parents, 0x0180, 0x0184, 0x0188, 7, 1, 11, 0x0008, 29), |
658 | MUX_GATE_CLR_SET_UPD(CLK_TOP_U3_OCC_500M, "top_u3_occ_500m" , |
659 | u3_occ_500m_parents, 0x0180, 0x0184, 0x0188, 12, 1, 16, 0x0008, 30), |
660 | MUX_GATE_CLR_SET_UPD(CLK_TOP_ADSP_BUS, "top_adsp_bus" , |
661 | adsp_bus_parents, 0x0180, 0x0184, 0x0188, 17, 3, 23, 0x0008, 31), |
662 | }; |
663 | |
664 | static struct mtk_composite top_muxes[] = { |
665 | /* CLK_AUDDIV_0 */ |
666 | MUX(CLK_TOP_APLL_I2S0_MCK_SEL, "apll_i2s0_mck_sel" , apll_mck_parents, 0x0320, 16, 1), |
667 | MUX(CLK_TOP_APLL_I2S1_MCK_SEL, "apll_i2s1_mck_sel" , apll_mck_parents, 0x0320, 17, 1), |
668 | MUX(CLK_TOP_APLL_I2S2_MCK_SEL, "apll_i2s2_mck_sel" , apll_mck_parents, 0x0320, 18, 1), |
669 | MUX(CLK_TOP_APLL_I2S4_MCK_SEL, "apll_i2s4_mck_sel" , apll_mck_parents, 0x0320, 19, 1), |
670 | MUX(CLK_TOP_APLL_TDMOUT_MCK_SEL, "apll_tdmout_mck_sel" , apll_mck_parents, |
671 | 0x0320, 20, 1), |
672 | DIV_GATE(CLK_TOP_APLL12_CK_DIV0, "apll12_div0" , "apll_i2s0_mck_sel" , |
673 | 0x0320, 0, 0x0328, 8, 0), |
674 | DIV_GATE(CLK_TOP_APLL12_CK_DIV1, "apll12_div1" , "apll_i2s1_mck_sel" , |
675 | 0x0320, 1, 0x0328, 8, 8), |
676 | DIV_GATE(CLK_TOP_APLL12_CK_DIV2, "apll12_div2" , "apll_i2s2_mck_sel" , |
677 | 0x0320, 2, 0x0328, 8, 16), |
678 | DIV_GATE(CLK_TOP_APLL12_CK_DIV4, "apll12_div4" , "apll_i2s4_mck_sel" , |
679 | 0x0320, 3, 0x0328, 8, 24), |
680 | DIV_GATE(CLK_TOP_APLL12_CK_DIV_TDMOUT_M, "apll12_div_tdmout_m" , "apll_tdmout_mck_sel" , |
681 | 0x0320, 4, 0x0334, 8, 0), |
682 | }; |
683 | |
684 | /* Register mux notifier for MFG mux */ |
685 | static int clk_mt8186_reg_mfg_mux_notifier(struct device *dev, struct clk *clk) |
686 | { |
687 | struct mtk_mux_nb *mfg_mux_nb; |
688 | int i; |
689 | |
690 | mfg_mux_nb = devm_kzalloc(dev, size: sizeof(*mfg_mux_nb), GFP_KERNEL); |
691 | if (!mfg_mux_nb) |
692 | return -ENOMEM; |
693 | |
694 | for (i = 0; i < ARRAY_SIZE(top_mtk_muxes); i++) |
695 | if (top_mtk_muxes[i].id == CLK_TOP_MFG) |
696 | break; |
697 | if (i == ARRAY_SIZE(top_mtk_muxes)) |
698 | return -EINVAL; |
699 | |
700 | mfg_mux_nb->ops = top_mtk_muxes[i].ops; |
701 | mfg_mux_nb->bypass_index = 0; /* Bypass to 26M crystal */ |
702 | |
703 | return devm_mtk_clk_mux_notifier_register(dev, clk, mux_nb: mfg_mux_nb); |
704 | } |
705 | |
706 | static const struct mtk_clk_desc topck_desc = { |
707 | .fixed_clks = top_fixed_clks, |
708 | .num_fixed_clks = ARRAY_SIZE(top_fixed_clks), |
709 | .factor_clks = top_divs, |
710 | .num_factor_clks = ARRAY_SIZE(top_divs), |
711 | .mux_clks = top_mtk_muxes, |
712 | .num_mux_clks = ARRAY_SIZE(top_mtk_muxes), |
713 | .composite_clks = top_muxes, |
714 | .num_composite_clks = ARRAY_SIZE(top_muxes), |
715 | .clk_lock = &mt8186_clk_lock, |
716 | .clk_notifier_func = clk_mt8186_reg_mfg_mux_notifier, |
717 | .mfg_clk_idx = CLK_TOP_MFG, |
718 | }; |
719 | |
720 | static const struct of_device_id of_match_clk_mt8186_topck[] = { |
721 | { .compatible = "mediatek,mt8186-topckgen" , .data = &topck_desc }, |
722 | { /* sentinel */ } |
723 | }; |
724 | MODULE_DEVICE_TABLE(of, of_match_clk_mt8186_topck); |
725 | |
726 | static struct platform_driver clk_mt8186_topck_drv = { |
727 | .probe = mtk_clk_simple_probe, |
728 | .remove_new = mtk_clk_simple_remove, |
729 | .driver = { |
730 | .name = "clk-mt8186-topck" , |
731 | .of_match_table = of_match_clk_mt8186_topck, |
732 | }, |
733 | }; |
734 | module_platform_driver(clk_mt8186_topck_drv); |
735 | MODULE_LICENSE("GPL" ); |
736 | |