Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / clk / bcm / clk-sr.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2017 Broadcom
4  */
5
6 #include <linux/err.h>
7 #include <linux/clk-provider.h>
8 #include <linux/of_device.h>
9 #include <linux/platform_device.h>
10
11 #include <dt-bindings/clock/bcm-sr.h>
12 #include "clk-iproc.h"
13
14 #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
15
16 #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
17         .pwr_shift = ps, .iso_shift = is }
18
19 #define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
20
21 #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
22         .p_reset_shift = prs }
23
24 #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \
25         .ki_shift = kis, .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, \
26         .ka_shift = kas, .ka_width = kaw }
27
28 #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
29
30 #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
31         .hold_shift = hs, .bypass_shift = bs }
32
33
34 static const struct iproc_pll_ctrl sr_genpll0 = {
35         .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
36                 IPROC_CLK_PLL_NEEDS_SW_CFG,
37         .aon = AON_VAL(0x0, 5, 1, 0),
38         .reset = RESET_VAL(0x0, 12, 11),
39         .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
40         .sw_ctrl = SW_CTRL_VAL(0x10, 31),
41         .ndiv_int = REG_VAL(0x10, 20, 10),
42         .ndiv_frac = REG_VAL(0x10, 0, 20),
43         .pdiv = REG_VAL(0x14, 0, 4),
44         .status = REG_VAL(0x30, 12, 1),
45 };
46
47 static const struct iproc_clk_ctrl sr_genpll0_clk[] = {
48         [BCM_SR_GENPLL0_125M_CLK] = {
49                 .channel = BCM_SR_GENPLL0_125M_CLK,
50                 .flags = IPROC_CLK_AON,
51                 .enable = ENABLE_VAL(0x4, 6, 0, 12),
52                 .mdiv = REG_VAL(0x18, 0, 9),
53         },
54         [BCM_SR_GENPLL0_SCR_CLK] = {
55                 .channel = BCM_SR_GENPLL0_SCR_CLK,
56                 .flags = IPROC_CLK_AON,
57                 .enable = ENABLE_VAL(0x4, 7, 1, 13),
58                 .mdiv = REG_VAL(0x18, 10, 9),
59         },
60         [BCM_SR_GENPLL0_250M_CLK] = {
61                 .channel = BCM_SR_GENPLL0_250M_CLK,
62                 .flags = IPROC_CLK_AON,
63                 .enable = ENABLE_VAL(0x4, 8, 2, 14),
64                 .mdiv = REG_VAL(0x18, 20, 9),
65         },
66         [BCM_SR_GENPLL0_PCIE_AXI_CLK] = {
67                 .channel = BCM_SR_GENPLL0_PCIE_AXI_CLK,
68                 .flags = IPROC_CLK_AON,
69                 .enable = ENABLE_VAL(0x4, 9, 3, 15),
70                 .mdiv = REG_VAL(0x1c, 0, 9),
71         },
72         [BCM_SR_GENPLL0_PAXC_AXI_X2_CLK] = {
73                 .channel = BCM_SR_GENPLL0_PAXC_AXI_X2_CLK,
74                 .flags = IPROC_CLK_AON,
75                 .enable = ENABLE_VAL(0x4, 10, 4, 16),
76                 .mdiv = REG_VAL(0x1c, 10, 9),
77         },
78         [BCM_SR_GENPLL0_PAXC_AXI_CLK] = {
79                 .channel = BCM_SR_GENPLL0_PAXC_AXI_CLK,
80                 .flags = IPROC_CLK_AON,
81                 .enable = ENABLE_VAL(0x4, 11, 5, 17),
82                 .mdiv = REG_VAL(0x1c, 20, 9),
83         },
84 };
85
86 static int sr_genpll0_clk_init(struct platform_device *pdev)
87 {
88         iproc_pll_clk_setup(pdev->dev.of_node,
89                             &sr_genpll0, NULL, 0, sr_genpll0_clk,
90                             ARRAY_SIZE(sr_genpll0_clk));
91         return 0;
92 }
93
94 static const struct iproc_pll_ctrl sr_genpll2 = {
95         .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
96                 IPROC_CLK_PLL_NEEDS_SW_CFG,
97         .aon = AON_VAL(0x0, 1, 13, 12),
98         .reset = RESET_VAL(0x0, 12, 11),
99         .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
100         .sw_ctrl = SW_CTRL_VAL(0x10, 31),
101         .ndiv_int = REG_VAL(0x10, 20, 10),
102         .ndiv_frac = REG_VAL(0x10, 0, 20),
103         .pdiv = REG_VAL(0x14, 0, 4),
104         .status = REG_VAL(0x30, 12, 1),
105 };
106
107 static const struct iproc_clk_ctrl sr_genpll2_clk[] = {
108         [BCM_SR_GENPLL2_NIC_CLK] = {
109                 .channel = BCM_SR_GENPLL2_NIC_CLK,
110                 .flags = IPROC_CLK_AON,
111                 .enable = ENABLE_VAL(0x4, 6, 0, 12),
112                 .mdiv = REG_VAL(0x18, 0, 9),
113         },
114         [BCM_SR_GENPLL2_TS_500_CLK] = {
115                 .channel = BCM_SR_GENPLL2_TS_500_CLK,
116                 .flags = IPROC_CLK_AON,
117                 .enable = ENABLE_VAL(0x4, 7, 1, 13),
118                 .mdiv = REG_VAL(0x18, 10, 9),
119         },
120         [BCM_SR_GENPLL2_125_NITRO_CLK] = {
121                 .channel = BCM_SR_GENPLL2_125_NITRO_CLK,
122                 .flags = IPROC_CLK_AON,
123                 .enable = ENABLE_VAL(0x4, 8, 2, 14),
124                 .mdiv = REG_VAL(0x18, 20, 9),
125         },
126         [BCM_SR_GENPLL2_CHIMP_CLK] = {
127                 .channel = BCM_SR_GENPLL2_CHIMP_CLK,
128                 .flags = IPROC_CLK_AON,
129                 .enable = ENABLE_VAL(0x4, 9, 3, 15),
130                 .mdiv = REG_VAL(0x1c, 0, 9),
131         },
132         [BCM_SR_GENPLL2_NIC_FLASH_CLK] = {
133                 .channel = BCM_SR_GENPLL2_NIC_FLASH_CLK,
134                 .flags = IPROC_CLK_AON,
135                 .enable = ENABLE_VAL(0x4, 10, 4, 16),
136                 .mdiv = REG_VAL(0x1c, 10, 9),
137         },
138         [BCM_SR_GENPLL2_FS4_CLK] = {
139                 .channel = BCM_SR_GENPLL2_FS4_CLK,
140                 .enable = ENABLE_VAL(0x4, 11, 5, 17),
141                 .mdiv = REG_VAL(0x1c, 20, 9),
142         },
143 };
144
145 static int sr_genpll2_clk_init(struct platform_device *pdev)
146 {
147         iproc_pll_clk_setup(pdev->dev.of_node,
148                             &sr_genpll2, NULL, 0, sr_genpll2_clk,
149                             ARRAY_SIZE(sr_genpll2_clk));
150         return 0;
151 }
152
153 static const struct iproc_pll_ctrl sr_genpll3 = {
154         .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
155                 IPROC_CLK_PLL_NEEDS_SW_CFG,
156         .aon = AON_VAL(0x0, 1, 19, 18),
157         .reset = RESET_VAL(0x0, 12, 11),
158         .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
159         .sw_ctrl = SW_CTRL_VAL(0x10, 31),
160         .ndiv_int = REG_VAL(0x10, 20, 10),
161         .ndiv_frac = REG_VAL(0x10, 0, 20),
162         .pdiv = REG_VAL(0x14, 0, 4),
163         .status = REG_VAL(0x30, 12, 1),
164 };
165
166 static const struct iproc_clk_ctrl sr_genpll3_clk[] = {
167         [BCM_SR_GENPLL3_HSLS_CLK] = {
168                 .channel = BCM_SR_GENPLL3_HSLS_CLK,
169                 .flags = IPROC_CLK_AON,
170                 .enable = ENABLE_VAL(0x4, 6, 0, 12),
171                 .mdiv = REG_VAL(0x18, 0, 9),
172         },
173         [BCM_SR_GENPLL3_SDIO_CLK] = {
174                 .channel = BCM_SR_GENPLL3_SDIO_CLK,
175                 .flags = IPROC_CLK_AON,
176                 .enable = ENABLE_VAL(0x4, 7, 1, 13),
177                 .mdiv = REG_VAL(0x18, 10, 9),
178         },
179 };
180
181 static void sr_genpll3_clk_init(struct device_node *node)
182 {
183         iproc_pll_clk_setup(node, &sr_genpll3, NULL, 0, sr_genpll3_clk,
184                             ARRAY_SIZE(sr_genpll3_clk));
185 }
186 CLK_OF_DECLARE(sr_genpll3_clk, "brcm,sr-genpll3", sr_genpll3_clk_init);
187
188 static const struct iproc_pll_ctrl sr_genpll4 = {
189         .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
190                 IPROC_CLK_PLL_NEEDS_SW_CFG,
191         .aon = AON_VAL(0x0, 1, 25, 24),
192         .reset = RESET_VAL(0x0, 12, 11),
193         .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
194         .sw_ctrl = SW_CTRL_VAL(0x10, 31),
195         .ndiv_int = REG_VAL(0x10, 20, 10),
196         .ndiv_frac = REG_VAL(0x10, 0, 20),
197         .pdiv = REG_VAL(0x14, 0, 4),
198         .status = REG_VAL(0x30, 12, 1),
199 };
200
201 static const struct iproc_clk_ctrl sr_genpll4_clk[] = {
202         [BCM_SR_GENPLL4_CCN_CLK] = {
203                 .channel = BCM_SR_GENPLL4_CCN_CLK,
204                 .flags = IPROC_CLK_AON,
205                 .enable = ENABLE_VAL(0x4, 6, 0, 12),
206                 .mdiv = REG_VAL(0x18, 0, 9),
207         },
208         [BCM_SR_GENPLL4_TPIU_PLL_CLK] = {
209                 .channel = BCM_SR_GENPLL4_TPIU_PLL_CLK,
210                 .flags = IPROC_CLK_AON,
211                 .enable = ENABLE_VAL(0x4, 7, 1, 13),
212                 .mdiv = REG_VAL(0x18, 10, 9),
213         },
214         [BCM_SR_GENPLL4_NOC_CLK] = {
215                 .channel = BCM_SR_GENPLL4_NOC_CLK,
216                 .flags = IPROC_CLK_AON,
217                 .enable = ENABLE_VAL(0x4, 8, 2, 14),
218                 .mdiv = REG_VAL(0x18, 20, 9),
219         },
220         [BCM_SR_GENPLL4_CHCLK_FS4_CLK] = {
221                 .channel = BCM_SR_GENPLL4_CHCLK_FS4_CLK,
222                 .flags = IPROC_CLK_AON,
223                 .enable = ENABLE_VAL(0x4, 9, 3, 15),
224                 .mdiv = REG_VAL(0x1c, 0, 9),
225         },
226         [BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK] = {
227                 .channel = BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK,
228                 .flags = IPROC_CLK_AON,
229                 .enable = ENABLE_VAL(0x4, 10, 4, 16),
230                 .mdiv = REG_VAL(0x1c, 10, 9),
231         },
232 };
233
234 static int sr_genpll4_clk_init(struct platform_device *pdev)
235 {
236         iproc_pll_clk_setup(pdev->dev.of_node,
237                             &sr_genpll4, NULL, 0, sr_genpll4_clk,
238                             ARRAY_SIZE(sr_genpll4_clk));
239         return 0;
240 }
241
242 static const struct iproc_pll_ctrl sr_genpll5 = {
243         .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
244                 IPROC_CLK_PLL_NEEDS_SW_CFG,
245         .aon = AON_VAL(0x0, 1, 1, 0),
246         .reset = RESET_VAL(0x0, 12, 11),
247         .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
248         .sw_ctrl = SW_CTRL_VAL(0x10, 31),
249         .ndiv_int = REG_VAL(0x10, 20, 10),
250         .ndiv_frac = REG_VAL(0x10, 0, 20),
251         .pdiv = REG_VAL(0x14, 0, 4),
252         .status = REG_VAL(0x30, 12, 1),
253 };
254
255 static const struct iproc_clk_ctrl sr_genpll5_clk[] = {
256         [BCM_SR_GENPLL5_FS4_HF_CLK] = {
257                 .channel = BCM_SR_GENPLL5_FS4_HF_CLK,
258                 .enable = ENABLE_VAL(0x4, 6, 0, 12),
259                 .mdiv = REG_VAL(0x18, 0, 9),
260         },
261         [BCM_SR_GENPLL5_CRYPTO_AE_CLK] = {
262                 .channel = BCM_SR_GENPLL5_CRYPTO_AE_CLK,
263                 .enable = ENABLE_VAL(0x4, 7, 1, 12),
264                 .mdiv = REG_VAL(0x18, 10, 9),
265         },
266         [BCM_SR_GENPLL5_RAID_AE_CLK] = {
267                 .channel = BCM_SR_GENPLL5_RAID_AE_CLK,
268                 .enable = ENABLE_VAL(0x4, 8, 2, 14),
269                 .mdiv = REG_VAL(0x18, 20, 9),
270         },
271 };
272
273 static int sr_genpll5_clk_init(struct platform_device *pdev)
274 {
275         iproc_pll_clk_setup(pdev->dev.of_node,
276                             &sr_genpll5, NULL, 0, sr_genpll5_clk,
277                             ARRAY_SIZE(sr_genpll5_clk));
278         return 0;
279 }
280
281 static const struct iproc_pll_ctrl sr_lcpll0 = {
282         .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
283         .aon = AON_VAL(0x0, 2, 19, 18),
284         .reset = RESET_VAL(0x0, 31, 30),
285         .sw_ctrl = SW_CTRL_VAL(0x4, 31),
286         .ndiv_int = REG_VAL(0x4, 16, 10),
287         .pdiv = REG_VAL(0x4, 26, 4),
288         .status = REG_VAL(0x38, 12, 1),
289 };
290
291 static const struct iproc_clk_ctrl sr_lcpll0_clk[] = {
292         [BCM_SR_LCPLL0_SATA_REFP_CLK] = {
293                 .channel = BCM_SR_LCPLL0_SATA_REFP_CLK,
294                 .flags = IPROC_CLK_AON,
295                 .enable = ENABLE_VAL(0x0, 7, 1, 13),
296                 .mdiv = REG_VAL(0x14, 0, 9),
297         },
298         [BCM_SR_LCPLL0_SATA_REFN_CLK] = {
299                 .channel = BCM_SR_LCPLL0_SATA_REFN_CLK,
300                 .flags = IPROC_CLK_AON,
301                 .enable = ENABLE_VAL(0x0, 8, 2, 14),
302                 .mdiv = REG_VAL(0x14, 10, 9),
303         },
304         [BCM_SR_LCPLL0_SATA_350_CLK] = {
305                 .channel = BCM_SR_LCPLL0_SATA_350_CLK,
306                 .flags = IPROC_CLK_AON,
307                 .enable = ENABLE_VAL(0x0, 9, 3, 15),
308                 .mdiv = REG_VAL(0x14, 20, 9),
309         },
310         [BCM_SR_LCPLL0_SATA_500_CLK] = {
311                 .channel = BCM_SR_LCPLL0_SATA_500_CLK,
312                 .flags = IPROC_CLK_AON,
313                 .enable = ENABLE_VAL(0x0, 10, 4, 16),
314                 .mdiv = REG_VAL(0x18, 0, 9),
315         },
316 };
317
318 static int sr_lcpll0_clk_init(struct platform_device *pdev)
319 {
320         iproc_pll_clk_setup(pdev->dev.of_node,
321                             &sr_lcpll0, NULL, 0, sr_lcpll0_clk,
322                             ARRAY_SIZE(sr_lcpll0_clk));
323         return 0;
324 }
325
326 static const struct iproc_pll_ctrl sr_lcpll1 = {
327         .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
328         .aon = AON_VAL(0x0, 2, 22, 21),
329         .reset = RESET_VAL(0x0, 31, 30),
330         .sw_ctrl = SW_CTRL_VAL(0x4, 31),
331         .ndiv_int = REG_VAL(0x4, 16, 10),
332         .pdiv = REG_VAL(0x4, 26, 4),
333         .status = REG_VAL(0x38, 12, 1),
334 };
335
336 static const struct iproc_clk_ctrl sr_lcpll1_clk[] = {
337         [BCM_SR_LCPLL1_WAN_CLK] = {
338                 .channel = BCM_SR_LCPLL1_WAN_CLK,
339                 .flags = IPROC_CLK_AON,
340                 .enable = ENABLE_VAL(0x0, 7, 1, 13),
341                 .mdiv = REG_VAL(0x14, 0, 9),
342         },
343         [BCM_SR_LCPLL1_USB_REF_CLK] = {
344                 .channel = BCM_SR_LCPLL1_USB_REF_CLK,
345                 .flags = IPROC_CLK_AON,
346                 .enable = ENABLE_VAL(0x0, 8, 2, 14),
347                 .mdiv = REG_VAL(0x14, 10, 9),
348         },
349         [BCM_SR_LCPLL1_CRMU_TS_CLK] = {
350                 .channel = BCM_SR_LCPLL1_CRMU_TS_CLK,
351                 .flags = IPROC_CLK_AON,
352                 .enable = ENABLE_VAL(0x0, 9, 3, 15),
353                 .mdiv = REG_VAL(0x14, 20, 9),
354         },
355 };
356
357 static int sr_lcpll1_clk_init(struct platform_device *pdev)
358 {
359         iproc_pll_clk_setup(pdev->dev.of_node,
360                             &sr_lcpll1, NULL, 0, sr_lcpll1_clk,
361                             ARRAY_SIZE(sr_lcpll1_clk));
362         return 0;
363 }
364
365 static const struct iproc_pll_ctrl sr_lcpll_pcie = {
366         .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
367         .aon = AON_VAL(0x0, 2, 25, 24),
368         .reset = RESET_VAL(0x0, 31, 30),
369         .sw_ctrl = SW_CTRL_VAL(0x4, 31),
370         .ndiv_int = REG_VAL(0x4, 16, 10),
371         .pdiv = REG_VAL(0x4, 26, 4),
372         .status = REG_VAL(0x38, 12, 1),
373 };
374
375 static const struct iproc_clk_ctrl sr_lcpll_pcie_clk[] = {
376         [BCM_SR_LCPLL_PCIE_PHY_REF_CLK] = {
377                 .channel = BCM_SR_LCPLL_PCIE_PHY_REF_CLK,
378                 .flags = IPROC_CLK_AON,
379                 .enable = ENABLE_VAL(0x0, 7, 1, 13),
380                 .mdiv = REG_VAL(0x14, 0, 9),
381         },
382 };
383
384 static int sr_lcpll_pcie_clk_init(struct platform_device *pdev)
385 {
386         iproc_pll_clk_setup(pdev->dev.of_node,
387                             &sr_lcpll_pcie, NULL, 0, sr_lcpll_pcie_clk,
388                             ARRAY_SIZE(sr_lcpll_pcie_clk));
389         return 0;
390 }
391
392 static const struct of_device_id sr_clk_dt_ids[] = {
393         { .compatible = "brcm,sr-genpll0", .data = sr_genpll0_clk_init },
394         { .compatible = "brcm,sr-genpll2", .data = sr_genpll2_clk_init },
395         { .compatible = "brcm,sr-genpll4", .data = sr_genpll4_clk_init },
396         { .compatible = "brcm,sr-genpll5", .data = sr_genpll5_clk_init },
397         { .compatible = "brcm,sr-lcpll0", .data = sr_lcpll0_clk_init },
398         { .compatible = "brcm,sr-lcpll1", .data = sr_lcpll1_clk_init },
399         { .compatible = "brcm,sr-lcpll-pcie", .data = sr_lcpll_pcie_clk_init },
400         { /* sentinel */ }
401 };
402
403 static int sr_clk_probe(struct platform_device *pdev)
404 {
405         int (*probe_func)(struct platform_device *);
406
407         probe_func = of_device_get_match_data(&pdev->dev);
408         if (!probe_func)
409                 return -ENODEV;
410
411         return probe_func(pdev);
412 }
413
414 static struct platform_driver sr_clk_driver = {
415         .driver = {
416                 .name = "sr-clk",
417                 .of_match_table = sr_clk_dt_ids,
418         },
419         .probe = sr_clk_probe,
420 };
421 builtin_platform_driver(sr_clk_driver);