Merge branches 'clk-of-refcount', 'clk-mmio-fixed-clock', 'clk-remove-clps', 'clk...
[linux-2.6-microblaze.git] / drivers / clk / meson / meson8b.c
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);