xref: /openbmc/linux/drivers/clk/meson/meson8b.c (revision c67e8ec0)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2015 Endless Mobile, Inc.
4  * Author: Carlo Caione <carlo@endlessm.com>
5  *
6  * Copyright (c) 2016 BayLibre, Inc.
7  * Michael Turquette <mturquette@baylibre.com>
8  */
9 
10 #include <linux/clk.h>
11 #include <linux/clk-provider.h>
12 #include <linux/init.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/of_address.h>
15 #include <linux/reset-controller.h>
16 #include <linux/slab.h>
17 #include <linux/regmap.h>
18 
19 #include "clkc.h"
20 #include "meson8b.h"
21 #include "clk-regmap.h"
22 
23 static DEFINE_SPINLOCK(meson_clk_lock);
24 
25 struct meson8b_clk_reset {
26 	struct reset_controller_dev reset;
27 	struct regmap *regmap;
28 };
29 
30 static const struct pll_params_table sys_pll_params_table[] = {
31 	PLL_PARAMS(50, 1),
32 	PLL_PARAMS(51, 1),
33 	PLL_PARAMS(52, 1),
34 	PLL_PARAMS(53, 1),
35 	PLL_PARAMS(54, 1),
36 	PLL_PARAMS(55, 1),
37 	PLL_PARAMS(56, 1),
38 	PLL_PARAMS(57, 1),
39 	PLL_PARAMS(58, 1),
40 	PLL_PARAMS(59, 1),
41 	PLL_PARAMS(60, 1),
42 	PLL_PARAMS(61, 1),
43 	PLL_PARAMS(62, 1),
44 	PLL_PARAMS(63, 1),
45 	PLL_PARAMS(64, 1),
46 	PLL_PARAMS(65, 1),
47 	PLL_PARAMS(66, 1),
48 	PLL_PARAMS(67, 1),
49 	PLL_PARAMS(68, 1),
50 	PLL_PARAMS(84, 1),
51 	{ /* sentinel */ },
52 };
53 
54 static struct clk_fixed_rate meson8b_xtal = {
55 	.fixed_rate = 24000000,
56 	.hw.init = &(struct clk_init_data){
57 		.name = "xtal",
58 		.num_parents = 0,
59 		.ops = &clk_fixed_rate_ops,
60 	},
61 };
62 
63 static struct clk_regmap meson8b_fixed_pll_dco = {
64 	.data = &(struct meson_clk_pll_data){
65 		.en = {
66 			.reg_off = HHI_MPLL_CNTL,
67 			.shift   = 30,
68 			.width   = 1,
69 		},
70 		.m = {
71 			.reg_off = HHI_MPLL_CNTL,
72 			.shift   = 0,
73 			.width   = 9,
74 		},
75 		.n = {
76 			.reg_off = HHI_MPLL_CNTL,
77 			.shift   = 9,
78 			.width   = 5,
79 		},
80 		.frac = {
81 			.reg_off = HHI_MPLL_CNTL2,
82 			.shift   = 0,
83 			.width   = 12,
84 		},
85 		.l = {
86 			.reg_off = HHI_MPLL_CNTL,
87 			.shift   = 31,
88 			.width   = 1,
89 		},
90 		.rst = {
91 			.reg_off = HHI_MPLL_CNTL,
92 			.shift   = 29,
93 			.width   = 1,
94 		},
95 	},
96 	.hw.init = &(struct clk_init_data){
97 		.name = "fixed_pll_dco",
98 		.ops = &meson_clk_pll_ro_ops,
99 		.parent_names = (const char *[]){ "xtal" },
100 		.num_parents = 1,
101 	},
102 };
103 
104 static struct clk_regmap meson8b_fixed_pll = {
105 	.data = &(struct clk_regmap_div_data){
106 		.offset = HHI_MPLL_CNTL,
107 		.shift = 16,
108 		.width = 2,
109 		.flags = CLK_DIVIDER_POWER_OF_TWO,
110 	},
111 	.hw.init = &(struct clk_init_data){
112 		.name = "fixed_pll",
113 		.ops = &clk_regmap_divider_ro_ops,
114 		.parent_names = (const char *[]){ "fixed_pll_dco" },
115 		.num_parents = 1,
116 		/*
117 		 * This clock won't ever change at runtime so
118 		 * CLK_SET_RATE_PARENT is not required
119 		 */
120 	},
121 };
122 
123 static struct clk_regmap meson8b_hdmi_pll_dco = {
124 	.data = &(struct meson_clk_pll_data){
125 		.en = {
126 			.reg_off = HHI_VID_PLL_CNTL,
127 			.shift   = 30,
128 			.width   = 1,
129 		},
130 		.m = {
131 			.reg_off = HHI_VID_PLL_CNTL,
132 			.shift   = 0,
133 			.width   = 9,
134 		},
135 		.n = {
136 			.reg_off = HHI_VID_PLL_CNTL,
137 			.shift   = 10,
138 			.width   = 5,
139 		},
140 		.frac = {
141 			.reg_off = HHI_VID_PLL_CNTL2,
142 			.shift   = 0,
143 			.width   = 12,
144 		},
145 		.l = {
146 			.reg_off = HHI_VID_PLL_CNTL,
147 			.shift   = 31,
148 			.width   = 1,
149 		},
150 		.rst = {
151 			.reg_off = HHI_VID_PLL_CNTL,
152 			.shift   = 29,
153 			.width   = 1,
154 		},
155 	},
156 	.hw.init = &(struct clk_init_data){
157 		/* sometimes also called "HPLL" or "HPLL PLL" */
158 		.name = "hdmi_pll_dco",
159 		.ops = &meson_clk_pll_ro_ops,
160 		.parent_names = (const char *[]){ "xtal" },
161 		.num_parents = 1,
162 	},
163 };
164 
165 static struct clk_regmap meson8b_hdmi_pll_lvds_out = {
166 	.data = &(struct clk_regmap_div_data){
167 		.offset = HHI_VID_PLL_CNTL,
168 		.shift = 16,
169 		.width = 2,
170 		.flags = CLK_DIVIDER_POWER_OF_TWO,
171 	},
172 	.hw.init = &(struct clk_init_data){
173 		.name = "hdmi_pll_lvds_out",
174 		.ops = &clk_regmap_divider_ro_ops,
175 		.parent_names = (const char *[]){ "hdmi_pll_dco" },
176 		.num_parents = 1,
177 		.flags = CLK_SET_RATE_PARENT,
178 	},
179 };
180 
181 static struct clk_regmap meson8b_hdmi_pll_hdmi_out = {
182 	.data = &(struct clk_regmap_div_data){
183 		.offset = HHI_VID_PLL_CNTL,
184 		.shift = 18,
185 		.width = 2,
186 		.flags = CLK_DIVIDER_POWER_OF_TWO,
187 	},
188 	.hw.init = &(struct clk_init_data){
189 		.name = "hdmi_pll_hdmi_out",
190 		.ops = &clk_regmap_divider_ro_ops,
191 		.parent_names = (const char *[]){ "hdmi_pll_dco" },
192 		.num_parents = 1,
193 		.flags = CLK_SET_RATE_PARENT,
194 	},
195 };
196 
197 static struct clk_regmap meson8b_sys_pll_dco = {
198 	.data = &(struct meson_clk_pll_data){
199 		.en = {
200 			.reg_off = HHI_SYS_PLL_CNTL,
201 			.shift   = 30,
202 			.width   = 1,
203 		},
204 		.m = {
205 			.reg_off = HHI_SYS_PLL_CNTL,
206 			.shift   = 0,
207 			.width   = 9,
208 		},
209 		.n = {
210 			.reg_off = HHI_SYS_PLL_CNTL,
211 			.shift   = 9,
212 			.width   = 5,
213 		},
214 		.l = {
215 			.reg_off = HHI_SYS_PLL_CNTL,
216 			.shift   = 31,
217 			.width   = 1,
218 		},
219 		.rst = {
220 			.reg_off = HHI_SYS_PLL_CNTL,
221 			.shift   = 29,
222 			.width   = 1,
223 		},
224 		.table = sys_pll_params_table,
225 	},
226 	.hw.init = &(struct clk_init_data){
227 		.name = "sys_pll_dco",
228 		.ops = &meson_clk_pll_ops,
229 		.parent_names = (const char *[]){ "xtal" },
230 		.num_parents = 1,
231 	},
232 };
233 
234 static struct clk_regmap meson8b_sys_pll = {
235 	.data = &(struct clk_regmap_div_data){
236 		.offset = HHI_SYS_PLL_CNTL,
237 		.shift = 16,
238 		.width = 2,
239 		.flags = CLK_DIVIDER_POWER_OF_TWO,
240 	},
241 	.hw.init = &(struct clk_init_data){
242 		.name = "sys_pll",
243 		.ops = &clk_regmap_divider_ops,
244 		.parent_names = (const char *[]){ "sys_pll_dco" },
245 		.num_parents = 1,
246 		.flags = CLK_SET_RATE_PARENT,
247 	},
248 };
249 
250 static struct clk_fixed_factor meson8b_fclk_div2_div = {
251 	.mult = 1,
252 	.div = 2,
253 	.hw.init = &(struct clk_init_data){
254 		.name = "fclk_div2_div",
255 		.ops = &clk_fixed_factor_ops,
256 		.parent_names = (const char *[]){ "fixed_pll" },
257 		.num_parents = 1,
258 	},
259 };
260 
261 static struct clk_regmap meson8b_fclk_div2 = {
262 	.data = &(struct clk_regmap_gate_data){
263 		.offset = HHI_MPLL_CNTL6,
264 		.bit_idx = 27,
265 	},
266 	.hw.init = &(struct clk_init_data){
267 		.name = "fclk_div2",
268 		.ops = &clk_regmap_gate_ops,
269 		.parent_names = (const char *[]){ "fclk_div2_div" },
270 		.num_parents = 1,
271 		/*
272 		 * FIXME: Ethernet with a RGMII PHYs is not working if
273 		 * fclk_div2 is disabled. it is currently unclear why this
274 		 * is. keep it enabled until the Ethernet driver knows how
275 		 * to manage this clock.
276 		 */
277 		.flags = CLK_IS_CRITICAL,
278 	},
279 };
280 
281 static struct clk_fixed_factor meson8b_fclk_div3_div = {
282 	.mult = 1,
283 	.div = 3,
284 	.hw.init = &(struct clk_init_data){
285 		.name = "fclk_div3_div",
286 		.ops = &clk_fixed_factor_ops,
287 		.parent_names = (const char *[]){ "fixed_pll" },
288 		.num_parents = 1,
289 	},
290 };
291 
292 static struct clk_regmap meson8b_fclk_div3 = {
293 	.data = &(struct clk_regmap_gate_data){
294 		.offset = HHI_MPLL_CNTL6,
295 		.bit_idx = 28,
296 	},
297 	.hw.init = &(struct clk_init_data){
298 		.name = "fclk_div3",
299 		.ops = &clk_regmap_gate_ops,
300 		.parent_names = (const char *[]){ "fclk_div3_div" },
301 		.num_parents = 1,
302 	},
303 };
304 
305 static struct clk_fixed_factor meson8b_fclk_div4_div = {
306 	.mult = 1,
307 	.div = 4,
308 	.hw.init = &(struct clk_init_data){
309 		.name = "fclk_div4_div",
310 		.ops = &clk_fixed_factor_ops,
311 		.parent_names = (const char *[]){ "fixed_pll" },
312 		.num_parents = 1,
313 	},
314 };
315 
316 static struct clk_regmap meson8b_fclk_div4 = {
317 	.data = &(struct clk_regmap_gate_data){
318 		.offset = HHI_MPLL_CNTL6,
319 		.bit_idx = 29,
320 	},
321 	.hw.init = &(struct clk_init_data){
322 		.name = "fclk_div4",
323 		.ops = &clk_regmap_gate_ops,
324 		.parent_names = (const char *[]){ "fclk_div4_div" },
325 		.num_parents = 1,
326 	},
327 };
328 
329 static struct clk_fixed_factor meson8b_fclk_div5_div = {
330 	.mult = 1,
331 	.div = 5,
332 	.hw.init = &(struct clk_init_data){
333 		.name = "fclk_div5_div",
334 		.ops = &clk_fixed_factor_ops,
335 		.parent_names = (const char *[]){ "fixed_pll" },
336 		.num_parents = 1,
337 	},
338 };
339 
340 static struct clk_regmap meson8b_fclk_div5 = {
341 	.data = &(struct clk_regmap_gate_data){
342 		.offset = HHI_MPLL_CNTL6,
343 		.bit_idx = 30,
344 	},
345 	.hw.init = &(struct clk_init_data){
346 		.name = "fclk_div5",
347 		.ops = &clk_regmap_gate_ops,
348 		.parent_names = (const char *[]){ "fclk_div5_div" },
349 		.num_parents = 1,
350 	},
351 };
352 
353 static struct clk_fixed_factor meson8b_fclk_div7_div = {
354 	.mult = 1,
355 	.div = 7,
356 	.hw.init = &(struct clk_init_data){
357 		.name = "fclk_div7_div",
358 		.ops = &clk_fixed_factor_ops,
359 		.parent_names = (const char *[]){ "fixed_pll" },
360 		.num_parents = 1,
361 	},
362 };
363 
364 static struct clk_regmap meson8b_fclk_div7 = {
365 	.data = &(struct clk_regmap_gate_data){
366 		.offset = HHI_MPLL_CNTL6,
367 		.bit_idx = 31,
368 	},
369 	.hw.init = &(struct clk_init_data){
370 		.name = "fclk_div7",
371 		.ops = &clk_regmap_gate_ops,
372 		.parent_names = (const char *[]){ "fclk_div7_div" },
373 		.num_parents = 1,
374 	},
375 };
376 
377 static struct clk_regmap meson8b_mpll_prediv = {
378 	.data = &(struct clk_regmap_div_data){
379 		.offset = HHI_MPLL_CNTL5,
380 		.shift = 12,
381 		.width = 1,
382 	},
383 	.hw.init = &(struct clk_init_data){
384 		.name = "mpll_prediv",
385 		.ops = &clk_regmap_divider_ro_ops,
386 		.parent_names = (const char *[]){ "fixed_pll" },
387 		.num_parents = 1,
388 	},
389 };
390 
391 static struct clk_regmap meson8b_mpll0_div = {
392 	.data = &(struct meson_clk_mpll_data){
393 		.sdm = {
394 			.reg_off = HHI_MPLL_CNTL7,
395 			.shift   = 0,
396 			.width   = 14,
397 		},
398 		.sdm_en = {
399 			.reg_off = HHI_MPLL_CNTL7,
400 			.shift   = 15,
401 			.width   = 1,
402 		},
403 		.n2 = {
404 			.reg_off = HHI_MPLL_CNTL7,
405 			.shift   = 16,
406 			.width   = 9,
407 		},
408 		.ssen = {
409 			.reg_off = HHI_MPLL_CNTL,
410 			.shift   = 25,
411 			.width   = 1,
412 		},
413 		.lock = &meson_clk_lock,
414 	},
415 	.hw.init = &(struct clk_init_data){
416 		.name = "mpll0_div",
417 		.ops = &meson_clk_mpll_ops,
418 		.parent_names = (const char *[]){ "mpll_prediv" },
419 		.num_parents = 1,
420 	},
421 };
422 
423 static struct clk_regmap meson8b_mpll0 = {
424 	.data = &(struct clk_regmap_gate_data){
425 		.offset = HHI_MPLL_CNTL7,
426 		.bit_idx = 14,
427 	},
428 	.hw.init = &(struct clk_init_data){
429 		.name = "mpll0",
430 		.ops = &clk_regmap_gate_ops,
431 		.parent_names = (const char *[]){ "mpll0_div" },
432 		.num_parents = 1,
433 		.flags = CLK_SET_RATE_PARENT,
434 	},
435 };
436 
437 static struct clk_regmap meson8b_mpll1_div = {
438 	.data = &(struct meson_clk_mpll_data){
439 		.sdm = {
440 			.reg_off = HHI_MPLL_CNTL8,
441 			.shift   = 0,
442 			.width   = 14,
443 		},
444 		.sdm_en = {
445 			.reg_off = HHI_MPLL_CNTL8,
446 			.shift   = 15,
447 			.width   = 1,
448 		},
449 		.n2 = {
450 			.reg_off = HHI_MPLL_CNTL8,
451 			.shift   = 16,
452 			.width   = 9,
453 		},
454 		.lock = &meson_clk_lock,
455 	},
456 	.hw.init = &(struct clk_init_data){
457 		.name = "mpll1_div",
458 		.ops = &meson_clk_mpll_ops,
459 		.parent_names = (const char *[]){ "mpll_prediv" },
460 		.num_parents = 1,
461 	},
462 };
463 
464 static struct clk_regmap meson8b_mpll1 = {
465 	.data = &(struct clk_regmap_gate_data){
466 		.offset = HHI_MPLL_CNTL8,
467 		.bit_idx = 14,
468 	},
469 	.hw.init = &(struct clk_init_data){
470 		.name = "mpll1",
471 		.ops = &clk_regmap_gate_ops,
472 		.parent_names = (const char *[]){ "mpll1_div" },
473 		.num_parents = 1,
474 		.flags = CLK_SET_RATE_PARENT,
475 	},
476 };
477 
478 static struct clk_regmap meson8b_mpll2_div = {
479 	.data = &(struct meson_clk_mpll_data){
480 		.sdm = {
481 			.reg_off = HHI_MPLL_CNTL9,
482 			.shift   = 0,
483 			.width   = 14,
484 		},
485 		.sdm_en = {
486 			.reg_off = HHI_MPLL_CNTL9,
487 			.shift   = 15,
488 			.width   = 1,
489 		},
490 		.n2 = {
491 			.reg_off = HHI_MPLL_CNTL9,
492 			.shift   = 16,
493 			.width   = 9,
494 		},
495 		.lock = &meson_clk_lock,
496 	},
497 	.hw.init = &(struct clk_init_data){
498 		.name = "mpll2_div",
499 		.ops = &meson_clk_mpll_ops,
500 		.parent_names = (const char *[]){ "mpll_prediv" },
501 		.num_parents = 1,
502 	},
503 };
504 
505 static struct clk_regmap meson8b_mpll2 = {
506 	.data = &(struct clk_regmap_gate_data){
507 		.offset = HHI_MPLL_CNTL9,
508 		.bit_idx = 14,
509 	},
510 	.hw.init = &(struct clk_init_data){
511 		.name = "mpll2",
512 		.ops = &clk_regmap_gate_ops,
513 		.parent_names = (const char *[]){ "mpll2_div" },
514 		.num_parents = 1,
515 		.flags = CLK_SET_RATE_PARENT,
516 	},
517 };
518 
519 static u32 mux_table_clk81[]	= { 6, 5, 7 };
520 static struct clk_regmap meson8b_mpeg_clk_sel = {
521 	.data = &(struct clk_regmap_mux_data){
522 		.offset = HHI_MPEG_CLK_CNTL,
523 		.mask = 0x7,
524 		.shift = 12,
525 		.table = mux_table_clk81,
526 	},
527 	.hw.init = &(struct clk_init_data){
528 		.name = "mpeg_clk_sel",
529 		.ops = &clk_regmap_mux_ro_ops,
530 		/*
531 		 * FIXME bits 14:12 selects from 8 possible parents:
532 		 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
533 		 * fclk_div4, fclk_div3, fclk_div5
534 		 */
535 		.parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
536 			"fclk_div5" },
537 		.num_parents = 3,
538 	},
539 };
540 
541 static struct clk_regmap meson8b_mpeg_clk_div = {
542 	.data = &(struct clk_regmap_div_data){
543 		.offset = HHI_MPEG_CLK_CNTL,
544 		.shift = 0,
545 		.width = 7,
546 	},
547 	.hw.init = &(struct clk_init_data){
548 		.name = "mpeg_clk_div",
549 		.ops = &clk_regmap_divider_ro_ops,
550 		.parent_names = (const char *[]){ "mpeg_clk_sel" },
551 		.num_parents = 1,
552 	},
553 };
554 
555 static struct clk_regmap meson8b_clk81 = {
556 	.data = &(struct clk_regmap_gate_data){
557 		.offset = HHI_MPEG_CLK_CNTL,
558 		.bit_idx = 7,
559 	},
560 	.hw.init = &(struct clk_init_data){
561 		.name = "clk81",
562 		.ops = &clk_regmap_gate_ops,
563 		.parent_names = (const char *[]){ "mpeg_clk_div" },
564 		.num_parents = 1,
565 		.flags = CLK_IS_CRITICAL,
566 	},
567 };
568 
569 static struct clk_regmap meson8b_cpu_in_sel = {
570 	.data = &(struct clk_regmap_mux_data){
571 		.offset = HHI_SYS_CPU_CLK_CNTL0,
572 		.mask = 0x1,
573 		.shift = 0,
574 	},
575 	.hw.init = &(struct clk_init_data){
576 		.name = "cpu_in_sel",
577 		.ops = &clk_regmap_mux_ops,
578 		.parent_names = (const char *[]){ "xtal", "sys_pll" },
579 		.num_parents = 2,
580 		.flags = (CLK_SET_RATE_PARENT |
581 			  CLK_SET_RATE_NO_REPARENT),
582 	},
583 };
584 
585 static struct clk_fixed_factor meson8b_cpu_in_div2 = {
586 	.mult = 1,
587 	.div = 2,
588 	.hw.init = &(struct clk_init_data){
589 		.name = "cpu_in_div2",
590 		.ops = &clk_fixed_factor_ops,
591 		.parent_names = (const char *[]){ "cpu_in_sel" },
592 		.num_parents = 1,
593 		.flags = CLK_SET_RATE_PARENT,
594 	},
595 };
596 
597 static struct clk_fixed_factor meson8b_cpu_in_div3 = {
598 	.mult = 1,
599 	.div = 3,
600 	.hw.init = &(struct clk_init_data){
601 		.name = "cpu_in_div3",
602 		.ops = &clk_fixed_factor_ops,
603 		.parent_names = (const char *[]){ "cpu_in_sel" },
604 		.num_parents = 1,
605 		.flags = CLK_SET_RATE_PARENT,
606 	},
607 };
608 
609 static const struct clk_div_table cpu_scale_table[] = {
610 	{ .val = 1, .div = 4 },
611 	{ .val = 2, .div = 6 },
612 	{ .val = 3, .div = 8 },
613 	{ .val = 4, .div = 10 },
614 	{ .val = 5, .div = 12 },
615 	{ .val = 6, .div = 14 },
616 	{ .val = 7, .div = 16 },
617 	{ .val = 8, .div = 18 },
618 	{ /* sentinel */ },
619 };
620 
621 static struct clk_regmap meson8b_cpu_scale_div = {
622 	.data = &(struct clk_regmap_div_data){
623 		.offset =  HHI_SYS_CPU_CLK_CNTL1,
624 		.shift = 20,
625 		.width = 10,
626 		.table = cpu_scale_table,
627 		.flags = CLK_DIVIDER_ALLOW_ZERO,
628 	},
629 	.hw.init = &(struct clk_init_data){
630 		.name = "cpu_scale_div",
631 		.ops = &clk_regmap_divider_ops,
632 		.parent_names = (const char *[]){ "cpu_in_sel" },
633 		.num_parents = 1,
634 		.flags = CLK_SET_RATE_PARENT,
635 	},
636 };
637 
638 static u32 mux_table_cpu_scale_out_sel[] = { 0, 1, 3 };
639 static struct clk_regmap meson8b_cpu_scale_out_sel = {
640 	.data = &(struct clk_regmap_mux_data){
641 		.offset = HHI_SYS_CPU_CLK_CNTL0,
642 		.mask = 0x3,
643 		.shift = 2,
644 		.table = mux_table_cpu_scale_out_sel,
645 	},
646 	.hw.init = &(struct clk_init_data){
647 		.name = "cpu_scale_out_sel",
648 		.ops = &clk_regmap_mux_ops,
649 		/*
650 		 * NOTE: We are skipping the parent with value 0x2 (which is
651 		 * "cpu_in_div3") because it results in a duty cycle of 33%
652 		 * which makes the system unstable and can result in a lockup
653 		 * of the whole system.
654 		 */
655 		.parent_names = (const char *[]) { "cpu_in_sel",
656 						   "cpu_in_div2",
657 						   "cpu_scale_div" },
658 		.num_parents = 3,
659 		.flags = CLK_SET_RATE_PARENT,
660 	},
661 };
662 
663 static struct clk_regmap meson8b_cpu_clk = {
664 	.data = &(struct clk_regmap_mux_data){
665 		.offset = HHI_SYS_CPU_CLK_CNTL0,
666 		.mask = 0x1,
667 		.shift = 7,
668 	},
669 	.hw.init = &(struct clk_init_data){
670 		.name = "cpu_clk",
671 		.ops = &clk_regmap_mux_ops,
672 		.parent_names = (const char *[]){ "xtal",
673 						  "cpu_scale_out_sel" },
674 		.num_parents = 2,
675 		.flags = (CLK_SET_RATE_PARENT |
676 			  CLK_SET_RATE_NO_REPARENT |
677 			  CLK_IS_CRITICAL),
678 	},
679 };
680 
681 static struct clk_regmap meson8b_nand_clk_sel = {
682 	.data = &(struct clk_regmap_mux_data){
683 		.offset = HHI_NAND_CLK_CNTL,
684 		.mask = 0x7,
685 		.shift = 9,
686 		.flags = CLK_MUX_ROUND_CLOSEST,
687 	},
688 	.hw.init = &(struct clk_init_data){
689 		.name = "nand_clk_sel",
690 		.ops = &clk_regmap_mux_ops,
691 		/* FIXME all other parents are unknown: */
692 		.parent_names = (const char *[]){ "fclk_div4", "fclk_div3",
693 			"fclk_div5", "fclk_div7", "xtal" },
694 		.num_parents = 5,
695 		.flags = CLK_SET_RATE_PARENT,
696 	},
697 };
698 
699 static struct clk_regmap meson8b_nand_clk_div = {
700 	.data = &(struct clk_regmap_div_data){
701 		.offset =  HHI_NAND_CLK_CNTL,
702 		.shift = 0,
703 		.width = 7,
704 		.flags = CLK_DIVIDER_ROUND_CLOSEST,
705 	},
706 	.hw.init = &(struct clk_init_data){
707 		.name = "nand_clk_div",
708 		.ops = &clk_regmap_divider_ops,
709 		.parent_names = (const char *[]){ "nand_clk_sel" },
710 		.num_parents = 1,
711 		.flags = CLK_SET_RATE_PARENT,
712 	},
713 };
714 
715 static struct clk_regmap meson8b_nand_clk_gate = {
716 	.data = &(struct clk_regmap_gate_data){
717 		.offset = HHI_NAND_CLK_CNTL,
718 		.bit_idx = 8,
719 	},
720 	.hw.init = &(struct clk_init_data){
721 		.name = "nand_clk_gate",
722 		.ops = &clk_regmap_gate_ops,
723 		.parent_names = (const char *[]){ "nand_clk_div" },
724 		.num_parents = 1,
725 		.flags = CLK_SET_RATE_PARENT,
726 	},
727 };
728 
729 static struct clk_fixed_factor meson8b_cpu_clk_div2 = {
730 	.mult = 1,
731 	.div = 2,
732 	.hw.init = &(struct clk_init_data){
733 		.name = "cpu_clk_div2",
734 		.ops = &clk_fixed_factor_ops,
735 		.parent_names = (const char *[]){ "cpu_clk" },
736 		.num_parents = 1,
737 	},
738 };
739 
740 static struct clk_fixed_factor meson8b_cpu_clk_div3 = {
741 	.mult = 1,
742 	.div = 3,
743 	.hw.init = &(struct clk_init_data){
744 		.name = "cpu_clk_div3",
745 		.ops = &clk_fixed_factor_ops,
746 		.parent_names = (const char *[]){ "cpu_clk" },
747 		.num_parents = 1,
748 	},
749 };
750 
751 static struct clk_fixed_factor meson8b_cpu_clk_div4 = {
752 	.mult = 1,
753 	.div = 4,
754 	.hw.init = &(struct clk_init_data){
755 		.name = "cpu_clk_div4",
756 		.ops = &clk_fixed_factor_ops,
757 		.parent_names = (const char *[]){ "cpu_clk" },
758 		.num_parents = 1,
759 	},
760 };
761 
762 static struct clk_fixed_factor meson8b_cpu_clk_div5 = {
763 	.mult = 1,
764 	.div = 5,
765 	.hw.init = &(struct clk_init_data){
766 		.name = "cpu_clk_div5",
767 		.ops = &clk_fixed_factor_ops,
768 		.parent_names = (const char *[]){ "cpu_clk" },
769 		.num_parents = 1,
770 	},
771 };
772 
773 static struct clk_fixed_factor meson8b_cpu_clk_div6 = {
774 	.mult = 1,
775 	.div = 6,
776 	.hw.init = &(struct clk_init_data){
777 		.name = "cpu_clk_div6",
778 		.ops = &clk_fixed_factor_ops,
779 		.parent_names = (const char *[]){ "cpu_clk" },
780 		.num_parents = 1,
781 	},
782 };
783 
784 static struct clk_fixed_factor meson8b_cpu_clk_div7 = {
785 	.mult = 1,
786 	.div = 7,
787 	.hw.init = &(struct clk_init_data){
788 		.name = "cpu_clk_div7",
789 		.ops = &clk_fixed_factor_ops,
790 		.parent_names = (const char *[]){ "cpu_clk" },
791 		.num_parents = 1,
792 	},
793 };
794 
795 static struct clk_fixed_factor meson8b_cpu_clk_div8 = {
796 	.mult = 1,
797 	.div = 8,
798 	.hw.init = &(struct clk_init_data){
799 		.name = "cpu_clk_div8",
800 		.ops = &clk_fixed_factor_ops,
801 		.parent_names = (const char *[]){ "cpu_clk" },
802 		.num_parents = 1,
803 	},
804 };
805 
806 static u32 mux_table_abp[] = { 1, 2, 3, 4, 5, 6, 7 };
807 static struct clk_regmap meson8b_abp_clk_sel = {
808 	.data = &(struct clk_regmap_mux_data){
809 		.offset = HHI_SYS_CPU_CLK_CNTL1,
810 		.mask = 0x7,
811 		.shift = 3,
812 		.table = mux_table_abp,
813 	},
814 	.hw.init = &(struct clk_init_data){
815 		.name = "abp_clk_sel",
816 		.ops = &clk_regmap_mux_ops,
817 		.parent_names = (const char *[]){ "cpu_clk_div2",
818 						  "cpu_clk_div3",
819 						  "cpu_clk_div4",
820 						  "cpu_clk_div5",
821 						  "cpu_clk_div6",
822 						  "cpu_clk_div7",
823 						  "cpu_clk_div8", },
824 		.num_parents = 7,
825 	},
826 };
827 
828 static struct clk_regmap meson8b_abp_clk_gate = {
829 	.data = &(struct clk_regmap_gate_data){
830 		.offset = HHI_SYS_CPU_CLK_CNTL1,
831 		.bit_idx = 16,
832 		.flags = CLK_GATE_SET_TO_DISABLE,
833 	},
834 	.hw.init = &(struct clk_init_data){
835 		.name = "abp_clk_dis",
836 		.ops = &clk_regmap_gate_ro_ops,
837 		.parent_names = (const char *[]){ "abp_clk_sel" },
838 		.num_parents = 1,
839 		.flags = CLK_SET_RATE_PARENT,
840 	},
841 };
842 
843 static struct clk_regmap meson8b_periph_clk_sel = {
844 	.data = &(struct clk_regmap_mux_data){
845 		.offset = HHI_SYS_CPU_CLK_CNTL1,
846 		.mask = 0x7,
847 		.shift = 6,
848 	},
849 	.hw.init = &(struct clk_init_data){
850 		.name = "periph_clk_sel",
851 		.ops = &clk_regmap_mux_ops,
852 		.parent_names = (const char *[]){ "cpu_clk_div2",
853 						  "cpu_clk_div3",
854 						  "cpu_clk_div4",
855 						  "cpu_clk_div5",
856 						  "cpu_clk_div6",
857 						  "cpu_clk_div7",
858 						  "cpu_clk_div8", },
859 		.num_parents = 7,
860 	},
861 };
862 
863 static struct clk_regmap meson8b_periph_clk_gate = {
864 	.data = &(struct clk_regmap_gate_data){
865 		.offset = HHI_SYS_CPU_CLK_CNTL1,
866 		.bit_idx = 17,
867 		.flags = CLK_GATE_SET_TO_DISABLE,
868 	},
869 	.hw.init = &(struct clk_init_data){
870 		.name = "periph_clk_dis",
871 		.ops = &clk_regmap_gate_ro_ops,
872 		.parent_names = (const char *[]){ "periph_clk_sel" },
873 		.num_parents = 1,
874 		.flags = CLK_SET_RATE_PARENT,
875 	},
876 };
877 
878 static u32 mux_table_axi[] = { 1, 2, 3, 4, 5, 6, 7 };
879 static struct clk_regmap meson8b_axi_clk_sel = {
880 	.data = &(struct clk_regmap_mux_data){
881 		.offset = HHI_SYS_CPU_CLK_CNTL1,
882 		.mask = 0x7,
883 		.shift = 9,
884 		.table = mux_table_axi,
885 	},
886 	.hw.init = &(struct clk_init_data){
887 		.name = "axi_clk_sel",
888 		.ops = &clk_regmap_mux_ops,
889 		.parent_names = (const char *[]){ "cpu_clk_div2",
890 						  "cpu_clk_div3",
891 						  "cpu_clk_div4",
892 						  "cpu_clk_div5",
893 						  "cpu_clk_div6",
894 						  "cpu_clk_div7",
895 						  "cpu_clk_div8", },
896 		.num_parents = 7,
897 	},
898 };
899 
900 static struct clk_regmap meson8b_axi_clk_gate = {
901 	.data = &(struct clk_regmap_gate_data){
902 		.offset = HHI_SYS_CPU_CLK_CNTL1,
903 		.bit_idx = 18,
904 		.flags = CLK_GATE_SET_TO_DISABLE,
905 	},
906 	.hw.init = &(struct clk_init_data){
907 		.name = "axi_clk_dis",
908 		.ops = &clk_regmap_gate_ro_ops,
909 		.parent_names = (const char *[]){ "axi_clk_sel" },
910 		.num_parents = 1,
911 		.flags = CLK_SET_RATE_PARENT,
912 	},
913 };
914 
915 static struct clk_regmap meson8b_l2_dram_clk_sel = {
916 	.data = &(struct clk_regmap_mux_data){
917 		.offset = HHI_SYS_CPU_CLK_CNTL1,
918 		.mask = 0x7,
919 		.shift = 12,
920 	},
921 	.hw.init = &(struct clk_init_data){
922 		.name = "l2_dram_clk_sel",
923 		.ops = &clk_regmap_mux_ops,
924 		.parent_names = (const char *[]){ "cpu_clk_div2",
925 						  "cpu_clk_div3",
926 						  "cpu_clk_div4",
927 						  "cpu_clk_div5",
928 						  "cpu_clk_div6",
929 						  "cpu_clk_div7",
930 						  "cpu_clk_div8", },
931 		.num_parents = 7,
932 	},
933 };
934 
935 static struct clk_regmap meson8b_l2_dram_clk_gate = {
936 	.data = &(struct clk_regmap_gate_data){
937 		.offset = HHI_SYS_CPU_CLK_CNTL1,
938 		.bit_idx = 19,
939 		.flags = CLK_GATE_SET_TO_DISABLE,
940 	},
941 	.hw.init = &(struct clk_init_data){
942 		.name = "l2_dram_clk_dis",
943 		.ops = &clk_regmap_gate_ro_ops,
944 		.parent_names = (const char *[]){ "l2_dram_clk_sel" },
945 		.num_parents = 1,
946 		.flags = CLK_SET_RATE_PARENT,
947 	},
948 };
949 
950 static struct clk_regmap meson8b_vid_pll_in_sel = {
951 	.data = &(struct clk_regmap_mux_data){
952 		.offset = HHI_VID_DIVIDER_CNTL,
953 		.mask = 0x1,
954 		.shift = 15,
955 	},
956 	.hw.init = &(struct clk_init_data){
957 		.name = "vid_pll_in_sel",
958 		.ops = &clk_regmap_mux_ro_ops,
959 		/*
960 		 * TODO: depending on the SoC there is also a second parent:
961 		 * Meson8: unknown
962 		 * Meson8b: hdmi_pll_dco
963 		 * Meson8m2: vid2_pll
964 		 */
965 		.parent_names = (const char *[]){ "hdmi_pll_dco" },
966 		.num_parents = 1,
967 		.flags = CLK_SET_RATE_PARENT,
968 	},
969 };
970 
971 static struct clk_regmap meson8b_vid_pll_in_en = {
972 	.data = &(struct clk_regmap_gate_data){
973 		.offset = HHI_VID_DIVIDER_CNTL,
974 		.bit_idx = 16,
975 	},
976 	.hw.init = &(struct clk_init_data){
977 		.name = "vid_pll_in_en",
978 		.ops = &clk_regmap_gate_ro_ops,
979 		.parent_names = (const char *[]){ "vid_pll_in_sel" },
980 		.num_parents = 1,
981 		.flags = CLK_SET_RATE_PARENT,
982 	},
983 };
984 
985 static struct clk_regmap meson8b_vid_pll_pre_div = {
986 	.data = &(struct clk_regmap_div_data){
987 		.offset =  HHI_VID_DIVIDER_CNTL,
988 		.shift = 4,
989 		.width = 3,
990 	},
991 	.hw.init = &(struct clk_init_data){
992 		.name = "vid_pll_pre_div",
993 		.ops = &clk_regmap_divider_ro_ops,
994 		.parent_names = (const char *[]){ "vid_pll_in_en" },
995 		.num_parents = 1,
996 		.flags = CLK_SET_RATE_PARENT,
997 	},
998 };
999 
1000 static struct clk_regmap meson8b_vid_pll_post_div = {
1001 	.data = &(struct clk_regmap_div_data){
1002 		.offset =  HHI_VID_DIVIDER_CNTL,
1003 		.shift = 12,
1004 		.width = 3,
1005 	},
1006 	.hw.init = &(struct clk_init_data){
1007 		.name = "vid_pll_post_div",
1008 		.ops = &clk_regmap_divider_ro_ops,
1009 		.parent_names = (const char *[]){ "vid_pll_pre_div" },
1010 		.num_parents = 1,
1011 		.flags = CLK_SET_RATE_PARENT,
1012 	},
1013 };
1014 
1015 static struct clk_regmap meson8b_vid_pll = {
1016 	.data = &(struct clk_regmap_mux_data){
1017 		.offset = HHI_VID_DIVIDER_CNTL,
1018 		.mask = 0x3,
1019 		.shift = 8,
1020 	},
1021 	.hw.init = &(struct clk_init_data){
1022 		.name = "vid_pll",
1023 		.ops = &clk_regmap_mux_ro_ops,
1024 		/* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */
1025 		.parent_names = (const char *[]){ "vid_pll_pre_div",
1026 						  "vid_pll_post_div" },
1027 		.num_parents = 2,
1028 		.flags = CLK_SET_RATE_PARENT,
1029 	},
1030 };
1031 
1032 static struct clk_regmap meson8b_vid_pll_final_div = {
1033 	.data = &(struct clk_regmap_div_data){
1034 		.offset =  HHI_VID_CLK_DIV,
1035 		.shift = 0,
1036 		.width = 8,
1037 	},
1038 	.hw.init = &(struct clk_init_data){
1039 		.name = "vid_pll_final_div",
1040 		.ops = &clk_regmap_divider_ro_ops,
1041 		.parent_names = (const char *[]){ "vid_pll" },
1042 		.num_parents = 1,
1043 		.flags = CLK_SET_RATE_PARENT,
1044 	},
1045 };
1046 
1047 static const char * const meson8b_vclk_mux_parents[] = {
1048 	"vid_pll_final_div", "fclk_div4", "fclk_div3", "fclk_div5",
1049 	"vid_pll_final_div", "fclk_div7", "mpll1"
1050 };
1051 
1052 static struct clk_regmap meson8b_vclk_in_sel = {
1053 	.data = &(struct clk_regmap_mux_data){
1054 		.offset = HHI_VID_CLK_CNTL,
1055 		.mask = 0x7,
1056 		.shift = 16,
1057 	},
1058 	.hw.init = &(struct clk_init_data){
1059 		.name = "vclk_in_sel",
1060 		.ops = &clk_regmap_mux_ro_ops,
1061 		.parent_names = meson8b_vclk_mux_parents,
1062 		.num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents),
1063 		.flags = CLK_SET_RATE_PARENT,
1064 	},
1065 };
1066 
1067 static struct clk_regmap meson8b_vclk_in_en = {
1068 	.data = &(struct clk_regmap_gate_data){
1069 		.offset = HHI_VID_CLK_DIV,
1070 		.bit_idx = 16,
1071 	},
1072 	.hw.init = &(struct clk_init_data){
1073 		.name = "vclk_in_en",
1074 		.ops = &clk_regmap_gate_ro_ops,
1075 		.parent_names = (const char *[]){ "vclk_in_sel" },
1076 		.num_parents = 1,
1077 		.flags = CLK_SET_RATE_PARENT,
1078 	},
1079 };
1080 
1081 static struct clk_regmap meson8b_vclk_div1_gate = {
1082 	.data = &(struct clk_regmap_gate_data){
1083 		.offset = HHI_VID_CLK_DIV,
1084 		.bit_idx = 0,
1085 	},
1086 	.hw.init = &(struct clk_init_data){
1087 		.name = "vclk_div1_en",
1088 		.ops = &clk_regmap_gate_ro_ops,
1089 		.parent_names = (const char *[]){ "vclk_in_en" },
1090 		.num_parents = 1,
1091 		.flags = CLK_SET_RATE_PARENT,
1092 	},
1093 };
1094 
1095 static struct clk_fixed_factor meson8b_vclk_div2_div = {
1096 	.mult = 1,
1097 	.div = 2,
1098 	.hw.init = &(struct clk_init_data){
1099 		.name = "vclk_div2",
1100 		.ops = &clk_fixed_factor_ops,
1101 		.parent_names = (const char *[]){ "vclk_in_en" },
1102 		.num_parents = 1,
1103 		.flags = CLK_SET_RATE_PARENT,
1104 	}
1105 };
1106 
1107 static struct clk_regmap meson8b_vclk_div2_div_gate = {
1108 	.data = &(struct clk_regmap_gate_data){
1109 		.offset = HHI_VID_CLK_DIV,
1110 		.bit_idx = 1,
1111 	},
1112 	.hw.init = &(struct clk_init_data){
1113 		.name = "vclk_div2_en",
1114 		.ops = &clk_regmap_gate_ro_ops,
1115 		.parent_names = (const char *[]){ "vclk_div2" },
1116 		.num_parents = 1,
1117 		.flags = CLK_SET_RATE_PARENT,
1118 	},
1119 };
1120 
1121 static struct clk_fixed_factor meson8b_vclk_div4_div = {
1122 	.mult = 1,
1123 	.div = 4,
1124 	.hw.init = &(struct clk_init_data){
1125 		.name = "vclk_div4",
1126 		.ops = &clk_fixed_factor_ops,
1127 		.parent_names = (const char *[]){ "vclk_in_en" },
1128 		.num_parents = 1,
1129 		.flags = CLK_SET_RATE_PARENT,
1130 	}
1131 };
1132 
1133 static struct clk_regmap meson8b_vclk_div4_div_gate = {
1134 	.data = &(struct clk_regmap_gate_data){
1135 		.offset = HHI_VID_CLK_DIV,
1136 		.bit_idx = 2,
1137 	},
1138 	.hw.init = &(struct clk_init_data){
1139 		.name = "vclk_div4_en",
1140 		.ops = &clk_regmap_gate_ro_ops,
1141 		.parent_names = (const char *[]){ "vclk_div4" },
1142 		.num_parents = 1,
1143 		.flags = CLK_SET_RATE_PARENT,
1144 	},
1145 };
1146 
1147 static struct clk_fixed_factor meson8b_vclk_div6_div = {
1148 	.mult = 1,
1149 	.div = 6,
1150 	.hw.init = &(struct clk_init_data){
1151 		.name = "vclk_div6",
1152 		.ops = &clk_fixed_factor_ops,
1153 		.parent_names = (const char *[]){ "vclk_in_en" },
1154 		.num_parents = 1,
1155 		.flags = CLK_SET_RATE_PARENT,
1156 	}
1157 };
1158 
1159 static struct clk_regmap meson8b_vclk_div6_div_gate = {
1160 	.data = &(struct clk_regmap_gate_data){
1161 		.offset = HHI_VID_CLK_DIV,
1162 		.bit_idx = 3,
1163 	},
1164 	.hw.init = &(struct clk_init_data){
1165 		.name = "vclk_div6_en",
1166 		.ops = &clk_regmap_gate_ro_ops,
1167 		.parent_names = (const char *[]){ "vclk_div6" },
1168 		.num_parents = 1,
1169 		.flags = CLK_SET_RATE_PARENT,
1170 	},
1171 };
1172 
1173 static struct clk_fixed_factor meson8b_vclk_div12_div = {
1174 	.mult = 1,
1175 	.div = 12,
1176 	.hw.init = &(struct clk_init_data){
1177 		.name = "vclk_div12",
1178 		.ops = &clk_fixed_factor_ops,
1179 		.parent_names = (const char *[]){ "vclk_in_en" },
1180 		.num_parents = 1,
1181 		.flags = CLK_SET_RATE_PARENT,
1182 	}
1183 };
1184 
1185 static struct clk_regmap meson8b_vclk_div12_div_gate = {
1186 	.data = &(struct clk_regmap_gate_data){
1187 		.offset = HHI_VID_CLK_DIV,
1188 		.bit_idx = 4,
1189 	},
1190 	.hw.init = &(struct clk_init_data){
1191 		.name = "vclk_div12_en",
1192 		.ops = &clk_regmap_gate_ro_ops,
1193 		.parent_names = (const char *[]){ "vclk_div12" },
1194 		.num_parents = 1,
1195 		.flags = CLK_SET_RATE_PARENT,
1196 	},
1197 };
1198 
1199 static struct clk_regmap meson8b_vclk2_in_sel = {
1200 	.data = &(struct clk_regmap_mux_data){
1201 		.offset = HHI_VIID_CLK_CNTL,
1202 		.mask = 0x7,
1203 		.shift = 16,
1204 	},
1205 	.hw.init = &(struct clk_init_data){
1206 		.name = "vclk2_in_sel",
1207 		.ops = &clk_regmap_mux_ro_ops,
1208 		.parent_names = meson8b_vclk_mux_parents,
1209 		.num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents),
1210 		.flags = CLK_SET_RATE_PARENT,
1211 	},
1212 };
1213 
1214 static struct clk_regmap meson8b_vclk2_clk_in_en = {
1215 	.data = &(struct clk_regmap_gate_data){
1216 		.offset = HHI_VIID_CLK_DIV,
1217 		.bit_idx = 16,
1218 	},
1219 	.hw.init = &(struct clk_init_data){
1220 		.name = "vclk2_in_en",
1221 		.ops = &clk_regmap_gate_ro_ops,
1222 		.parent_names = (const char *[]){ "vclk2_in_sel" },
1223 		.num_parents = 1,
1224 		.flags = CLK_SET_RATE_PARENT,
1225 	},
1226 };
1227 
1228 static struct clk_regmap meson8b_vclk2_div1_gate = {
1229 	.data = &(struct clk_regmap_gate_data){
1230 		.offset = HHI_VIID_CLK_DIV,
1231 		.bit_idx = 0,
1232 	},
1233 	.hw.init = &(struct clk_init_data){
1234 		.name = "vclk2_div1_en",
1235 		.ops = &clk_regmap_gate_ro_ops,
1236 		.parent_names = (const char *[]){ "vclk2_in_en" },
1237 		.num_parents = 1,
1238 		.flags = CLK_SET_RATE_PARENT,
1239 	},
1240 };
1241 
1242 static struct clk_fixed_factor meson8b_vclk2_div2_div = {
1243 	.mult = 1,
1244 	.div = 2,
1245 	.hw.init = &(struct clk_init_data){
1246 		.name = "vclk2_div2",
1247 		.ops = &clk_fixed_factor_ops,
1248 		.parent_names = (const char *[]){ "vclk2_in_en" },
1249 		.num_parents = 1,
1250 		.flags = CLK_SET_RATE_PARENT,
1251 	}
1252 };
1253 
1254 static struct clk_regmap meson8b_vclk2_div2_div_gate = {
1255 	.data = &(struct clk_regmap_gate_data){
1256 		.offset = HHI_VIID_CLK_DIV,
1257 		.bit_idx = 1,
1258 	},
1259 	.hw.init = &(struct clk_init_data){
1260 		.name = "vclk2_div2_en",
1261 		.ops = &clk_regmap_gate_ro_ops,
1262 		.parent_names = (const char *[]){ "vclk2_div2" },
1263 		.num_parents = 1,
1264 		.flags = CLK_SET_RATE_PARENT,
1265 	},
1266 };
1267 
1268 static struct clk_fixed_factor meson8b_vclk2_div4_div = {
1269 	.mult = 1,
1270 	.div = 4,
1271 	.hw.init = &(struct clk_init_data){
1272 		.name = "vclk2_div4",
1273 		.ops = &clk_fixed_factor_ops,
1274 		.parent_names = (const char *[]){ "vclk2_in_en" },
1275 		.num_parents = 1,
1276 		.flags = CLK_SET_RATE_PARENT,
1277 	}
1278 };
1279 
1280 static struct clk_regmap meson8b_vclk2_div4_div_gate = {
1281 	.data = &(struct clk_regmap_gate_data){
1282 		.offset = HHI_VIID_CLK_DIV,
1283 		.bit_idx = 2,
1284 	},
1285 	.hw.init = &(struct clk_init_data){
1286 		.name = "vclk2_div4_en",
1287 		.ops = &clk_regmap_gate_ro_ops,
1288 		.parent_names = (const char *[]){ "vclk2_div4" },
1289 		.num_parents = 1,
1290 		.flags = CLK_SET_RATE_PARENT,
1291 	},
1292 };
1293 
1294 static struct clk_fixed_factor meson8b_vclk2_div6_div = {
1295 	.mult = 1,
1296 	.div = 6,
1297 	.hw.init = &(struct clk_init_data){
1298 		.name = "vclk2_div6",
1299 		.ops = &clk_fixed_factor_ops,
1300 		.parent_names = (const char *[]){ "vclk2_in_en" },
1301 		.num_parents = 1,
1302 		.flags = CLK_SET_RATE_PARENT,
1303 	}
1304 };
1305 
1306 static struct clk_regmap meson8b_vclk2_div6_div_gate = {
1307 	.data = &(struct clk_regmap_gate_data){
1308 		.offset = HHI_VIID_CLK_DIV,
1309 		.bit_idx = 3,
1310 	},
1311 	.hw.init = &(struct clk_init_data){
1312 		.name = "vclk2_div6_en",
1313 		.ops = &clk_regmap_gate_ro_ops,
1314 		.parent_names = (const char *[]){ "vclk2_div6" },
1315 		.num_parents = 1,
1316 		.flags = CLK_SET_RATE_PARENT,
1317 	},
1318 };
1319 
1320 static struct clk_fixed_factor meson8b_vclk2_div12_div = {
1321 	.mult = 1,
1322 	.div = 12,
1323 	.hw.init = &(struct clk_init_data){
1324 		.name = "vclk2_div12",
1325 		.ops = &clk_fixed_factor_ops,
1326 		.parent_names = (const char *[]){ "vclk2_in_en" },
1327 		.num_parents = 1,
1328 		.flags = CLK_SET_RATE_PARENT,
1329 	}
1330 };
1331 
1332 static struct clk_regmap meson8b_vclk2_div12_div_gate = {
1333 	.data = &(struct clk_regmap_gate_data){
1334 		.offset = HHI_VIID_CLK_DIV,
1335 		.bit_idx = 4,
1336 	},
1337 	.hw.init = &(struct clk_init_data){
1338 		.name = "vclk2_div12_en",
1339 		.ops = &clk_regmap_gate_ro_ops,
1340 		.parent_names = (const char *[]){ "vclk2_div12" },
1341 		.num_parents = 1,
1342 		.flags = CLK_SET_RATE_PARENT,
1343 	},
1344 };
1345 
1346 static const char * const meson8b_vclk_enc_mux_parents[] = {
1347 	"vclk_div1_en", "vclk_div2_en", "vclk_div4_en", "vclk_div6_en",
1348 	"vclk_div12_en",
1349 };
1350 
1351 static struct clk_regmap meson8b_cts_enct_sel = {
1352 	.data = &(struct clk_regmap_mux_data){
1353 		.offset = HHI_VID_CLK_DIV,
1354 		.mask = 0xf,
1355 		.shift = 20,
1356 	},
1357 	.hw.init = &(struct clk_init_data){
1358 		.name = "cts_enct_sel",
1359 		.ops = &clk_regmap_mux_ro_ops,
1360 		.parent_names = meson8b_vclk_enc_mux_parents,
1361 		.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
1362 		.flags = CLK_SET_RATE_PARENT,
1363 	},
1364 };
1365 
1366 static struct clk_regmap meson8b_cts_enct = {
1367 	.data = &(struct clk_regmap_gate_data){
1368 		.offset = HHI_VID_CLK_CNTL2,
1369 		.bit_idx = 1,
1370 	},
1371 	.hw.init = &(struct clk_init_data){
1372 		.name = "cts_enct",
1373 		.ops = &clk_regmap_gate_ro_ops,
1374 		.parent_names = (const char *[]){ "cts_enct_sel" },
1375 		.num_parents = 1,
1376 		.flags = CLK_SET_RATE_PARENT,
1377 	},
1378 };
1379 
1380 static struct clk_regmap meson8b_cts_encp_sel = {
1381 	.data = &(struct clk_regmap_mux_data){
1382 		.offset = HHI_VID_CLK_DIV,
1383 		.mask = 0xf,
1384 		.shift = 24,
1385 	},
1386 	.hw.init = &(struct clk_init_data){
1387 		.name = "cts_encp_sel",
1388 		.ops = &clk_regmap_mux_ro_ops,
1389 		.parent_names = meson8b_vclk_enc_mux_parents,
1390 		.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
1391 		.flags = CLK_SET_RATE_PARENT,
1392 	},
1393 };
1394 
1395 static struct clk_regmap meson8b_cts_encp = {
1396 	.data = &(struct clk_regmap_gate_data){
1397 		.offset = HHI_VID_CLK_CNTL2,
1398 		.bit_idx = 2,
1399 	},
1400 	.hw.init = &(struct clk_init_data){
1401 		.name = "cts_encp",
1402 		.ops = &clk_regmap_gate_ro_ops,
1403 		.parent_names = (const char *[]){ "cts_encp_sel" },
1404 		.num_parents = 1,
1405 		.flags = CLK_SET_RATE_PARENT,
1406 	},
1407 };
1408 
1409 static struct clk_regmap meson8b_cts_enci_sel = {
1410 	.data = &(struct clk_regmap_mux_data){
1411 		.offset = HHI_VID_CLK_DIV,
1412 		.mask = 0xf,
1413 		.shift = 28,
1414 	},
1415 	.hw.init = &(struct clk_init_data){
1416 		.name = "cts_enci_sel",
1417 		.ops = &clk_regmap_mux_ro_ops,
1418 		.parent_names = meson8b_vclk_enc_mux_parents,
1419 		.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
1420 		.flags = CLK_SET_RATE_PARENT,
1421 	},
1422 };
1423 
1424 static struct clk_regmap meson8b_cts_enci = {
1425 	.data = &(struct clk_regmap_gate_data){
1426 		.offset = HHI_VID_CLK_CNTL2,
1427 		.bit_idx = 0,
1428 	},
1429 	.hw.init = &(struct clk_init_data){
1430 		.name = "cts_enci",
1431 		.ops = &clk_regmap_gate_ro_ops,
1432 		.parent_names = (const char *[]){ "cts_enci_sel" },
1433 		.num_parents = 1,
1434 		.flags = CLK_SET_RATE_PARENT,
1435 	},
1436 };
1437 
1438 static struct clk_regmap meson8b_hdmi_tx_pixel_sel = {
1439 	.data = &(struct clk_regmap_mux_data){
1440 		.offset = HHI_HDMI_CLK_CNTL,
1441 		.mask = 0xf,
1442 		.shift = 16,
1443 	},
1444 	.hw.init = &(struct clk_init_data){
1445 		.name = "hdmi_tx_pixel_sel",
1446 		.ops = &clk_regmap_mux_ro_ops,
1447 		.parent_names = meson8b_vclk_enc_mux_parents,
1448 		.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
1449 		.flags = CLK_SET_RATE_PARENT,
1450 	},
1451 };
1452 
1453 static struct clk_regmap meson8b_hdmi_tx_pixel = {
1454 	.data = &(struct clk_regmap_gate_data){
1455 		.offset = HHI_VID_CLK_CNTL2,
1456 		.bit_idx = 5,
1457 	},
1458 	.hw.init = &(struct clk_init_data){
1459 		.name = "hdmi_tx_pixel",
1460 		.ops = &clk_regmap_gate_ro_ops,
1461 		.parent_names = (const char *[]){ "hdmi_tx_pixel_sel" },
1462 		.num_parents = 1,
1463 		.flags = CLK_SET_RATE_PARENT,
1464 	},
1465 };
1466 
1467 static const char * const meson8b_vclk2_enc_mux_parents[] = {
1468 	"vclk2_div1_en", "vclk2_div2_en", "vclk2_div4_en", "vclk2_div6_en",
1469 	"vclk2_div12_en",
1470 };
1471 
1472 static struct clk_regmap meson8b_cts_encl_sel = {
1473 	.data = &(struct clk_regmap_mux_data){
1474 		.offset = HHI_VIID_CLK_DIV,
1475 		.mask = 0xf,
1476 		.shift = 12,
1477 	},
1478 	.hw.init = &(struct clk_init_data){
1479 		.name = "cts_encl_sel",
1480 		.ops = &clk_regmap_mux_ro_ops,
1481 		.parent_names = meson8b_vclk2_enc_mux_parents,
1482 		.num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents),
1483 		.flags = CLK_SET_RATE_PARENT,
1484 	},
1485 };
1486 
1487 static struct clk_regmap meson8b_cts_encl = {
1488 	.data = &(struct clk_regmap_gate_data){
1489 		.offset = HHI_VID_CLK_CNTL2,
1490 		.bit_idx = 3,
1491 	},
1492 	.hw.init = &(struct clk_init_data){
1493 		.name = "cts_encl",
1494 		.ops = &clk_regmap_gate_ro_ops,
1495 		.parent_names = (const char *[]){ "cts_encl_sel" },
1496 		.num_parents = 1,
1497 		.flags = CLK_SET_RATE_PARENT,
1498 	},
1499 };
1500 
1501 static struct clk_regmap meson8b_cts_vdac0_sel = {
1502 	.data = &(struct clk_regmap_mux_data){
1503 		.offset = HHI_VIID_CLK_DIV,
1504 		.mask = 0xf,
1505 		.shift = 28,
1506 	},
1507 	.hw.init = &(struct clk_init_data){
1508 		.name = "cts_vdac0_sel",
1509 		.ops = &clk_regmap_mux_ro_ops,
1510 		.parent_names = meson8b_vclk2_enc_mux_parents,
1511 		.num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents),
1512 		.flags = CLK_SET_RATE_PARENT,
1513 	},
1514 };
1515 
1516 static struct clk_regmap meson8b_cts_vdac0 = {
1517 	.data = &(struct clk_regmap_gate_data){
1518 		.offset = HHI_VID_CLK_CNTL2,
1519 		.bit_idx = 4,
1520 	},
1521 	.hw.init = &(struct clk_init_data){
1522 		.name = "cts_vdac0",
1523 		.ops = &clk_regmap_gate_ro_ops,
1524 		.parent_names = (const char *[]){ "cts_vdac0_sel" },
1525 		.num_parents = 1,
1526 		.flags = CLK_SET_RATE_PARENT,
1527 	},
1528 };
1529 
1530 static struct clk_regmap meson8b_hdmi_sys_sel = {
1531 	.data = &(struct clk_regmap_mux_data){
1532 		.offset = HHI_HDMI_CLK_CNTL,
1533 		.mask = 0x3,
1534 		.shift = 9,
1535 		.flags = CLK_MUX_ROUND_CLOSEST,
1536 	},
1537 	.hw.init = &(struct clk_init_data){
1538 		.name = "hdmi_sys_sel",
1539 		.ops = &clk_regmap_mux_ro_ops,
1540 		/* FIXME: all other parents are unknown */
1541 		.parent_names = (const char *[]){ "xtal" },
1542 		.num_parents = 1,
1543 		.flags = CLK_SET_RATE_NO_REPARENT,
1544 	},
1545 };
1546 
1547 static struct clk_regmap meson8b_hdmi_sys_div = {
1548 	.data = &(struct clk_regmap_div_data){
1549 		.offset = HHI_HDMI_CLK_CNTL,
1550 		.shift = 0,
1551 		.width = 7,
1552 	},
1553 	.hw.init = &(struct clk_init_data){
1554 		.name = "hdmi_sys_div",
1555 		.ops = &clk_regmap_divider_ro_ops,
1556 		.parent_names = (const char *[]){ "hdmi_sys_sel" },
1557 		.num_parents = 1,
1558 		.flags = CLK_SET_RATE_PARENT,
1559 	},
1560 };
1561 
1562 static struct clk_regmap meson8b_hdmi_sys = {
1563 	.data = &(struct clk_regmap_gate_data){
1564 		.offset = HHI_HDMI_CLK_CNTL,
1565 		.bit_idx = 8,
1566 	},
1567 	.hw.init = &(struct clk_init_data) {
1568 		.name = "hdmi_sys",
1569 		.ops = &clk_regmap_gate_ro_ops,
1570 		.parent_names = (const char *[]){ "hdmi_sys_div" },
1571 		.num_parents = 1,
1572 		.flags = CLK_SET_RATE_PARENT,
1573 	},
1574 };
1575 
1576 /* Everything Else (EE) domain gates */
1577 
1578 static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
1579 static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1);
1580 static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5);
1581 static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6);
1582 static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7);
1583 static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8);
1584 static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9);
1585 static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10);
1586 static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11);
1587 static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12);
1588 static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13);
1589 static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14);
1590 static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15);
1591 static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16);
1592 static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17);
1593 static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18);
1594 static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19);
1595 static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23);
1596 static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30);
1597 
1598 static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2);
1599 static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3);
1600 static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4);
1601 static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6);
1602 static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7);
1603 static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8);
1604 static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9);
1605 static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10);
1606 static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11);
1607 static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12);
1608 static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13);
1609 static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14);
1610 static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15);
1611 static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16);
1612 static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20);
1613 static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21);
1614 static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22);
1615 static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23);
1616 static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24);
1617 static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25);
1618 static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26);
1619 static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28);
1620 static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29);
1621 static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30);
1622 static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31);
1623 
1624 static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1);
1625 static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
1626 static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
1627 static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4);
1628 static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
1629 static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
1630 static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11);
1631 static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12);
1632 static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15);
1633 static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22);
1634 static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25);
1635 static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
1636 static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29);
1637 
1638 static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1);
1639 static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2);
1640 static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3);
1641 static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4);
1642 static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8);
1643 static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9);
1644 static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10);
1645 static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14);
1646 static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16);
1647 static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20);
1648 static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21);
1649 static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22);
1650 static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
1651 static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25);
1652 static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26);
1653 static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31);
1654 
1655 /* Always On (AO) domain gates */
1656 
1657 static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0);
1658 static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1);
1659 static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2);
1660 static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
1661 
1662 static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
1663 	.hws = {
1664 		[CLKID_XTAL] = &meson8b_xtal.hw,
1665 		[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
1666 		[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
1667 		[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
1668 		[CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
1669 		[CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
1670 		[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
1671 		[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
1672 		[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
1673 		[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
1674 		[CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
1675 		[CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
1676 		[CLKID_CLK81] = &meson8b_clk81.hw,
1677 		[CLKID_DDR]		    = &meson8b_ddr.hw,
1678 		[CLKID_DOS]		    = &meson8b_dos.hw,
1679 		[CLKID_ISA]		    = &meson8b_isa.hw,
1680 		[CLKID_PL301]		    = &meson8b_pl301.hw,
1681 		[CLKID_PERIPHS]		    = &meson8b_periphs.hw,
1682 		[CLKID_SPICC]		    = &meson8b_spicc.hw,
1683 		[CLKID_I2C]		    = &meson8b_i2c.hw,
1684 		[CLKID_SAR_ADC]		    = &meson8b_sar_adc.hw,
1685 		[CLKID_SMART_CARD]	    = &meson8b_smart_card.hw,
1686 		[CLKID_RNG0]		    = &meson8b_rng0.hw,
1687 		[CLKID_UART0]		    = &meson8b_uart0.hw,
1688 		[CLKID_SDHC]		    = &meson8b_sdhc.hw,
1689 		[CLKID_STREAM]		    = &meson8b_stream.hw,
1690 		[CLKID_ASYNC_FIFO]	    = &meson8b_async_fifo.hw,
1691 		[CLKID_SDIO]		    = &meson8b_sdio.hw,
1692 		[CLKID_ABUF]		    = &meson8b_abuf.hw,
1693 		[CLKID_HIU_IFACE]	    = &meson8b_hiu_iface.hw,
1694 		[CLKID_ASSIST_MISC]	    = &meson8b_assist_misc.hw,
1695 		[CLKID_SPI]		    = &meson8b_spi.hw,
1696 		[CLKID_I2S_SPDIF]	    = &meson8b_i2s_spdif.hw,
1697 		[CLKID_ETH]		    = &meson8b_eth.hw,
1698 		[CLKID_DEMUX]		    = &meson8b_demux.hw,
1699 		[CLKID_AIU_GLUE]	    = &meson8b_aiu_glue.hw,
1700 		[CLKID_IEC958]		    = &meson8b_iec958.hw,
1701 		[CLKID_I2S_OUT]		    = &meson8b_i2s_out.hw,
1702 		[CLKID_AMCLK]		    = &meson8b_amclk.hw,
1703 		[CLKID_AIFIFO2]		    = &meson8b_aififo2.hw,
1704 		[CLKID_MIXER]		    = &meson8b_mixer.hw,
1705 		[CLKID_MIXER_IFACE]	    = &meson8b_mixer_iface.hw,
1706 		[CLKID_ADC]		    = &meson8b_adc.hw,
1707 		[CLKID_BLKMV]		    = &meson8b_blkmv.hw,
1708 		[CLKID_AIU]		    = &meson8b_aiu.hw,
1709 		[CLKID_UART1]		    = &meson8b_uart1.hw,
1710 		[CLKID_G2D]		    = &meson8b_g2d.hw,
1711 		[CLKID_USB0]		    = &meson8b_usb0.hw,
1712 		[CLKID_USB1]		    = &meson8b_usb1.hw,
1713 		[CLKID_RESET]		    = &meson8b_reset.hw,
1714 		[CLKID_NAND]		    = &meson8b_nand.hw,
1715 		[CLKID_DOS_PARSER]	    = &meson8b_dos_parser.hw,
1716 		[CLKID_USB]		    = &meson8b_usb.hw,
1717 		[CLKID_VDIN1]		    = &meson8b_vdin1.hw,
1718 		[CLKID_AHB_ARB0]	    = &meson8b_ahb_arb0.hw,
1719 		[CLKID_EFUSE]		    = &meson8b_efuse.hw,
1720 		[CLKID_BOOT_ROM]	    = &meson8b_boot_rom.hw,
1721 		[CLKID_AHB_DATA_BUS]	    = &meson8b_ahb_data_bus.hw,
1722 		[CLKID_AHB_CTRL_BUS]	    = &meson8b_ahb_ctrl_bus.hw,
1723 		[CLKID_HDMI_INTR_SYNC]	    = &meson8b_hdmi_intr_sync.hw,
1724 		[CLKID_HDMI_PCLK]	    = &meson8b_hdmi_pclk.hw,
1725 		[CLKID_USB1_DDR_BRIDGE]	    = &meson8b_usb1_ddr_bridge.hw,
1726 		[CLKID_USB0_DDR_BRIDGE]	    = &meson8b_usb0_ddr_bridge.hw,
1727 		[CLKID_MMC_PCLK]	    = &meson8b_mmc_pclk.hw,
1728 		[CLKID_DVIN]		    = &meson8b_dvin.hw,
1729 		[CLKID_UART2]		    = &meson8b_uart2.hw,
1730 		[CLKID_SANA]		    = &meson8b_sana.hw,
1731 		[CLKID_VPU_INTR]	    = &meson8b_vpu_intr.hw,
1732 		[CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
1733 		[CLKID_CLK81_A9]	    = &meson8b_clk81_a9.hw,
1734 		[CLKID_VCLK2_VENCI0]	    = &meson8b_vclk2_venci0.hw,
1735 		[CLKID_VCLK2_VENCI1]	    = &meson8b_vclk2_venci1.hw,
1736 		[CLKID_VCLK2_VENCP0]	    = &meson8b_vclk2_vencp0.hw,
1737 		[CLKID_VCLK2_VENCP1]	    = &meson8b_vclk2_vencp1.hw,
1738 		[CLKID_GCLK_VENCI_INT]	    = &meson8b_gclk_venci_int.hw,
1739 		[CLKID_GCLK_VENCP_INT]	    = &meson8b_gclk_vencp_int.hw,
1740 		[CLKID_DAC_CLK]		    = &meson8b_dac_clk.hw,
1741 		[CLKID_AOCLK_GATE]	    = &meson8b_aoclk_gate.hw,
1742 		[CLKID_IEC958_GATE]	    = &meson8b_iec958_gate.hw,
1743 		[CLKID_ENC480P]		    = &meson8b_enc480p.hw,
1744 		[CLKID_RNG1]		    = &meson8b_rng1.hw,
1745 		[CLKID_GCLK_VENCL_INT]	    = &meson8b_gclk_vencl_int.hw,
1746 		[CLKID_VCLK2_VENCLMCC]	    = &meson8b_vclk2_venclmcc.hw,
1747 		[CLKID_VCLK2_VENCL]	    = &meson8b_vclk2_vencl.hw,
1748 		[CLKID_VCLK2_OTHER]	    = &meson8b_vclk2_other.hw,
1749 		[CLKID_EDP]		    = &meson8b_edp.hw,
1750 		[CLKID_AO_MEDIA_CPU]	    = &meson8b_ao_media_cpu.hw,
1751 		[CLKID_AO_AHB_SRAM]	    = &meson8b_ao_ahb_sram.hw,
1752 		[CLKID_AO_AHB_BUS]	    = &meson8b_ao_ahb_bus.hw,
1753 		[CLKID_AO_IFACE]	    = &meson8b_ao_iface.hw,
1754 		[CLKID_MPLL0]		    = &meson8b_mpll0.hw,
1755 		[CLKID_MPLL1]		    = &meson8b_mpll1.hw,
1756 		[CLKID_MPLL2]		    = &meson8b_mpll2.hw,
1757 		[CLKID_MPLL0_DIV]	    = &meson8b_mpll0_div.hw,
1758 		[CLKID_MPLL1_DIV]	    = &meson8b_mpll1_div.hw,
1759 		[CLKID_MPLL2_DIV]	    = &meson8b_mpll2_div.hw,
1760 		[CLKID_CPU_IN_SEL]	    = &meson8b_cpu_in_sel.hw,
1761 		[CLKID_CPU_IN_DIV2]	    = &meson8b_cpu_in_div2.hw,
1762 		[CLKID_CPU_IN_DIV3]	    = &meson8b_cpu_in_div3.hw,
1763 		[CLKID_CPU_SCALE_DIV]	    = &meson8b_cpu_scale_div.hw,
1764 		[CLKID_CPU_SCALE_OUT_SEL]   = &meson8b_cpu_scale_out_sel.hw,
1765 		[CLKID_MPLL_PREDIV]	    = &meson8b_mpll_prediv.hw,
1766 		[CLKID_FCLK_DIV2_DIV]	    = &meson8b_fclk_div2_div.hw,
1767 		[CLKID_FCLK_DIV3_DIV]	    = &meson8b_fclk_div3_div.hw,
1768 		[CLKID_FCLK_DIV4_DIV]	    = &meson8b_fclk_div4_div.hw,
1769 		[CLKID_FCLK_DIV5_DIV]	    = &meson8b_fclk_div5_div.hw,
1770 		[CLKID_FCLK_DIV7_DIV]	    = &meson8b_fclk_div7_div.hw,
1771 		[CLKID_NAND_SEL]	    = &meson8b_nand_clk_sel.hw,
1772 		[CLKID_NAND_DIV]	    = &meson8b_nand_clk_div.hw,
1773 		[CLKID_NAND_CLK]	    = &meson8b_nand_clk_gate.hw,
1774 		[CLKID_PLL_FIXED_DCO]	    = &meson8b_fixed_pll_dco.hw,
1775 		[CLKID_HDMI_PLL_DCO]	    = &meson8b_hdmi_pll_dco.hw,
1776 		[CLKID_PLL_SYS_DCO]	    = &meson8b_sys_pll_dco.hw,
1777 		[CLKID_CPU_CLK_DIV2]	    = &meson8b_cpu_clk_div2.hw,
1778 		[CLKID_CPU_CLK_DIV3]	    = &meson8b_cpu_clk_div3.hw,
1779 		[CLKID_CPU_CLK_DIV4]	    = &meson8b_cpu_clk_div4.hw,
1780 		[CLKID_CPU_CLK_DIV5]	    = &meson8b_cpu_clk_div5.hw,
1781 		[CLKID_CPU_CLK_DIV6]	    = &meson8b_cpu_clk_div6.hw,
1782 		[CLKID_CPU_CLK_DIV7]	    = &meson8b_cpu_clk_div7.hw,
1783 		[CLKID_CPU_CLK_DIV8]	    = &meson8b_cpu_clk_div8.hw,
1784 		[CLKID_ABP_SEL]		    = &meson8b_abp_clk_sel.hw,
1785 		[CLKID_ABP]		    = &meson8b_abp_clk_gate.hw,
1786 		[CLKID_PERIPH_SEL]	    = &meson8b_periph_clk_sel.hw,
1787 		[CLKID_PERIPH]		    = &meson8b_periph_clk_gate.hw,
1788 		[CLKID_AXI_SEL]		    = &meson8b_axi_clk_sel.hw,
1789 		[CLKID_AXI]		    = &meson8b_axi_clk_gate.hw,
1790 		[CLKID_L2_DRAM_SEL]	    = &meson8b_l2_dram_clk_sel.hw,
1791 		[CLKID_L2_DRAM]		    = &meson8b_l2_dram_clk_gate.hw,
1792 		[CLKID_HDMI_PLL_LVDS_OUT]   = &meson8b_hdmi_pll_lvds_out.hw,
1793 		[CLKID_HDMI_PLL_HDMI_OUT]   = &meson8b_hdmi_pll_hdmi_out.hw,
1794 		[CLKID_VID_PLL_IN_SEL]	    = &meson8b_vid_pll_in_sel.hw,
1795 		[CLKID_VID_PLL_IN_EN]	    = &meson8b_vid_pll_in_en.hw,
1796 		[CLKID_VID_PLL_PRE_DIV]	    = &meson8b_vid_pll_pre_div.hw,
1797 		[CLKID_VID_PLL_POST_DIV]    = &meson8b_vid_pll_post_div.hw,
1798 		[CLKID_VID_PLL_FINAL_DIV]   = &meson8b_vid_pll_final_div.hw,
1799 		[CLKID_VCLK_IN_SEL]	    = &meson8b_vclk_in_sel.hw,
1800 		[CLKID_VCLK_IN_EN]	    = &meson8b_vclk_in_en.hw,
1801 		[CLKID_VCLK_DIV1]	    = &meson8b_vclk_div1_gate.hw,
1802 		[CLKID_VCLK_DIV2_DIV]	    = &meson8b_vclk_div2_div.hw,
1803 		[CLKID_VCLK_DIV2]	    = &meson8b_vclk_div2_div_gate.hw,
1804 		[CLKID_VCLK_DIV4_DIV]	    = &meson8b_vclk_div4_div.hw,
1805 		[CLKID_VCLK_DIV4]	    = &meson8b_vclk_div4_div_gate.hw,
1806 		[CLKID_VCLK_DIV6_DIV]	    = &meson8b_vclk_div6_div.hw,
1807 		[CLKID_VCLK_DIV6]	    = &meson8b_vclk_div6_div_gate.hw,
1808 		[CLKID_VCLK_DIV12_DIV]	    = &meson8b_vclk_div12_div.hw,
1809 		[CLKID_VCLK_DIV12]	    = &meson8b_vclk_div12_div_gate.hw,
1810 		[CLKID_VCLK2_IN_SEL]	    = &meson8b_vclk2_in_sel.hw,
1811 		[CLKID_VCLK2_IN_EN]	    = &meson8b_vclk2_clk_in_en.hw,
1812 		[CLKID_VCLK2_DIV1]	    = &meson8b_vclk2_div1_gate.hw,
1813 		[CLKID_VCLK2_DIV2_DIV]	    = &meson8b_vclk2_div2_div.hw,
1814 		[CLKID_VCLK2_DIV2]	    = &meson8b_vclk2_div2_div_gate.hw,
1815 		[CLKID_VCLK2_DIV4_DIV]	    = &meson8b_vclk2_div4_div.hw,
1816 		[CLKID_VCLK2_DIV4]	    = &meson8b_vclk2_div4_div_gate.hw,
1817 		[CLKID_VCLK2_DIV6_DIV]	    = &meson8b_vclk2_div6_div.hw,
1818 		[CLKID_VCLK2_DIV6]	    = &meson8b_vclk2_div6_div_gate.hw,
1819 		[CLKID_VCLK2_DIV12_DIV]	    = &meson8b_vclk2_div12_div.hw,
1820 		[CLKID_VCLK2_DIV12]	    = &meson8b_vclk2_div12_div_gate.hw,
1821 		[CLKID_CTS_ENCT_SEL]	    = &meson8b_cts_enct_sel.hw,
1822 		[CLKID_CTS_ENCT]	    = &meson8b_cts_enct.hw,
1823 		[CLKID_CTS_ENCP_SEL]	    = &meson8b_cts_encp_sel.hw,
1824 		[CLKID_CTS_ENCP]	    = &meson8b_cts_encp.hw,
1825 		[CLKID_CTS_ENCI_SEL]	    = &meson8b_cts_enci_sel.hw,
1826 		[CLKID_CTS_ENCI]	    = &meson8b_cts_enci.hw,
1827 		[CLKID_HDMI_TX_PIXEL_SEL]   = &meson8b_hdmi_tx_pixel_sel.hw,
1828 		[CLKID_HDMI_TX_PIXEL]	    = &meson8b_hdmi_tx_pixel.hw,
1829 		[CLKID_CTS_ENCL_SEL]	    = &meson8b_cts_encl_sel.hw,
1830 		[CLKID_CTS_ENCL]	    = &meson8b_cts_encl.hw,
1831 		[CLKID_CTS_VDAC0_SEL]	    = &meson8b_cts_vdac0_sel.hw,
1832 		[CLKID_CTS_VDAC0]	    = &meson8b_cts_vdac0.hw,
1833 		[CLKID_HDMI_SYS_SEL]	    = &meson8b_hdmi_sys_sel.hw,
1834 		[CLKID_HDMI_SYS_DIV]	    = &meson8b_hdmi_sys_div.hw,
1835 		[CLKID_HDMI_SYS]	    = &meson8b_hdmi_sys.hw,
1836 		[CLK_NR_CLKS]		    = NULL,
1837 	},
1838 	.num = CLK_NR_CLKS,
1839 };
1840 
1841 static struct clk_regmap *const meson8b_clk_regmaps[] = {
1842 	&meson8b_clk81,
1843 	&meson8b_ddr,
1844 	&meson8b_dos,
1845 	&meson8b_isa,
1846 	&meson8b_pl301,
1847 	&meson8b_periphs,
1848 	&meson8b_spicc,
1849 	&meson8b_i2c,
1850 	&meson8b_sar_adc,
1851 	&meson8b_smart_card,
1852 	&meson8b_rng0,
1853 	&meson8b_uart0,
1854 	&meson8b_sdhc,
1855 	&meson8b_stream,
1856 	&meson8b_async_fifo,
1857 	&meson8b_sdio,
1858 	&meson8b_abuf,
1859 	&meson8b_hiu_iface,
1860 	&meson8b_assist_misc,
1861 	&meson8b_spi,
1862 	&meson8b_i2s_spdif,
1863 	&meson8b_eth,
1864 	&meson8b_demux,
1865 	&meson8b_aiu_glue,
1866 	&meson8b_iec958,
1867 	&meson8b_i2s_out,
1868 	&meson8b_amclk,
1869 	&meson8b_aififo2,
1870 	&meson8b_mixer,
1871 	&meson8b_mixer_iface,
1872 	&meson8b_adc,
1873 	&meson8b_blkmv,
1874 	&meson8b_aiu,
1875 	&meson8b_uart1,
1876 	&meson8b_g2d,
1877 	&meson8b_usb0,
1878 	&meson8b_usb1,
1879 	&meson8b_reset,
1880 	&meson8b_nand,
1881 	&meson8b_dos_parser,
1882 	&meson8b_usb,
1883 	&meson8b_vdin1,
1884 	&meson8b_ahb_arb0,
1885 	&meson8b_efuse,
1886 	&meson8b_boot_rom,
1887 	&meson8b_ahb_data_bus,
1888 	&meson8b_ahb_ctrl_bus,
1889 	&meson8b_hdmi_intr_sync,
1890 	&meson8b_hdmi_pclk,
1891 	&meson8b_usb1_ddr_bridge,
1892 	&meson8b_usb0_ddr_bridge,
1893 	&meson8b_mmc_pclk,
1894 	&meson8b_dvin,
1895 	&meson8b_uart2,
1896 	&meson8b_sana,
1897 	&meson8b_vpu_intr,
1898 	&meson8b_sec_ahb_ahb3_bridge,
1899 	&meson8b_clk81_a9,
1900 	&meson8b_vclk2_venci0,
1901 	&meson8b_vclk2_venci1,
1902 	&meson8b_vclk2_vencp0,
1903 	&meson8b_vclk2_vencp1,
1904 	&meson8b_gclk_venci_int,
1905 	&meson8b_gclk_vencp_int,
1906 	&meson8b_dac_clk,
1907 	&meson8b_aoclk_gate,
1908 	&meson8b_iec958_gate,
1909 	&meson8b_enc480p,
1910 	&meson8b_rng1,
1911 	&meson8b_gclk_vencl_int,
1912 	&meson8b_vclk2_venclmcc,
1913 	&meson8b_vclk2_vencl,
1914 	&meson8b_vclk2_other,
1915 	&meson8b_edp,
1916 	&meson8b_ao_media_cpu,
1917 	&meson8b_ao_ahb_sram,
1918 	&meson8b_ao_ahb_bus,
1919 	&meson8b_ao_iface,
1920 	&meson8b_mpeg_clk_div,
1921 	&meson8b_mpeg_clk_sel,
1922 	&meson8b_mpll0,
1923 	&meson8b_mpll1,
1924 	&meson8b_mpll2,
1925 	&meson8b_mpll0_div,
1926 	&meson8b_mpll1_div,
1927 	&meson8b_mpll2_div,
1928 	&meson8b_fixed_pll,
1929 	&meson8b_sys_pll,
1930 	&meson8b_cpu_in_sel,
1931 	&meson8b_cpu_scale_div,
1932 	&meson8b_cpu_scale_out_sel,
1933 	&meson8b_cpu_clk,
1934 	&meson8b_mpll_prediv,
1935 	&meson8b_fclk_div2,
1936 	&meson8b_fclk_div3,
1937 	&meson8b_fclk_div4,
1938 	&meson8b_fclk_div5,
1939 	&meson8b_fclk_div7,
1940 	&meson8b_nand_clk_sel,
1941 	&meson8b_nand_clk_div,
1942 	&meson8b_nand_clk_gate,
1943 	&meson8b_fixed_pll_dco,
1944 	&meson8b_hdmi_pll_dco,
1945 	&meson8b_sys_pll_dco,
1946 	&meson8b_abp_clk_sel,
1947 	&meson8b_abp_clk_gate,
1948 	&meson8b_periph_clk_sel,
1949 	&meson8b_periph_clk_gate,
1950 	&meson8b_axi_clk_sel,
1951 	&meson8b_axi_clk_gate,
1952 	&meson8b_l2_dram_clk_sel,
1953 	&meson8b_l2_dram_clk_gate,
1954 	&meson8b_hdmi_pll_lvds_out,
1955 	&meson8b_hdmi_pll_hdmi_out,
1956 	&meson8b_vid_pll_in_sel,
1957 	&meson8b_vid_pll_in_en,
1958 	&meson8b_vid_pll_pre_div,
1959 	&meson8b_vid_pll_post_div,
1960 	&meson8b_vid_pll,
1961 	&meson8b_vid_pll_final_div,
1962 	&meson8b_vclk_in_sel,
1963 	&meson8b_vclk_in_en,
1964 	&meson8b_vclk_div1_gate,
1965 	&meson8b_vclk_div2_div_gate,
1966 	&meson8b_vclk_div4_div_gate,
1967 	&meson8b_vclk_div6_div_gate,
1968 	&meson8b_vclk_div12_div_gate,
1969 	&meson8b_vclk2_in_sel,
1970 	&meson8b_vclk2_clk_in_en,
1971 	&meson8b_vclk2_div1_gate,
1972 	&meson8b_vclk2_div2_div_gate,
1973 	&meson8b_vclk2_div4_div_gate,
1974 	&meson8b_vclk2_div6_div_gate,
1975 	&meson8b_vclk2_div12_div_gate,
1976 	&meson8b_cts_enct_sel,
1977 	&meson8b_cts_enct,
1978 	&meson8b_cts_encp_sel,
1979 	&meson8b_cts_encp,
1980 	&meson8b_cts_enci_sel,
1981 	&meson8b_cts_enci,
1982 	&meson8b_hdmi_tx_pixel_sel,
1983 	&meson8b_hdmi_tx_pixel,
1984 	&meson8b_cts_encl_sel,
1985 	&meson8b_cts_encl,
1986 	&meson8b_cts_vdac0_sel,
1987 	&meson8b_cts_vdac0,
1988 	&meson8b_hdmi_sys_sel,
1989 	&meson8b_hdmi_sys_div,
1990 	&meson8b_hdmi_sys,
1991 };
1992 
1993 static const struct meson8b_clk_reset_line {
1994 	u32 reg;
1995 	u8 bit_idx;
1996 } meson8b_clk_reset_bits[] = {
1997 	[CLKC_RESET_L2_CACHE_SOFT_RESET] = {
1998 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
1999 	},
2000 	[CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
2001 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
2002 	},
2003 	[CLKC_RESET_SCU_SOFT_RESET] = {
2004 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
2005 	},
2006 	[CLKC_RESET_CPU3_SOFT_RESET] = {
2007 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
2008 	},
2009 	[CLKC_RESET_CPU2_SOFT_RESET] = {
2010 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
2011 	},
2012 	[CLKC_RESET_CPU1_SOFT_RESET] = {
2013 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
2014 	},
2015 	[CLKC_RESET_CPU0_SOFT_RESET] = {
2016 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
2017 	},
2018 	[CLKC_RESET_A5_GLOBAL_RESET] = {
2019 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
2020 	},
2021 	[CLKC_RESET_A5_AXI_SOFT_RESET] = {
2022 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
2023 	},
2024 	[CLKC_RESET_A5_ABP_SOFT_RESET] = {
2025 		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
2026 	},
2027 	[CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
2028 		.reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
2029 	},
2030 	[CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
2031 		.reg = HHI_VID_CLK_CNTL, .bit_idx = 15
2032 	},
2033 	[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
2034 		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
2035 	},
2036 	[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
2037 		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
2038 	},
2039 	[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
2040 		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
2041 	},
2042 	[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
2043 		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
2044 	},
2045 };
2046 
2047 static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
2048 				    unsigned long id, bool assert)
2049 {
2050 	struct meson8b_clk_reset *meson8b_clk_reset =
2051 		container_of(rcdev, struct meson8b_clk_reset, reset);
2052 	unsigned long flags;
2053 	const struct meson8b_clk_reset_line *reset;
2054 
2055 	if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
2056 		return -EINVAL;
2057 
2058 	reset = &meson8b_clk_reset_bits[id];
2059 
2060 	spin_lock_irqsave(&meson_clk_lock, flags);
2061 
2062 	if (assert)
2063 		regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
2064 				   BIT(reset->bit_idx), BIT(reset->bit_idx));
2065 	else
2066 		regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
2067 				   BIT(reset->bit_idx), 0);
2068 
2069 	spin_unlock_irqrestore(&meson_clk_lock, flags);
2070 
2071 	return 0;
2072 }
2073 
2074 static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev,
2075 				     unsigned long id)
2076 {
2077 	return meson8b_clk_reset_update(rcdev, id, true);
2078 }
2079 
2080 static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev,
2081 				       unsigned long id)
2082 {
2083 	return meson8b_clk_reset_update(rcdev, id, false);
2084 }
2085 
2086 static const struct reset_control_ops meson8b_clk_reset_ops = {
2087 	.assert = meson8b_clk_reset_assert,
2088 	.deassert = meson8b_clk_reset_deassert,
2089 };
2090 
2091 struct meson8b_nb_data {
2092 	struct notifier_block nb;
2093 	struct clk_hw_onecell_data *onecell_data;
2094 };
2095 
2096 static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb,
2097 				       unsigned long event, void *data)
2098 {
2099 	struct meson8b_nb_data *nb_data =
2100 		container_of(nb, struct meson8b_nb_data, nb);
2101 	struct clk_hw **hws = nb_data->onecell_data->hws;
2102 	struct clk_hw *cpu_clk_hw, *parent_clk_hw;
2103 	struct clk *cpu_clk, *parent_clk;
2104 	int ret;
2105 
2106 	switch (event) {
2107 	case PRE_RATE_CHANGE:
2108 		parent_clk_hw = hws[CLKID_XTAL];
2109 		break;
2110 
2111 	case POST_RATE_CHANGE:
2112 		parent_clk_hw = hws[CLKID_CPU_SCALE_OUT_SEL];
2113 		break;
2114 
2115 	default:
2116 		return NOTIFY_DONE;
2117 	}
2118 
2119 	cpu_clk_hw = hws[CLKID_CPUCLK];
2120 	cpu_clk = __clk_lookup(clk_hw_get_name(cpu_clk_hw));
2121 
2122 	parent_clk = __clk_lookup(clk_hw_get_name(parent_clk_hw));
2123 
2124 	ret = clk_set_parent(cpu_clk, parent_clk);
2125 	if (ret)
2126 		return notifier_from_errno(ret);
2127 
2128 	udelay(100);
2129 
2130 	return NOTIFY_OK;
2131 }
2132 
2133 static struct meson8b_nb_data meson8b_cpu_nb_data = {
2134 	.nb.notifier_call = meson8b_cpu_clk_notifier_cb,
2135 	.onecell_data = &meson8b_hw_onecell_data,
2136 };
2137 
2138 static const struct regmap_config clkc_regmap_config = {
2139 	.reg_bits       = 32,
2140 	.val_bits       = 32,
2141 	.reg_stride     = 4,
2142 };
2143 
2144 static void __init meson8b_clkc_init(struct device_node *np)
2145 {
2146 	struct meson8b_clk_reset *rstc;
2147 	const char *notifier_clk_name;
2148 	struct clk *notifier_clk;
2149 	void __iomem *clk_base;
2150 	struct regmap *map;
2151 	int i, ret;
2152 
2153 	map = syscon_node_to_regmap(of_get_parent(np));
2154 	if (IS_ERR(map)) {
2155 		pr_info("failed to get HHI regmap - Trying obsolete regs\n");
2156 
2157 		/* Generic clocks, PLLs and some of the reset-bits */
2158 		clk_base = of_iomap(np, 1);
2159 		if (!clk_base) {
2160 			pr_err("%s: Unable to map clk base\n", __func__);
2161 			return;
2162 		}
2163 
2164 		map = regmap_init_mmio(NULL, clk_base, &clkc_regmap_config);
2165 		if (IS_ERR(map))
2166 			return;
2167 	}
2168 
2169 	rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
2170 	if (!rstc)
2171 		return;
2172 
2173 	/* Reset Controller */
2174 	rstc->regmap = map;
2175 	rstc->reset.ops = &meson8b_clk_reset_ops;
2176 	rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
2177 	rstc->reset.of_node = np;
2178 	ret = reset_controller_register(&rstc->reset);
2179 	if (ret) {
2180 		pr_err("%s: Failed to register clkc reset controller: %d\n",
2181 		       __func__, ret);
2182 		return;
2183 	}
2184 
2185 	/* Populate regmap for the regmap backed clocks */
2186 	for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
2187 		meson8b_clk_regmaps[i]->map = map;
2188 
2189 	/*
2190 	 * register all clks
2191 	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
2192 	 */
2193 	for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
2194 		/* array might be sparse */
2195 		if (!meson8b_hw_onecell_data.hws[i])
2196 			continue;
2197 
2198 		ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[i]);
2199 		if (ret)
2200 			return;
2201 	}
2202 
2203 	/*
2204 	 * FIXME we shouldn't program the muxes in notifier handlers. The
2205 	 * tricky programming sequence will be handled by the forthcoming
2206 	 * coordinated clock rates mechanism once that feature is released.
2207 	 */
2208 	notifier_clk_name = clk_hw_get_name(&meson8b_cpu_scale_out_sel.hw);
2209 	notifier_clk = __clk_lookup(notifier_clk_name);
2210 	ret = clk_notifier_register(notifier_clk, &meson8b_cpu_nb_data.nb);
2211 	if (ret) {
2212 		pr_err("%s: failed to register the CPU clock notifier\n",
2213 		       __func__);
2214 		return;
2215 	}
2216 
2217 	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
2218 				     &meson8b_hw_onecell_data);
2219 	if (ret)
2220 		pr_err("%s: failed to register clock provider\n", __func__);
2221 }
2222 
2223 CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
2224 		      meson8b_clkc_init);
2225 CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
2226 		      meson8b_clkc_init);
2227 CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
2228 		      meson8b_clkc_init);
2229