xref: /OK3568_Linux_fs/kernel/drivers/clk/bcm/clk-bcm63xx-gate.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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