1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun #include <linux/clk-provider.h>
4*4882a593Smuzhiyun #include <linux/init.h>
5*4882a593Smuzhiyun #include <linux/of.h>
6*4882a593Smuzhiyun #include <linux/of_device.h>
7*4882a593Smuzhiyun #include <linux/platform_device.h>
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <dt-bindings/clock/bcm3368-clock.h>
10*4882a593Smuzhiyun #include <dt-bindings/clock/bcm6318-clock.h>
11*4882a593Smuzhiyun #include <dt-bindings/clock/bcm6328-clock.h>
12*4882a593Smuzhiyun #include <dt-bindings/clock/bcm6358-clock.h>
13*4882a593Smuzhiyun #include <dt-bindings/clock/bcm6362-clock.h>
14*4882a593Smuzhiyun #include <dt-bindings/clock/bcm6368-clock.h>
15*4882a593Smuzhiyun #include <dt-bindings/clock/bcm63268-clock.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun struct clk_bcm63xx_table_entry {
18*4882a593Smuzhiyun const char * const name;
19*4882a593Smuzhiyun u8 bit;
20*4882a593Smuzhiyun unsigned long flags;
21*4882a593Smuzhiyun };
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun struct clk_bcm63xx_hw {
24*4882a593Smuzhiyun void __iomem *regs;
25*4882a593Smuzhiyun spinlock_t lock;
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun struct clk_hw_onecell_data data;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun static const struct clk_bcm63xx_table_entry bcm3368_clocks[] = {
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun .name = "mac",
33*4882a593Smuzhiyun .bit = BCM3368_CLK_MAC,
34*4882a593Smuzhiyun }, {
35*4882a593Smuzhiyun .name = "tc",
36*4882a593Smuzhiyun .bit = BCM3368_CLK_TC,
37*4882a593Smuzhiyun }, {
38*4882a593Smuzhiyun .name = "us_top",
39*4882a593Smuzhiyun .bit = BCM3368_CLK_US_TOP,
40*4882a593Smuzhiyun }, {
41*4882a593Smuzhiyun .name = "ds_top",
42*4882a593Smuzhiyun .bit = BCM3368_CLK_DS_TOP,
43*4882a593Smuzhiyun }, {
44*4882a593Smuzhiyun .name = "acm",
45*4882a593Smuzhiyun .bit = BCM3368_CLK_ACM,
46*4882a593Smuzhiyun }, {
47*4882a593Smuzhiyun .name = "spi",
48*4882a593Smuzhiyun .bit = BCM3368_CLK_SPI,
49*4882a593Smuzhiyun }, {
50*4882a593Smuzhiyun .name = "usbs",
51*4882a593Smuzhiyun .bit = BCM3368_CLK_USBS,
52*4882a593Smuzhiyun }, {
53*4882a593Smuzhiyun .name = "bmu",
54*4882a593Smuzhiyun .bit = BCM3368_CLK_BMU,
55*4882a593Smuzhiyun }, {
56*4882a593Smuzhiyun .name = "pcm",
57*4882a593Smuzhiyun .bit = BCM3368_CLK_PCM,
58*4882a593Smuzhiyun }, {
59*4882a593Smuzhiyun .name = "ntp",
60*4882a593Smuzhiyun .bit = BCM3368_CLK_NTP,
61*4882a593Smuzhiyun }, {
62*4882a593Smuzhiyun .name = "acp_b",
63*4882a593Smuzhiyun .bit = BCM3368_CLK_ACP_B,
64*4882a593Smuzhiyun }, {
65*4882a593Smuzhiyun .name = "acp_a",
66*4882a593Smuzhiyun .bit = BCM3368_CLK_ACP_A,
67*4882a593Smuzhiyun }, {
68*4882a593Smuzhiyun .name = "emusb",
69*4882a593Smuzhiyun .bit = BCM3368_CLK_EMUSB,
70*4882a593Smuzhiyun }, {
71*4882a593Smuzhiyun .name = "enet0",
72*4882a593Smuzhiyun .bit = BCM3368_CLK_ENET0,
73*4882a593Smuzhiyun }, {
74*4882a593Smuzhiyun .name = "enet1",
75*4882a593Smuzhiyun .bit = BCM3368_CLK_ENET1,
76*4882a593Smuzhiyun }, {
77*4882a593Smuzhiyun .name = "usbsu",
78*4882a593Smuzhiyun .bit = BCM3368_CLK_USBSU,
79*4882a593Smuzhiyun }, {
80*4882a593Smuzhiyun .name = "ephy",
81*4882a593Smuzhiyun .bit = BCM3368_CLK_EPHY,
82*4882a593Smuzhiyun }, {
83*4882a593Smuzhiyun /* sentinel */
84*4882a593Smuzhiyun },
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun static const struct clk_bcm63xx_table_entry bcm6318_clocks[] = {
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun .name = "adsl_asb",
90*4882a593Smuzhiyun .bit = BCM6318_CLK_ADSL_ASB,
91*4882a593Smuzhiyun }, {
92*4882a593Smuzhiyun .name = "usb_asb",
93*4882a593Smuzhiyun .bit = BCM6318_CLK_USB_ASB,
94*4882a593Smuzhiyun }, {
95*4882a593Smuzhiyun .name = "mips_asb",
96*4882a593Smuzhiyun .bit = BCM6318_CLK_MIPS_ASB,
97*4882a593Smuzhiyun }, {
98*4882a593Smuzhiyun .name = "pcie_asb",
99*4882a593Smuzhiyun .bit = BCM6318_CLK_PCIE_ASB,
100*4882a593Smuzhiyun }, {
101*4882a593Smuzhiyun .name = "phymips_asb",
102*4882a593Smuzhiyun .bit = BCM6318_CLK_PHYMIPS_ASB,
103*4882a593Smuzhiyun }, {
104*4882a593Smuzhiyun .name = "robosw_asb",
105*4882a593Smuzhiyun .bit = BCM6318_CLK_ROBOSW_ASB,
106*4882a593Smuzhiyun }, {
107*4882a593Smuzhiyun .name = "sar_asb",
108*4882a593Smuzhiyun .bit = BCM6318_CLK_SAR_ASB,
109*4882a593Smuzhiyun }, {
110*4882a593Smuzhiyun .name = "sdr_asb",
111*4882a593Smuzhiyun .bit = BCM6318_CLK_SDR_ASB,
112*4882a593Smuzhiyun }, {
113*4882a593Smuzhiyun .name = "swreg_asb",
114*4882a593Smuzhiyun .bit = BCM6318_CLK_SWREG_ASB,
115*4882a593Smuzhiyun }, {
116*4882a593Smuzhiyun .name = "periph_asb",
117*4882a593Smuzhiyun .bit = BCM6318_CLK_PERIPH_ASB,
118*4882a593Smuzhiyun }, {
119*4882a593Smuzhiyun .name = "cpubus160",
120*4882a593Smuzhiyun .bit = BCM6318_CLK_CPUBUS160,
121*4882a593Smuzhiyun }, {
122*4882a593Smuzhiyun .name = "adsl",
123*4882a593Smuzhiyun .bit = BCM6318_CLK_ADSL,
124*4882a593Smuzhiyun }, {
125*4882a593Smuzhiyun .name = "sar125",
126*4882a593Smuzhiyun .bit = BCM6318_CLK_SAR125,
127*4882a593Smuzhiyun }, {
128*4882a593Smuzhiyun .name = "mips",
129*4882a593Smuzhiyun .bit = BCM6318_CLK_MIPS,
130*4882a593Smuzhiyun .flags = CLK_IS_CRITICAL,
131*4882a593Smuzhiyun }, {
132*4882a593Smuzhiyun .name = "pcie",
133*4882a593Smuzhiyun .bit = BCM6318_CLK_PCIE,
134*4882a593Smuzhiyun }, {
135*4882a593Smuzhiyun .name = "robosw250",
136*4882a593Smuzhiyun .bit = BCM6318_CLK_ROBOSW250,
137*4882a593Smuzhiyun }, {
138*4882a593Smuzhiyun .name = "robosw025",
139*4882a593Smuzhiyun .bit = BCM6318_CLK_ROBOSW025,
140*4882a593Smuzhiyun }, {
141*4882a593Smuzhiyun .name = "sdr",
142*4882a593Smuzhiyun .bit = BCM6318_CLK_SDR,
143*4882a593Smuzhiyun .flags = CLK_IS_CRITICAL,
144*4882a593Smuzhiyun }, {
145*4882a593Smuzhiyun .name = "usbd",
146*4882a593Smuzhiyun .bit = BCM6318_CLK_USBD,
147*4882a593Smuzhiyun }, {
148*4882a593Smuzhiyun .name = "hsspi",
149*4882a593Smuzhiyun .bit = BCM6318_CLK_HSSPI,
150*4882a593Smuzhiyun }, {
151*4882a593Smuzhiyun .name = "pcie25",
152*4882a593Smuzhiyun .bit = BCM6318_CLK_PCIE25,
153*4882a593Smuzhiyun }, {
154*4882a593Smuzhiyun .name = "phymips",
155*4882a593Smuzhiyun .bit = BCM6318_CLK_PHYMIPS,
156*4882a593Smuzhiyun }, {
157*4882a593Smuzhiyun .name = "afe",
158*4882a593Smuzhiyun .bit = BCM6318_CLK_AFE,
159*4882a593Smuzhiyun }, {
160*4882a593Smuzhiyun .name = "qproc",
161*4882a593Smuzhiyun .bit = BCM6318_CLK_QPROC,
162*4882a593Smuzhiyun }, {
163*4882a593Smuzhiyun /* sentinel */
164*4882a593Smuzhiyun },
165*4882a593Smuzhiyun };
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun static const struct clk_bcm63xx_table_entry bcm6318_ubus_clocks[] = {
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun .name = "adsl-ubus",
170*4882a593Smuzhiyun .bit = BCM6318_UCLK_ADSL,
171*4882a593Smuzhiyun }, {
172*4882a593Smuzhiyun .name = "arb-ubus",
173*4882a593Smuzhiyun .bit = BCM6318_UCLK_ARB,
174*4882a593Smuzhiyun .flags = CLK_IS_CRITICAL,
175*4882a593Smuzhiyun }, {
176*4882a593Smuzhiyun .name = "mips-ubus",
177*4882a593Smuzhiyun .bit = BCM6318_UCLK_MIPS,
178*4882a593Smuzhiyun .flags = CLK_IS_CRITICAL,
179*4882a593Smuzhiyun }, {
180*4882a593Smuzhiyun .name = "pcie-ubus",
181*4882a593Smuzhiyun .bit = BCM6318_UCLK_PCIE,
182*4882a593Smuzhiyun }, {
183*4882a593Smuzhiyun .name = "periph-ubus",
184*4882a593Smuzhiyun .bit = BCM6318_UCLK_PERIPH,
185*4882a593Smuzhiyun .flags = CLK_IS_CRITICAL,
186*4882a593Smuzhiyun }, {
187*4882a593Smuzhiyun .name = "phymips-ubus",
188*4882a593Smuzhiyun .bit = BCM6318_UCLK_PHYMIPS,
189*4882a593Smuzhiyun }, {
190*4882a593Smuzhiyun .name = "robosw-ubus",
191*4882a593Smuzhiyun .bit = BCM6318_UCLK_ROBOSW,
192*4882a593Smuzhiyun }, {
193*4882a593Smuzhiyun .name = "sar-ubus",
194*4882a593Smuzhiyun .bit = BCM6318_UCLK_SAR,
195*4882a593Smuzhiyun }, {
196*4882a593Smuzhiyun .name = "sdr-ubus",
197*4882a593Smuzhiyun .bit = BCM6318_UCLK_SDR,
198*4882a593Smuzhiyun }, {
199*4882a593Smuzhiyun .name = "usb-ubus",
200*4882a593Smuzhiyun .bit = BCM6318_UCLK_USB,
201*4882a593Smuzhiyun }, {
202*4882a593Smuzhiyun /* sentinel */
203*4882a593Smuzhiyun },
204*4882a593Smuzhiyun };
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun static const struct clk_bcm63xx_table_entry bcm6328_clocks[] = {
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun .name = "phy_mips",
209*4882a593Smuzhiyun .bit = BCM6328_CLK_PHYMIPS,
210*4882a593Smuzhiyun }, {
211*4882a593Smuzhiyun .name = "adsl_qproc",
212*4882a593Smuzhiyun .bit = BCM6328_CLK_ADSL_QPROC,
213*4882a593Smuzhiyun }, {
214*4882a593Smuzhiyun .name = "adsl_afe",
215*4882a593Smuzhiyun .bit = BCM6328_CLK_ADSL_AFE,
216*4882a593Smuzhiyun }, {
217*4882a593Smuzhiyun .name = "adsl",
218*4882a593Smuzhiyun .bit = BCM6328_CLK_ADSL,
219*4882a593Smuzhiyun }, {
220*4882a593Smuzhiyun .name = "mips",
221*4882a593Smuzhiyun .bit = BCM6328_CLK_MIPS,
222*4882a593Smuzhiyun .flags = CLK_IS_CRITICAL,
223*4882a593Smuzhiyun }, {
224*4882a593Smuzhiyun .name = "sar",
225*4882a593Smuzhiyun .bit = BCM6328_CLK_SAR,
226*4882a593Smuzhiyun }, {
227*4882a593Smuzhiyun .name = "pcm",
228*4882a593Smuzhiyun .bit = BCM6328_CLK_PCM,
229*4882a593Smuzhiyun }, {
230*4882a593Smuzhiyun .name = "usbd",
231*4882a593Smuzhiyun .bit = BCM6328_CLK_USBD,
232*4882a593Smuzhiyun }, {
233*4882a593Smuzhiyun .name = "usbh",
234*4882a593Smuzhiyun .bit = BCM6328_CLK_USBH,
235*4882a593Smuzhiyun }, {
236*4882a593Smuzhiyun .name = "hsspi",
237*4882a593Smuzhiyun .bit = BCM6328_CLK_HSSPI,
238*4882a593Smuzhiyun }, {
239*4882a593Smuzhiyun .name = "pcie",
240*4882a593Smuzhiyun .bit = BCM6328_CLK_PCIE,
241*4882a593Smuzhiyun }, {
242*4882a593Smuzhiyun .name = "robosw",
243*4882a593Smuzhiyun .bit = BCM6328_CLK_ROBOSW,
244*4882a593Smuzhiyun }, {
245*4882a593Smuzhiyun /* sentinel */
246*4882a593Smuzhiyun },
247*4882a593Smuzhiyun };
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun static const struct clk_bcm63xx_table_entry bcm6358_clocks[] = {
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun .name = "enet",
252*4882a593Smuzhiyun .bit = BCM6358_CLK_ENET,
253*4882a593Smuzhiyun }, {
254*4882a593Smuzhiyun .name = "adslphy",
255*4882a593Smuzhiyun .bit = BCM6358_CLK_ADSLPHY,
256*4882a593Smuzhiyun }, {
257*4882a593Smuzhiyun .name = "pcm",
258*4882a593Smuzhiyun .bit = BCM6358_CLK_PCM,
259*4882a593Smuzhiyun }, {
260*4882a593Smuzhiyun .name = "spi",
261*4882a593Smuzhiyun .bit = BCM6358_CLK_SPI,
262*4882a593Smuzhiyun }, {
263*4882a593Smuzhiyun .name = "usbs",
264*4882a593Smuzhiyun .bit = BCM6358_CLK_USBS,
265*4882a593Smuzhiyun }, {
266*4882a593Smuzhiyun .name = "sar",
267*4882a593Smuzhiyun .bit = BCM6358_CLK_SAR,
268*4882a593Smuzhiyun }, {
269*4882a593Smuzhiyun .name = "emusb",
270*4882a593Smuzhiyun .bit = BCM6358_CLK_EMUSB,
271*4882a593Smuzhiyun }, {
272*4882a593Smuzhiyun .name = "enet0",
273*4882a593Smuzhiyun .bit = BCM6358_CLK_ENET0,
274*4882a593Smuzhiyun }, {
275*4882a593Smuzhiyun .name = "enet1",
276*4882a593Smuzhiyun .bit = BCM6358_CLK_ENET1,
277*4882a593Smuzhiyun }, {
278*4882a593Smuzhiyun .name = "usbsu",
279*4882a593Smuzhiyun .bit = BCM6358_CLK_USBSU,
280*4882a593Smuzhiyun }, {
281*4882a593Smuzhiyun .name = "ephy",
282*4882a593Smuzhiyun .bit = BCM6358_CLK_EPHY,
283*4882a593Smuzhiyun }, {
284*4882a593Smuzhiyun /* sentinel */
285*4882a593Smuzhiyun },
286*4882a593Smuzhiyun };
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun static const struct clk_bcm63xx_table_entry bcm6362_clocks[] = {
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun .name = "adsl_qproc",
291*4882a593Smuzhiyun .bit = BCM6362_CLK_ADSL_QPROC,
292*4882a593Smuzhiyun }, {
293*4882a593Smuzhiyun .name = "adsl_afe",
294*4882a593Smuzhiyun .bit = BCM6362_CLK_ADSL_AFE,
295*4882a593Smuzhiyun }, {
296*4882a593Smuzhiyun .name = "adsl",
297*4882a593Smuzhiyun .bit = BCM6362_CLK_ADSL,
298*4882a593Smuzhiyun }, {
299*4882a593Smuzhiyun .name = "mips",
300*4882a593Smuzhiyun .bit = BCM6362_CLK_MIPS,
301*4882a593Smuzhiyun .flags = CLK_IS_CRITICAL,
302*4882a593Smuzhiyun }, {
303*4882a593Smuzhiyun .name = "wlan_ocp",
304*4882a593Smuzhiyun .bit = BCM6362_CLK_WLAN_OCP,
305*4882a593Smuzhiyun }, {
306*4882a593Smuzhiyun .name = "swpkt_usb",
307*4882a593Smuzhiyun .bit = BCM6362_CLK_SWPKT_USB,
308*4882a593Smuzhiyun }, {
309*4882a593Smuzhiyun .name = "swpkt_sar",
310*4882a593Smuzhiyun .bit = BCM6362_CLK_SWPKT_SAR,
311*4882a593Smuzhiyun }, {
312*4882a593Smuzhiyun .name = "sar",
313*4882a593Smuzhiyun .bit = BCM6362_CLK_SAR,
314*4882a593Smuzhiyun }, {
315*4882a593Smuzhiyun .name = "robosw",
316*4882a593Smuzhiyun .bit = BCM6362_CLK_ROBOSW,
317*4882a593Smuzhiyun }, {
318*4882a593Smuzhiyun .name = "pcm",
319*4882a593Smuzhiyun .bit = BCM6362_CLK_PCM,
320*4882a593Smuzhiyun }, {
321*4882a593Smuzhiyun .name = "usbd",
322*4882a593Smuzhiyun .bit = BCM6362_CLK_USBD,
323*4882a593Smuzhiyun }, {
324*4882a593Smuzhiyun .name = "usbh",
325*4882a593Smuzhiyun .bit = BCM6362_CLK_USBH,
326*4882a593Smuzhiyun }, {
327*4882a593Smuzhiyun .name = "ipsec",
328*4882a593Smuzhiyun .bit = BCM6362_CLK_IPSEC,
329*4882a593Smuzhiyun }, {
330*4882a593Smuzhiyun .name = "spi",
331*4882a593Smuzhiyun .bit = BCM6362_CLK_SPI,
332*4882a593Smuzhiyun }, {
333*4882a593Smuzhiyun .name = "hsspi",
334*4882a593Smuzhiyun .bit = BCM6362_CLK_HSSPI,
335*4882a593Smuzhiyun }, {
336*4882a593Smuzhiyun .name = "pcie",
337*4882a593Smuzhiyun .bit = BCM6362_CLK_PCIE,
338*4882a593Smuzhiyun }, {
339*4882a593Smuzhiyun .name = "fap",
340*4882a593Smuzhiyun .bit = BCM6362_CLK_FAP,
341*4882a593Smuzhiyun }, {
342*4882a593Smuzhiyun .name = "phymips",
343*4882a593Smuzhiyun .bit = BCM6362_CLK_PHYMIPS,
344*4882a593Smuzhiyun }, {
345*4882a593Smuzhiyun .name = "nand",
346*4882a593Smuzhiyun .bit = BCM6362_CLK_NAND,
347*4882a593Smuzhiyun }, {
348*4882a593Smuzhiyun /* sentinel */
349*4882a593Smuzhiyun },
350*4882a593Smuzhiyun };
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun static const struct clk_bcm63xx_table_entry bcm6368_clocks[] = {
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun .name = "vdsl_qproc",
355*4882a593Smuzhiyun .bit = BCM6368_CLK_VDSL_QPROC,
356*4882a593Smuzhiyun }, {
357*4882a593Smuzhiyun .name = "vdsl_afe",
358*4882a593Smuzhiyun .bit = BCM6368_CLK_VDSL_AFE,
359*4882a593Smuzhiyun }, {
360*4882a593Smuzhiyun .name = "vdsl_bonding",
361*4882a593Smuzhiyun .bit = BCM6368_CLK_VDSL_BONDING,
362*4882a593Smuzhiyun }, {
363*4882a593Smuzhiyun .name = "vdsl",
364*4882a593Smuzhiyun .bit = BCM6368_CLK_VDSL,
365*4882a593Smuzhiyun }, {
366*4882a593Smuzhiyun .name = "phymips",
367*4882a593Smuzhiyun .bit = BCM6368_CLK_PHYMIPS,
368*4882a593Smuzhiyun }, {
369*4882a593Smuzhiyun .name = "swpkt_usb",
370*4882a593Smuzhiyun .bit = BCM6368_CLK_SWPKT_USB,
371*4882a593Smuzhiyun }, {
372*4882a593Smuzhiyun .name = "swpkt_sar",
373*4882a593Smuzhiyun .bit = BCM6368_CLK_SWPKT_SAR,
374*4882a593Smuzhiyun }, {
375*4882a593Smuzhiyun .name = "spi",
376*4882a593Smuzhiyun .bit = BCM6368_CLK_SPI,
377*4882a593Smuzhiyun }, {
378*4882a593Smuzhiyun .name = "usbd",
379*4882a593Smuzhiyun .bit = BCM6368_CLK_USBD,
380*4882a593Smuzhiyun }, {
381*4882a593Smuzhiyun .name = "sar",
382*4882a593Smuzhiyun .bit = BCM6368_CLK_SAR,
383*4882a593Smuzhiyun }, {
384*4882a593Smuzhiyun .name = "robosw",
385*4882a593Smuzhiyun .bit = BCM6368_CLK_ROBOSW,
386*4882a593Smuzhiyun }, {
387*4882a593Smuzhiyun .name = "utopia",
388*4882a593Smuzhiyun .bit = BCM6368_CLK_UTOPIA,
389*4882a593Smuzhiyun }, {
390*4882a593Smuzhiyun .name = "pcm",
391*4882a593Smuzhiyun .bit = BCM6368_CLK_PCM,
392*4882a593Smuzhiyun }, {
393*4882a593Smuzhiyun .name = "usbh",
394*4882a593Smuzhiyun .bit = BCM6368_CLK_USBH,
395*4882a593Smuzhiyun }, {
396*4882a593Smuzhiyun .name = "disable_gless",
397*4882a593Smuzhiyun .bit = BCM6368_CLK_DIS_GLESS,
398*4882a593Smuzhiyun }, {
399*4882a593Smuzhiyun .name = "nand",
400*4882a593Smuzhiyun .bit = BCM6368_CLK_NAND,
401*4882a593Smuzhiyun }, {
402*4882a593Smuzhiyun .name = "ipsec",
403*4882a593Smuzhiyun .bit = BCM6368_CLK_IPSEC,
404*4882a593Smuzhiyun }, {
405*4882a593Smuzhiyun /* sentinel */
406*4882a593Smuzhiyun },
407*4882a593Smuzhiyun };
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun static const struct clk_bcm63xx_table_entry bcm63268_clocks[] = {
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun .name = "disable_gless",
412*4882a593Smuzhiyun .bit = BCM63268_CLK_DIS_GLESS,
413*4882a593Smuzhiyun }, {
414*4882a593Smuzhiyun .name = "vdsl_qproc",
415*4882a593Smuzhiyun .bit = BCM63268_CLK_VDSL_QPROC,
416*4882a593Smuzhiyun }, {
417*4882a593Smuzhiyun .name = "vdsl_afe",
418*4882a593Smuzhiyun .bit = BCM63268_CLK_VDSL_AFE,
419*4882a593Smuzhiyun }, {
420*4882a593Smuzhiyun .name = "vdsl",
421*4882a593Smuzhiyun .bit = BCM63268_CLK_VDSL,
422*4882a593Smuzhiyun }, {
423*4882a593Smuzhiyun .name = "mips",
424*4882a593Smuzhiyun .bit = BCM63268_CLK_MIPS,
425*4882a593Smuzhiyun .flags = CLK_IS_CRITICAL,
426*4882a593Smuzhiyun }, {
427*4882a593Smuzhiyun .name = "wlan_ocp",
428*4882a593Smuzhiyun .bit = BCM63268_CLK_WLAN_OCP,
429*4882a593Smuzhiyun }, {
430*4882a593Smuzhiyun .name = "dect",
431*4882a593Smuzhiyun .bit = BCM63268_CLK_DECT,
432*4882a593Smuzhiyun }, {
433*4882a593Smuzhiyun .name = "fap0",
434*4882a593Smuzhiyun .bit = BCM63268_CLK_FAP0,
435*4882a593Smuzhiyun }, {
436*4882a593Smuzhiyun .name = "fap1",
437*4882a593Smuzhiyun .bit = BCM63268_CLK_FAP1,
438*4882a593Smuzhiyun }, {
439*4882a593Smuzhiyun .name = "sar",
440*4882a593Smuzhiyun .bit = BCM63268_CLK_SAR,
441*4882a593Smuzhiyun }, {
442*4882a593Smuzhiyun .name = "robosw",
443*4882a593Smuzhiyun .bit = BCM63268_CLK_ROBOSW,
444*4882a593Smuzhiyun }, {
445*4882a593Smuzhiyun .name = "pcm",
446*4882a593Smuzhiyun .bit = BCM63268_CLK_PCM,
447*4882a593Smuzhiyun }, {
448*4882a593Smuzhiyun .name = "usbd",
449*4882a593Smuzhiyun .bit = BCM63268_CLK_USBD,
450*4882a593Smuzhiyun }, {
451*4882a593Smuzhiyun .name = "usbh",
452*4882a593Smuzhiyun .bit = BCM63268_CLK_USBH,
453*4882a593Smuzhiyun }, {
454*4882a593Smuzhiyun .name = "ipsec",
455*4882a593Smuzhiyun .bit = BCM63268_CLK_IPSEC,
456*4882a593Smuzhiyun }, {
457*4882a593Smuzhiyun .name = "spi",
458*4882a593Smuzhiyun .bit = BCM63268_CLK_SPI,
459*4882a593Smuzhiyun }, {
460*4882a593Smuzhiyun .name = "hsspi",
461*4882a593Smuzhiyun .bit = BCM63268_CLK_HSSPI,
462*4882a593Smuzhiyun }, {
463*4882a593Smuzhiyun .name = "pcie",
464*4882a593Smuzhiyun .bit = BCM63268_CLK_PCIE,
465*4882a593Smuzhiyun }, {
466*4882a593Smuzhiyun .name = "phymips",
467*4882a593Smuzhiyun .bit = BCM63268_CLK_PHYMIPS,
468*4882a593Smuzhiyun }, {
469*4882a593Smuzhiyun .name = "gmac",
470*4882a593Smuzhiyun .bit = BCM63268_CLK_GMAC,
471*4882a593Smuzhiyun }, {
472*4882a593Smuzhiyun .name = "nand",
473*4882a593Smuzhiyun .bit = BCM63268_CLK_NAND,
474*4882a593Smuzhiyun }, {
475*4882a593Smuzhiyun .name = "tbus",
476*4882a593Smuzhiyun .bit = BCM63268_CLK_TBUS,
477*4882a593Smuzhiyun }, {
478*4882a593Smuzhiyun .name = "robosw250",
479*4882a593Smuzhiyun .bit = BCM63268_CLK_ROBOSW250,
480*4882a593Smuzhiyun }, {
481*4882a593Smuzhiyun /* sentinel */
482*4882a593Smuzhiyun },
483*4882a593Smuzhiyun };
484*4882a593Smuzhiyun
clk_bcm63xx_probe(struct platform_device * pdev)485*4882a593Smuzhiyun static int clk_bcm63xx_probe(struct platform_device *pdev)
486*4882a593Smuzhiyun {
487*4882a593Smuzhiyun const struct clk_bcm63xx_table_entry *entry, *table;
488*4882a593Smuzhiyun struct clk_bcm63xx_hw *hw;
489*4882a593Smuzhiyun u8 maxbit = 0;
490*4882a593Smuzhiyun int i, ret;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun table = of_device_get_match_data(&pdev->dev);
493*4882a593Smuzhiyun if (!table)
494*4882a593Smuzhiyun return -EINVAL;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun for (entry = table; entry->name; entry++)
497*4882a593Smuzhiyun maxbit = max_t(u8, maxbit, entry->bit);
498*4882a593Smuzhiyun maxbit++;
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),
501*4882a593Smuzhiyun GFP_KERNEL);
502*4882a593Smuzhiyun if (!hw)
503*4882a593Smuzhiyun return -ENOMEM;
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun platform_set_drvdata(pdev, hw);
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun spin_lock_init(&hw->lock);
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun hw->data.num = maxbit;
510*4882a593Smuzhiyun for (i = 0; i < maxbit; i++)
511*4882a593Smuzhiyun hw->data.hws[i] = ERR_PTR(-ENODEV);
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun hw->regs = devm_platform_ioremap_resource(pdev, 0);
514*4882a593Smuzhiyun if (IS_ERR(hw->regs))
515*4882a593Smuzhiyun return PTR_ERR(hw->regs);
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun for (entry = table; entry->name; entry++) {
518*4882a593Smuzhiyun struct clk_hw *clk;
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun clk = clk_hw_register_gate(&pdev->dev, entry->name, NULL,
521*4882a593Smuzhiyun entry->flags, hw->regs, entry->bit,
522*4882a593Smuzhiyun CLK_GATE_BIG_ENDIAN, &hw->lock);
523*4882a593Smuzhiyun if (IS_ERR(clk)) {
524*4882a593Smuzhiyun ret = PTR_ERR(clk);
525*4882a593Smuzhiyun goto out_err;
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun hw->data.hws[entry->bit] = clk;
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
532*4882a593Smuzhiyun &hw->data);
533*4882a593Smuzhiyun if (!ret)
534*4882a593Smuzhiyun return 0;
535*4882a593Smuzhiyun out_err:
536*4882a593Smuzhiyun for (i = 0; i < hw->data.num; i++) {
537*4882a593Smuzhiyun if (!IS_ERR(hw->data.hws[i]))
538*4882a593Smuzhiyun clk_hw_unregister_gate(hw->data.hws[i]);
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun return ret;
542*4882a593Smuzhiyun }
543*4882a593Smuzhiyun
clk_bcm63xx_remove(struct platform_device * pdev)544*4882a593Smuzhiyun static int clk_bcm63xx_remove(struct platform_device *pdev)
545*4882a593Smuzhiyun {
546*4882a593Smuzhiyun struct clk_bcm63xx_hw *hw = platform_get_drvdata(pdev);
547*4882a593Smuzhiyun int i;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun of_clk_del_provider(pdev->dev.of_node);
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun for (i = 0; i < hw->data.num; i++) {
552*4882a593Smuzhiyun if (!IS_ERR(hw->data.hws[i]))
553*4882a593Smuzhiyun clk_hw_unregister_gate(hw->data.hws[i]);
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun return 0;
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun static const struct of_device_id clk_bcm63xx_dt_ids[] = {
560*4882a593Smuzhiyun { .compatible = "brcm,bcm3368-clocks", .data = &bcm3368_clocks, },
561*4882a593Smuzhiyun { .compatible = "brcm,bcm6318-clocks", .data = &bcm6318_clocks, },
562*4882a593Smuzhiyun { .compatible = "brcm,bcm6318-ubus-clocks", .data = &bcm6318_ubus_clocks, },
563*4882a593Smuzhiyun { .compatible = "brcm,bcm6328-clocks", .data = &bcm6328_clocks, },
564*4882a593Smuzhiyun { .compatible = "brcm,bcm6358-clocks", .data = &bcm6358_clocks, },
565*4882a593Smuzhiyun { .compatible = "brcm,bcm6362-clocks", .data = &bcm6362_clocks, },
566*4882a593Smuzhiyun { .compatible = "brcm,bcm6368-clocks", .data = &bcm6368_clocks, },
567*4882a593Smuzhiyun { .compatible = "brcm,bcm63268-clocks", .data = &bcm63268_clocks, },
568*4882a593Smuzhiyun { }
569*4882a593Smuzhiyun };
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun static struct platform_driver clk_bcm63xx = {
572*4882a593Smuzhiyun .probe = clk_bcm63xx_probe,
573*4882a593Smuzhiyun .remove = clk_bcm63xx_remove,
574*4882a593Smuzhiyun .driver = {
575*4882a593Smuzhiyun .name = "bcm63xx-clock",
576*4882a593Smuzhiyun .of_match_table = clk_bcm63xx_dt_ids,
577*4882a593Smuzhiyun },
578*4882a593Smuzhiyun };
579*4882a593Smuzhiyun builtin_platform_driver(clk_bcm63xx);
580