1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2017 Broadcom
7 #include <linux/clk-provider.h>
8 #include <linux/of_device.h>
9 #include <linux/platform_device.h>
11 #include <dt-bindings/clock/bcm-sr.h>
12 #include "clk-iproc.h"
14 #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
16 #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
17 .pwr_shift = ps, .iso_shift = is }
19 #define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
21 #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
22 .p_reset_shift = prs }
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 }
28 #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
30 #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
31 .hold_shift = hs, .bypass_shift = bs }
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),
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),
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),
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),
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),
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),
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),
86 static int sr_genpll0_clk_init(struct platform_device
*pdev
)
88 iproc_pll_clk_setup(pdev
->dev
.of_node
,
89 &sr_genpll0
, NULL
, 0, sr_genpll0_clk
,
90 ARRAY_SIZE(sr_genpll0_clk
));
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),
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),
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),
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),
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),
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),
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),
145 static int sr_genpll2_clk_init(struct platform_device
*pdev
)
147 iproc_pll_clk_setup(pdev
->dev
.of_node
,
148 &sr_genpll2
, NULL
, 0, sr_genpll2_clk
,
149 ARRAY_SIZE(sr_genpll2_clk
));
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),
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),
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),
181 static void sr_genpll3_clk_init(struct device_node
*node
)
183 iproc_pll_clk_setup(node
, &sr_genpll3
, NULL
, 0, sr_genpll3_clk
,
184 ARRAY_SIZE(sr_genpll3_clk
));
186 CLK_OF_DECLARE(sr_genpll3_clk
, "brcm,sr-genpll3", sr_genpll3_clk_init
);
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),
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),
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),
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),
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),
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),
234 static int sr_genpll4_clk_init(struct platform_device
*pdev
)
236 iproc_pll_clk_setup(pdev
->dev
.of_node
,
237 &sr_genpll4
, NULL
, 0, sr_genpll4_clk
,
238 ARRAY_SIZE(sr_genpll4_clk
));
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),
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),
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),
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),
273 static int sr_genpll5_clk_init(struct platform_device
*pdev
)
275 iproc_pll_clk_setup(pdev
->dev
.of_node
,
276 &sr_genpll5
, NULL
, 0, sr_genpll5_clk
,
277 ARRAY_SIZE(sr_genpll5_clk
));
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),
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),
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),
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),
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),
318 static int sr_lcpll0_clk_init(struct platform_device
*pdev
)
320 iproc_pll_clk_setup(pdev
->dev
.of_node
,
321 &sr_lcpll0
, NULL
, 0, sr_lcpll0_clk
,
322 ARRAY_SIZE(sr_lcpll0_clk
));
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),
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),
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),
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),
357 static int sr_lcpll1_clk_init(struct platform_device
*pdev
)
359 iproc_pll_clk_setup(pdev
->dev
.of_node
,
360 &sr_lcpll1
, NULL
, 0, sr_lcpll1_clk
,
361 ARRAY_SIZE(sr_lcpll1_clk
));
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),
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),
384 static int sr_lcpll_pcie_clk_init(struct platform_device
*pdev
)
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
));
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
},
403 static int sr_clk_probe(struct platform_device
*pdev
)
405 int (*probe_func
)(struct platform_device
*);
407 probe_func
= of_device_get_match_data(&pdev
->dev
);
411 return probe_func(pdev
);
414 static struct platform_driver sr_clk_driver
= {
417 .of_match_table
= sr_clk_dt_ids
,
419 .probe
= sr_clk_probe
,
421 builtin_platform_driver(sr_clk_driver
);