gfs2: Initialize atime of I_NEW inodes
[cascardo/linux.git] / drivers / clk / berlin / bg2.c
1 /*
2  * Copyright (c) 2014 Marvell Technology Group Ltd.
3  *
4  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5  * Alexandre Belloni <alexandre.belloni@free-electrons.com>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU General Public License,
9  * version 2, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <linux/clk.h>
21 #include <linux/clk-provider.h>
22 #include <linux/kernel.h>
23 #include <linux/of.h>
24 #include <linux/of_address.h>
25 #include <linux/slab.h>
26
27 #include <dt-bindings/clock/berlin2.h>
28
29 #include "berlin2-avpll.h"
30 #include "berlin2-div.h"
31 #include "berlin2-pll.h"
32 #include "common.h"
33
34 #define REG_PINMUX0             0x0000
35 #define REG_PINMUX1             0x0004
36 #define REG_SYSPLLCTL0          0x0014
37 #define REG_SYSPLLCTL4          0x0024
38 #define REG_MEMPLLCTL0          0x0028
39 #define REG_MEMPLLCTL4          0x0038
40 #define REG_CPUPLLCTL0          0x003c
41 #define REG_CPUPLLCTL4          0x004c
42 #define REG_AVPLLCTL0           0x0050
43 #define REG_AVPLLCTL31          0x00cc
44 #define REG_AVPLLCTL62          0x0148
45 #define REG_PLLSTATUS           0x014c
46 #define REG_CLKENABLE           0x0150
47 #define REG_CLKSELECT0          0x0154
48 #define REG_CLKSELECT1          0x0158
49 #define REG_CLKSELECT2          0x015c
50 #define REG_CLKSELECT3          0x0160
51 #define REG_CLKSWITCH0          0x0164
52 #define REG_CLKSWITCH1          0x0168
53 #define REG_RESET_TRIGGER       0x0178
54 #define REG_RESET_STATUS0       0x017c
55 #define REG_RESET_STATUS1       0x0180
56 #define REG_SW_GENERIC0         0x0184
57 #define REG_SW_GENERIC3         0x0190
58 #define REG_PRODUCTID           0x01cc
59 #define REG_PRODUCTID_EXT       0x01d0
60 #define REG_GFX3DCORE_CLKCTL    0x022c
61 #define REG_GFX3DSYS_CLKCTL     0x0230
62 #define REG_ARC_CLKCTL          0x0234
63 #define REG_VIP_CLKCTL          0x0238
64 #define REG_SDIO0XIN_CLKCTL     0x023c
65 #define REG_SDIO1XIN_CLKCTL     0x0240
66 #define REG_GFX3DEXTRA_CLKCTL   0x0244
67 #define REG_GFX3D_RESET         0x0248
68 #define REG_GC360_CLKCTL        0x024c
69 #define REG_SDIO_DLLMST_CLKCTL  0x0250
70
71 /*
72  * BG2/BG2CD SoCs have the following audio/video I/O units:
73  *
74  * audiohd: HDMI TX audio
75  * audio0:  7.1ch TX
76  * audio1:  2ch TX
77  * audio2:  2ch RX
78  * audio3:  SPDIF TX
79  * video0:  HDMI video
80  * video1:  Secondary video
81  * video2:  SD auxiliary video
82  *
83  * There are no external audio clocks (ACLKI0, ACLKI1) and
84  * only one external video clock (VCLKI0).
85  *
86  * Currently missing bits and pieces:
87  * - audio_fast_pll is unknown
88  * - audiohd_pll is unknown
89  * - video0_pll is unknown
90  * - audio[023], audiohd parent pll is assumed to be audio_fast_pll
91  *
92  */
93
94 #define MAX_CLKS 41
95 static struct clk *clks[MAX_CLKS];
96 static struct clk_onecell_data clk_data;
97 static DEFINE_SPINLOCK(lock);
98 static void __iomem *gbase;
99
100 enum {
101         REFCLK, VIDEO_EXT0,
102         SYSPLL, MEMPLL, CPUPLL,
103         AVPLL_A1, AVPLL_A2, AVPLL_A3, AVPLL_A4,
104         AVPLL_A5, AVPLL_A6, AVPLL_A7, AVPLL_A8,
105         AVPLL_B1, AVPLL_B2, AVPLL_B3, AVPLL_B4,
106         AVPLL_B5, AVPLL_B6, AVPLL_B7, AVPLL_B8,
107         AUDIO1_PLL, AUDIO_FAST_PLL,
108         VIDEO0_PLL, VIDEO0_IN,
109         VIDEO1_PLL, VIDEO1_IN,
110         VIDEO2_PLL, VIDEO2_IN,
111 };
112
113 static const char *clk_names[] = {
114         [REFCLK]                = "refclk",
115         [VIDEO_EXT0]            = "video_ext0",
116         [SYSPLL]                = "syspll",
117         [MEMPLL]                = "mempll",
118         [CPUPLL]                = "cpupll",
119         [AVPLL_A1]              = "avpll_a1",
120         [AVPLL_A2]              = "avpll_a2",
121         [AVPLL_A3]              = "avpll_a3",
122         [AVPLL_A4]              = "avpll_a4",
123         [AVPLL_A5]              = "avpll_a5",
124         [AVPLL_A6]              = "avpll_a6",
125         [AVPLL_A7]              = "avpll_a7",
126         [AVPLL_A8]              = "avpll_a8",
127         [AVPLL_B1]              = "avpll_b1",
128         [AVPLL_B2]              = "avpll_b2",
129         [AVPLL_B3]              = "avpll_b3",
130         [AVPLL_B4]              = "avpll_b4",
131         [AVPLL_B5]              = "avpll_b5",
132         [AVPLL_B6]              = "avpll_b6",
133         [AVPLL_B7]              = "avpll_b7",
134         [AVPLL_B8]              = "avpll_b8",
135         [AUDIO1_PLL]            = "audio1_pll",
136         [AUDIO_FAST_PLL]        = "audio_fast_pll",
137         [VIDEO0_PLL]            = "video0_pll",
138         [VIDEO0_IN]             = "video0_in",
139         [VIDEO1_PLL]            = "video1_pll",
140         [VIDEO1_IN]             = "video1_in",
141         [VIDEO2_PLL]            = "video2_pll",
142         [VIDEO2_IN]             = "video2_in",
143 };
144
145 static const struct berlin2_pll_map bg2_pll_map __initconst = {
146         .vcodiv         = {10, 15, 20, 25, 30, 40, 50, 60, 80},
147         .mult           = 10,
148         .fbdiv_shift    = 6,
149         .rfdiv_shift    = 1,
150         .divsel_shift   = 7,
151 };
152
153 static const u8 default_parent_ids[] = {
154         SYSPLL, AVPLL_B4, AVPLL_A5, AVPLL_B6, AVPLL_B7, SYSPLL
155 };
156
157 static const struct berlin2_div_data bg2_divs[] __initconst = {
158         {
159                 .name = "sys",
160                 .parent_ids = (const u8 []){
161                         SYSPLL, AVPLL_B4, AVPLL_B5, AVPLL_B6, AVPLL_B7, SYSPLL
162                 },
163                 .num_parents = 6,
164                 .map = {
165                         BERLIN2_DIV_GATE(REG_CLKENABLE, 0),
166                         BERLIN2_PLL_SELECT(REG_CLKSELECT0, 0),
167                         BERLIN2_DIV_SELECT(REG_CLKSELECT0, 3),
168                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 3),
169                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 4),
170                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 5),
171                 },
172                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
173                 .flags = CLK_IGNORE_UNUSED,
174         },
175         {
176                 .name = "cpu",
177                 .parent_ids = (const u8 []){
178                         CPUPLL, MEMPLL, MEMPLL, MEMPLL, MEMPLL
179                 },
180                 .num_parents = 5,
181                 .map = {
182                         BERLIN2_PLL_SELECT(REG_CLKSELECT0, 6),
183                         BERLIN2_DIV_SELECT(REG_CLKSELECT0, 9),
184                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 6),
185                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 7),
186                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 8),
187                 },
188                 .div_flags = BERLIN2_DIV_HAS_MUX,
189                 .flags = 0,
190         },
191         {
192                 .name = "drmfigo",
193                 .parent_ids = default_parent_ids,
194                 .num_parents = ARRAY_SIZE(default_parent_ids),
195                 .map = {
196                         BERLIN2_DIV_GATE(REG_CLKENABLE, 16),
197                         BERLIN2_PLL_SELECT(REG_CLKSELECT0, 17),
198                         BERLIN2_DIV_SELECT(REG_CLKSELECT0, 20),
199                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 12),
200                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 13),
201                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 14),
202                 },
203                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
204                 .flags = 0,
205         },
206         {
207                 .name = "cfg",
208                 .parent_ids = default_parent_ids,
209                 .num_parents = ARRAY_SIZE(default_parent_ids),
210                 .map = {
211                         BERLIN2_DIV_GATE(REG_CLKENABLE, 1),
212                         BERLIN2_PLL_SELECT(REG_CLKSELECT0, 23),
213                         BERLIN2_DIV_SELECT(REG_CLKSELECT0, 26),
214                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 15),
215                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 16),
216                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 17),
217                 },
218                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
219                 .flags = 0,
220         },
221         {
222                 .name = "gfx",
223                 .parent_ids = default_parent_ids,
224                 .num_parents = ARRAY_SIZE(default_parent_ids),
225                 .map = {
226                         BERLIN2_DIV_GATE(REG_CLKENABLE, 4),
227                         BERLIN2_PLL_SELECT(REG_CLKSELECT0, 29),
228                         BERLIN2_DIV_SELECT(REG_CLKSELECT1, 0),
229                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 18),
230                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 19),
231                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 20),
232                 },
233                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
234                 .flags = 0,
235         },
236         {
237                 .name = "zsp",
238                 .parent_ids = default_parent_ids,
239                 .num_parents = ARRAY_SIZE(default_parent_ids),
240                 .map = {
241                         BERLIN2_DIV_GATE(REG_CLKENABLE, 5),
242                         BERLIN2_PLL_SELECT(REG_CLKSELECT1, 3),
243                         BERLIN2_DIV_SELECT(REG_CLKSELECT1, 6),
244                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 21),
245                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 22),
246                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 23),
247                 },
248                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
249                 .flags = 0,
250         },
251         {
252                 .name = "perif",
253                 .parent_ids = default_parent_ids,
254                 .num_parents = ARRAY_SIZE(default_parent_ids),
255                 .map = {
256                         BERLIN2_DIV_GATE(REG_CLKENABLE, 6),
257                         BERLIN2_PLL_SELECT(REG_CLKSELECT1, 9),
258                         BERLIN2_DIV_SELECT(REG_CLKSELECT1, 12),
259                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 24),
260                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 25),
261                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 26),
262                 },
263                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
264                 .flags = CLK_IGNORE_UNUSED,
265         },
266         {
267                 .name = "pcube",
268                 .parent_ids = default_parent_ids,
269                 .num_parents = ARRAY_SIZE(default_parent_ids),
270                 .map = {
271                         BERLIN2_DIV_GATE(REG_CLKENABLE, 2),
272                         BERLIN2_PLL_SELECT(REG_CLKSELECT1, 15),
273                         BERLIN2_DIV_SELECT(REG_CLKSELECT1, 18),
274                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 27),
275                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 28),
276                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 29),
277                 },
278                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
279                 .flags = 0,
280         },
281         {
282                 .name = "vscope",
283                 .parent_ids = default_parent_ids,
284                 .num_parents = ARRAY_SIZE(default_parent_ids),
285                 .map = {
286                         BERLIN2_DIV_GATE(REG_CLKENABLE, 3),
287                         BERLIN2_PLL_SELECT(REG_CLKSELECT1, 21),
288                         BERLIN2_DIV_SELECT(REG_CLKSELECT1, 24),
289                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 30),
290                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 31),
291                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 0),
292                 },
293                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
294                 .flags = 0,
295         },
296         {
297                 .name = "nfc_ecc",
298                 .parent_ids = default_parent_ids,
299                 .num_parents = ARRAY_SIZE(default_parent_ids),
300                 .map = {
301                         BERLIN2_DIV_GATE(REG_CLKENABLE, 18),
302                         BERLIN2_PLL_SELECT(REG_CLKSELECT1, 27),
303                         BERLIN2_DIV_SELECT(REG_CLKSELECT2, 0),
304                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 1),
305                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 2),
306                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 3),
307                 },
308                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
309                 .flags = 0,
310         },
311         {
312                 .name = "vpp",
313                 .parent_ids = default_parent_ids,
314                 .num_parents = ARRAY_SIZE(default_parent_ids),
315                 .map = {
316                         BERLIN2_DIV_GATE(REG_CLKENABLE, 21),
317                         BERLIN2_PLL_SELECT(REG_CLKSELECT2, 3),
318                         BERLIN2_DIV_SELECT(REG_CLKSELECT2, 6),
319                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 4),
320                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 5),
321                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 6),
322                 },
323                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
324                 .flags = 0,
325         },
326         {
327                 .name = "app",
328                 .parent_ids = default_parent_ids,
329                 .num_parents = ARRAY_SIZE(default_parent_ids),
330                 .map = {
331                         BERLIN2_DIV_GATE(REG_CLKENABLE, 20),
332                         BERLIN2_PLL_SELECT(REG_CLKSELECT2, 9),
333                         BERLIN2_DIV_SELECT(REG_CLKSELECT2, 12),
334                         BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 7),
335                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 8),
336                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 9),
337                 },
338                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
339                 .flags = 0,
340         },
341         {
342                 .name = "audio0",
343                 .parent_ids = (const u8 []){ AUDIO_FAST_PLL },
344                 .num_parents = 1,
345                 .map = {
346                         BERLIN2_DIV_GATE(REG_CLKENABLE, 22),
347                         BERLIN2_DIV_SELECT(REG_CLKSELECT2, 17),
348                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 10),
349                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 11),
350                 },
351                 .div_flags = BERLIN2_DIV_HAS_GATE,
352                 .flags = 0,
353         },
354         {
355                 .name = "audio2",
356                 .parent_ids = (const u8 []){ AUDIO_FAST_PLL },
357                 .num_parents = 1,
358                 .map = {
359                         BERLIN2_DIV_GATE(REG_CLKENABLE, 24),
360                         BERLIN2_DIV_SELECT(REG_CLKSELECT2, 20),
361                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 14),
362                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 15),
363                 },
364                 .div_flags = BERLIN2_DIV_HAS_GATE,
365                 .flags = 0,
366         },
367         {
368                 .name = "audio3",
369                 .parent_ids = (const u8 []){ AUDIO_FAST_PLL },
370                 .num_parents = 1,
371                 .map = {
372                         BERLIN2_DIV_GATE(REG_CLKENABLE, 25),
373                         BERLIN2_DIV_SELECT(REG_CLKSELECT2, 23),
374                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 16),
375                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 17),
376                 },
377                 .div_flags = BERLIN2_DIV_HAS_GATE,
378                 .flags = 0,
379         },
380         {
381                 .name = "audio1",
382                 .parent_ids = (const u8 []){ AUDIO1_PLL },
383                 .num_parents = 1,
384                 .map = {
385                         BERLIN2_DIV_GATE(REG_CLKENABLE, 23),
386                         BERLIN2_DIV_SELECT(REG_CLKSELECT3, 0),
387                         BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 12),
388                         BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 13),
389                 },
390                 .div_flags = BERLIN2_DIV_HAS_GATE,
391                 .flags = 0,
392         },
393         {
394                 .name = "gfx3d_core",
395                 .parent_ids = default_parent_ids,
396                 .num_parents = ARRAY_SIZE(default_parent_ids),
397                 .map = {
398                         BERLIN2_SINGLE_DIV(REG_GFX3DCORE_CLKCTL),
399                 },
400                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
401                 .flags = 0,
402         },
403         {
404                 .name = "gfx3d_sys",
405                 .parent_ids = default_parent_ids,
406                 .num_parents = ARRAY_SIZE(default_parent_ids),
407                 .map = {
408                         BERLIN2_SINGLE_DIV(REG_GFX3DSYS_CLKCTL),
409                 },
410                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
411                 .flags = 0,
412         },
413         {
414                 .name = "arc",
415                 .parent_ids = default_parent_ids,
416                 .num_parents = ARRAY_SIZE(default_parent_ids),
417                 .map = {
418                         BERLIN2_SINGLE_DIV(REG_ARC_CLKCTL),
419                 },
420                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
421                 .flags = 0,
422         },
423         {
424                 .name = "vip",
425                 .parent_ids = default_parent_ids,
426                 .num_parents = ARRAY_SIZE(default_parent_ids),
427                 .map = {
428                         BERLIN2_SINGLE_DIV(REG_VIP_CLKCTL),
429                 },
430                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
431                 .flags = 0,
432         },
433         {
434                 .name = "sdio0xin",
435                 .parent_ids = default_parent_ids,
436                 .num_parents = ARRAY_SIZE(default_parent_ids),
437                 .map = {
438                         BERLIN2_SINGLE_DIV(REG_SDIO0XIN_CLKCTL),
439                 },
440                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
441                 .flags = 0,
442         },
443         {
444                 .name = "sdio1xin",
445                 .parent_ids = default_parent_ids,
446                 .num_parents = ARRAY_SIZE(default_parent_ids),
447                 .map = {
448                         BERLIN2_SINGLE_DIV(REG_SDIO1XIN_CLKCTL),
449                 },
450                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
451                 .flags = 0,
452         },
453         {
454                 .name = "gfx3d_extra",
455                 .parent_ids = default_parent_ids,
456                 .num_parents = ARRAY_SIZE(default_parent_ids),
457                 .map = {
458                         BERLIN2_SINGLE_DIV(REG_GFX3DEXTRA_CLKCTL),
459                 },
460                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
461                 .flags = 0,
462         },
463         {
464                 .name = "gc360",
465                 .parent_ids = default_parent_ids,
466                 .num_parents = ARRAY_SIZE(default_parent_ids),
467                 .map = {
468                         BERLIN2_SINGLE_DIV(REG_GC360_CLKCTL),
469                 },
470                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
471                 .flags = 0,
472         },
473         {
474                 .name = "sdio_dllmst",
475                 .parent_ids = default_parent_ids,
476                 .num_parents = ARRAY_SIZE(default_parent_ids),
477                 .map = {
478                         BERLIN2_SINGLE_DIV(REG_SDIO_DLLMST_CLKCTL),
479                 },
480                 .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
481                 .flags = 0,
482         },
483 };
484
485 static const struct berlin2_gate_data bg2_gates[] __initconst = {
486         { "geth0",      "perif",        7 },
487         { "geth1",      "perif",        8 },
488         { "sata",       "perif",        9 },
489         { "ahbapb",     "perif",        10, CLK_IGNORE_UNUSED },
490         { "usb0",       "perif",        11 },
491         { "usb1",       "perif",        12 },
492         { "pbridge",    "perif",        13, CLK_IGNORE_UNUSED },
493         { "sdio0",      "perif",        14 },
494         { "sdio1",      "perif",        15 },
495         { "nfc",        "perif",        17 },
496         { "smemc",      "perif",        19 },
497         { "audiohd",    "audiohd_pll",  26 },
498         { "video0",     "video0_in",    27 },
499         { "video1",     "video1_in",    28 },
500         { "video2",     "video2_in",    29 },
501 };
502
503 static void __init berlin2_clock_setup(struct device_node *np)
504 {
505         struct device_node *parent_np = of_get_parent(np);
506         const char *parent_names[9];
507         struct clk *clk;
508         u8 avpll_flags = 0;
509         int n;
510
511         gbase = of_iomap(parent_np, 0);
512         if (!gbase)
513                 return;
514
515         /* overwrite default clock names with DT provided ones */
516         clk = of_clk_get_by_name(np, clk_names[REFCLK]);
517         if (!IS_ERR(clk)) {
518                 clk_names[REFCLK] = __clk_get_name(clk);
519                 clk_put(clk);
520         }
521
522         clk = of_clk_get_by_name(np, clk_names[VIDEO_EXT0]);
523         if (!IS_ERR(clk)) {
524                 clk_names[VIDEO_EXT0] = __clk_get_name(clk);
525                 clk_put(clk);
526         }
527
528         /* simple register PLLs */
529         clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
530                                    clk_names[SYSPLL], clk_names[REFCLK], 0);
531         if (IS_ERR(clk))
532                 goto bg2_fail;
533
534         clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
535                                    clk_names[MEMPLL], clk_names[REFCLK], 0);
536         if (IS_ERR(clk))
537                 goto bg2_fail;
538
539         clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
540                                    clk_names[CPUPLL], clk_names[REFCLK], 0);
541         if (IS_ERR(clk))
542                 goto bg2_fail;
543
544         if (of_device_is_compatible(np, "marvell,berlin2-global-register"))
545                 avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK;
546
547         /* audio/video VCOs */
548         clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
549                          clk_names[REFCLK], avpll_flags, 0);
550         if (IS_ERR(clk))
551                 goto bg2_fail;
552
553         for (n = 0; n < 8; n++) {
554                 clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
555                              clk_names[AVPLL_A1 + n], n, "avpll_vcoA",
556                              avpll_flags, 0);
557                 if (IS_ERR(clk))
558                         goto bg2_fail;
559         }
560
561         clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
562                                  clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK |
563                                  avpll_flags, 0);
564         if (IS_ERR(clk))
565                 goto bg2_fail;
566
567         for (n = 0; n < 8; n++) {
568                 clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
569                              clk_names[AVPLL_B1 + n], n, "avpll_vcoB",
570                              BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0);
571                 if (IS_ERR(clk))
572                         goto bg2_fail;
573         }
574
575         /* reference clock bypass switches */
576         parent_names[0] = clk_names[SYSPLL];
577         parent_names[1] = clk_names[REFCLK];
578         clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2,
579                                0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock);
580         if (IS_ERR(clk))
581                 goto bg2_fail;
582         clk_names[SYSPLL] = __clk_get_name(clk);
583
584         parent_names[0] = clk_names[MEMPLL];
585         parent_names[1] = clk_names[REFCLK];
586         clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2,
587                                0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock);
588         if (IS_ERR(clk))
589                 goto bg2_fail;
590         clk_names[MEMPLL] = __clk_get_name(clk);
591
592         parent_names[0] = clk_names[CPUPLL];
593         parent_names[1] = clk_names[REFCLK];
594         clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2,
595                                0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock);
596         if (IS_ERR(clk))
597                 goto bg2_fail;
598         clk_names[CPUPLL] = __clk_get_name(clk);
599
600         /* clock muxes */
601         parent_names[0] = clk_names[AVPLL_B3];
602         parent_names[1] = clk_names[AVPLL_A3];
603         clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
604                                0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock);
605         if (IS_ERR(clk))
606                 goto bg2_fail;
607
608         parent_names[0] = clk_names[VIDEO0_PLL];
609         parent_names[1] = clk_names[VIDEO_EXT0];
610         clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
611                                0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock);
612         if (IS_ERR(clk))
613                 goto bg2_fail;
614
615         parent_names[0] = clk_names[VIDEO1_PLL];
616         parent_names[1] = clk_names[VIDEO_EXT0];
617         clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
618                                0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock);
619         if (IS_ERR(clk))
620                 goto bg2_fail;
621
622         parent_names[0] = clk_names[AVPLL_A2];
623         parent_names[1] = clk_names[AVPLL_B2];
624         clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
625                                0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock);
626         if (IS_ERR(clk))
627                 goto bg2_fail;
628
629         parent_names[0] = clk_names[VIDEO2_PLL];
630         parent_names[1] = clk_names[VIDEO_EXT0];
631         clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
632                                0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock);
633         if (IS_ERR(clk))
634                 goto bg2_fail;
635
636         parent_names[0] = clk_names[AVPLL_B1];
637         parent_names[1] = clk_names[AVPLL_A5];
638         clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
639                                0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock);
640         if (IS_ERR(clk))
641                 goto bg2_fail;
642
643         /* clock divider cells */
644         for (n = 0; n < ARRAY_SIZE(bg2_divs); n++) {
645                 const struct berlin2_div_data *dd = &bg2_divs[n];
646                 int k;
647
648                 for (k = 0; k < dd->num_parents; k++)
649                         parent_names[k] = clk_names[dd->parent_ids[k]];
650
651                 clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
652                                 dd->name, dd->div_flags, parent_names,
653                                 dd->num_parents, dd->flags, &lock);
654         }
655
656         /* clock gate cells */
657         for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) {
658                 const struct berlin2_gate_data *gd = &bg2_gates[n];
659
660                 clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name,
661                             gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
662                             gd->bit_idx, 0, &lock);
663         }
664
665         /* twdclk is derived from cpu/3 */
666         clks[CLKID_TWD] =
667                 clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
668
669         /* check for errors on leaf clocks */
670         for (n = 0; n < MAX_CLKS; n++) {
671                 if (!IS_ERR(clks[n]))
672                         continue;
673
674                 pr_err("%s: Unable to register leaf clock %d\n",
675                        np->full_name, n);
676                 goto bg2_fail;
677         }
678
679         /* register clk-provider */
680         clk_data.clks = clks;
681         clk_data.clk_num = MAX_CLKS;
682         of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
683
684         return;
685
686 bg2_fail:
687         iounmap(gbase);
688 }
689 CLK_OF_DECLARE(berlin2_clk, "marvell,berlin2-clk",
690                berlin2_clock_setup);