Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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, CLK_IGNORE_UNUSED },
494         { "sdio1",      "perif",        15, CLK_IGNORE_UNUSED },
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         const char *parent_names[9];
506         struct clk *clk;
507         u8 avpll_flags = 0;
508         int n;
509
510         gbase = of_iomap(np, 0);
511         if (!gbase)
512                 return;
513
514         /* overwrite default clock names with DT provided ones */
515         clk = of_clk_get_by_name(np, clk_names[REFCLK]);
516         if (!IS_ERR(clk)) {
517                 clk_names[REFCLK] = __clk_get_name(clk);
518                 clk_put(clk);
519         }
520
521         clk = of_clk_get_by_name(np, clk_names[VIDEO_EXT0]);
522         if (!IS_ERR(clk)) {
523                 clk_names[VIDEO_EXT0] = __clk_get_name(clk);
524                 clk_put(clk);
525         }
526
527         /* simple register PLLs */
528         clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
529                                    clk_names[SYSPLL], clk_names[REFCLK], 0);
530         if (IS_ERR(clk))
531                 goto bg2_fail;
532
533         clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
534                                    clk_names[MEMPLL], clk_names[REFCLK], 0);
535         if (IS_ERR(clk))
536                 goto bg2_fail;
537
538         clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
539                                    clk_names[CPUPLL], clk_names[REFCLK], 0);
540         if (IS_ERR(clk))
541                 goto bg2_fail;
542
543         if (of_device_is_compatible(np, "marvell,berlin2-global-register"))
544                 avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK;
545
546         /* audio/video VCOs */
547         clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
548                          clk_names[REFCLK], avpll_flags, 0);
549         if (IS_ERR(clk))
550                 goto bg2_fail;
551
552         for (n = 0; n < 8; n++) {
553                 clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
554                              clk_names[AVPLL_A1 + n], n, "avpll_vcoA",
555                              avpll_flags, 0);
556                 if (IS_ERR(clk))
557                         goto bg2_fail;
558         }
559
560         clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
561                                  clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK |
562                                  avpll_flags, 0);
563         if (IS_ERR(clk))
564                 goto bg2_fail;
565
566         for (n = 0; n < 8; n++) {
567                 clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
568                              clk_names[AVPLL_B1 + n], n, "avpll_vcoB",
569                              BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0);
570                 if (IS_ERR(clk))
571                         goto bg2_fail;
572         }
573
574         /* reference clock bypass switches */
575         parent_names[0] = clk_names[SYSPLL];
576         parent_names[1] = clk_names[REFCLK];
577         clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2,
578                                0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock);
579         if (IS_ERR(clk))
580                 goto bg2_fail;
581         clk_names[SYSPLL] = __clk_get_name(clk);
582
583         parent_names[0] = clk_names[MEMPLL];
584         parent_names[1] = clk_names[REFCLK];
585         clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2,
586                                0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock);
587         if (IS_ERR(clk))
588                 goto bg2_fail;
589         clk_names[MEMPLL] = __clk_get_name(clk);
590
591         parent_names[0] = clk_names[CPUPLL];
592         parent_names[1] = clk_names[REFCLK];
593         clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2,
594                                0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock);
595         if (IS_ERR(clk))
596                 goto bg2_fail;
597         clk_names[CPUPLL] = __clk_get_name(clk);
598
599         /* clock muxes */
600         parent_names[0] = clk_names[AVPLL_B3];
601         parent_names[1] = clk_names[AVPLL_A3];
602         clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
603                                0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock);
604         if (IS_ERR(clk))
605                 goto bg2_fail;
606
607         parent_names[0] = clk_names[VIDEO0_PLL];
608         parent_names[1] = clk_names[VIDEO_EXT0];
609         clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
610                                0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock);
611         if (IS_ERR(clk))
612                 goto bg2_fail;
613
614         parent_names[0] = clk_names[VIDEO1_PLL];
615         parent_names[1] = clk_names[VIDEO_EXT0];
616         clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
617                                0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock);
618         if (IS_ERR(clk))
619                 goto bg2_fail;
620
621         parent_names[0] = clk_names[AVPLL_A2];
622         parent_names[1] = clk_names[AVPLL_B2];
623         clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
624                                0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock);
625         if (IS_ERR(clk))
626                 goto bg2_fail;
627
628         parent_names[0] = clk_names[VIDEO2_PLL];
629         parent_names[1] = clk_names[VIDEO_EXT0];
630         clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
631                                0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock);
632         if (IS_ERR(clk))
633                 goto bg2_fail;
634
635         parent_names[0] = clk_names[AVPLL_B1];
636         parent_names[1] = clk_names[AVPLL_A5];
637         clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
638                                0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock);
639         if (IS_ERR(clk))
640                 goto bg2_fail;
641
642         /* clock divider cells */
643         for (n = 0; n < ARRAY_SIZE(bg2_divs); n++) {
644                 const struct berlin2_div_data *dd = &bg2_divs[n];
645                 int k;
646
647                 for (k = 0; k < dd->num_parents; k++)
648                         parent_names[k] = clk_names[dd->parent_ids[k]];
649
650                 clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
651                                 dd->name, dd->div_flags, parent_names,
652                                 dd->num_parents, dd->flags, &lock);
653         }
654
655         /* clock gate cells */
656         for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) {
657                 const struct berlin2_gate_data *gd = &bg2_gates[n];
658
659                 clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name,
660                             gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
661                             gd->bit_idx, 0, &lock);
662         }
663
664         /* twdclk is derived from cpu/3 */
665         clks[CLKID_TWD] =
666                 clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
667
668         /* check for errors on leaf clocks */
669         for (n = 0; n < MAX_CLKS; n++) {
670                 if (!IS_ERR(clks[n]))
671                         continue;
672
673                 pr_err("%s: Unable to register leaf clock %d\n",
674                        np->full_name, n);
675                 goto bg2_fail;
676         }
677
678         /* register clk-provider */
679         clk_data.clks = clks;
680         clk_data.clk_num = MAX_CLKS;
681         of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
682
683         return;
684
685 bg2_fail:
686         iounmap(gbase);
687 }
688 CLK_OF_DECLARE(berlin2_clock, "marvell,berlin2-chip-ctrl",
689                berlin2_clock_setup);
690 CLK_OF_DECLARE(berlin2cd_clock, "marvell,berlin2cd-chip-ctrl",
691                berlin2_clock_setup);