xref: /OK3568_Linux_fs/kernel/arch/mips/bcm63xx/clk.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * This file is subject to the terms and conditions of the GNU General Public
3*4882a593Smuzhiyun  * License.  See the file "COPYING" in the main directory of this archive
4*4882a593Smuzhiyun  * for more details.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/export.h>
11*4882a593Smuzhiyun #include <linux/mutex.h>
12*4882a593Smuzhiyun #include <linux/err.h>
13*4882a593Smuzhiyun #include <linux/clk.h>
14*4882a593Smuzhiyun #include <linux/clkdev.h>
15*4882a593Smuzhiyun #include <linux/delay.h>
16*4882a593Smuzhiyun #include <bcm63xx_cpu.h>
17*4882a593Smuzhiyun #include <bcm63xx_io.h>
18*4882a593Smuzhiyun #include <bcm63xx_regs.h>
19*4882a593Smuzhiyun #include <bcm63xx_reset.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun struct clk {
22*4882a593Smuzhiyun 	void		(*set)(struct clk *, int);
23*4882a593Smuzhiyun 	unsigned int	rate;
24*4882a593Smuzhiyun 	unsigned int	usage;
25*4882a593Smuzhiyun 	int		id;
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun static DEFINE_MUTEX(clocks_mutex);
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 
clk_enable_unlocked(struct clk * clk)31*4882a593Smuzhiyun static void clk_enable_unlocked(struct clk *clk)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun 	if (clk->set && (clk->usage++) == 0)
34*4882a593Smuzhiyun 		clk->set(clk, 1);
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun 
clk_disable_unlocked(struct clk * clk)37*4882a593Smuzhiyun static void clk_disable_unlocked(struct clk *clk)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun 	if (clk->set && (--clk->usage) == 0)
40*4882a593Smuzhiyun 		clk->set(clk, 0);
41*4882a593Smuzhiyun }
42*4882a593Smuzhiyun 
bcm_hwclock_set(u32 mask,int enable)43*4882a593Smuzhiyun static void bcm_hwclock_set(u32 mask, int enable)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	u32 reg;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	reg = bcm_perf_readl(PERF_CKCTL_REG);
48*4882a593Smuzhiyun 	if (enable)
49*4882a593Smuzhiyun 		reg |= mask;
50*4882a593Smuzhiyun 	else
51*4882a593Smuzhiyun 		reg &= ~mask;
52*4882a593Smuzhiyun 	bcm_perf_writel(reg, PERF_CKCTL_REG);
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun /*
56*4882a593Smuzhiyun  * Ethernet MAC "misc" clock: dma clocks and main clock on 6348
57*4882a593Smuzhiyun  */
enet_misc_set(struct clk * clk,int enable)58*4882a593Smuzhiyun static void enet_misc_set(struct clk *clk, int enable)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	u32 mask;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	if (BCMCPU_IS_6338())
63*4882a593Smuzhiyun 		mask = CKCTL_6338_ENET_EN;
64*4882a593Smuzhiyun 	else if (BCMCPU_IS_6345())
65*4882a593Smuzhiyun 		mask = CKCTL_6345_ENET_EN;
66*4882a593Smuzhiyun 	else if (BCMCPU_IS_6348())
67*4882a593Smuzhiyun 		mask = CKCTL_6348_ENET_EN;
68*4882a593Smuzhiyun 	else
69*4882a593Smuzhiyun 		/* BCMCPU_IS_6358 */
70*4882a593Smuzhiyun 		mask = CKCTL_6358_EMUSB_EN;
71*4882a593Smuzhiyun 	bcm_hwclock_set(mask, enable);
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun static struct clk clk_enet_misc = {
75*4882a593Smuzhiyun 	.set	= enet_misc_set,
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /*
79*4882a593Smuzhiyun  * Ethernet MAC clocks: only revelant on 6358, silently enable misc
80*4882a593Smuzhiyun  * clocks
81*4882a593Smuzhiyun  */
enetx_set(struct clk * clk,int enable)82*4882a593Smuzhiyun static void enetx_set(struct clk *clk, int enable)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun 	if (enable)
85*4882a593Smuzhiyun 		clk_enable_unlocked(&clk_enet_misc);
86*4882a593Smuzhiyun 	else
87*4882a593Smuzhiyun 		clk_disable_unlocked(&clk_enet_misc);
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
90*4882a593Smuzhiyun 		u32 mask;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 		if (clk->id == 0)
93*4882a593Smuzhiyun 			mask = CKCTL_6358_ENET0_EN;
94*4882a593Smuzhiyun 		else
95*4882a593Smuzhiyun 			mask = CKCTL_6358_ENET1_EN;
96*4882a593Smuzhiyun 		bcm_hwclock_set(mask, enable);
97*4882a593Smuzhiyun 	}
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun static struct clk clk_enet0 = {
101*4882a593Smuzhiyun 	.id	= 0,
102*4882a593Smuzhiyun 	.set	= enetx_set,
103*4882a593Smuzhiyun };
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun static struct clk clk_enet1 = {
106*4882a593Smuzhiyun 	.id	= 1,
107*4882a593Smuzhiyun 	.set	= enetx_set,
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /*
111*4882a593Smuzhiyun  * Ethernet PHY clock
112*4882a593Smuzhiyun  */
ephy_set(struct clk * clk,int enable)113*4882a593Smuzhiyun static void ephy_set(struct clk *clk, int enable)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
116*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun static struct clk clk_ephy = {
121*4882a593Smuzhiyun 	.set	= ephy_set,
122*4882a593Smuzhiyun };
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun /*
125*4882a593Smuzhiyun  * Ethernet switch SAR clock
126*4882a593Smuzhiyun  */
swpkt_sar_set(struct clk * clk,int enable)127*4882a593Smuzhiyun static void swpkt_sar_set(struct clk *clk, int enable)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	if (BCMCPU_IS_6368())
130*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6368_SWPKT_SAR_EN, enable);
131*4882a593Smuzhiyun 	else
132*4882a593Smuzhiyun 		return;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun static struct clk clk_swpkt_sar = {
136*4882a593Smuzhiyun 	.set	= swpkt_sar_set,
137*4882a593Smuzhiyun };
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /*
140*4882a593Smuzhiyun  * Ethernet switch USB clock
141*4882a593Smuzhiyun  */
swpkt_usb_set(struct clk * clk,int enable)142*4882a593Smuzhiyun static void swpkt_usb_set(struct clk *clk, int enable)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun 	if (BCMCPU_IS_6368())
145*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6368_SWPKT_USB_EN, enable);
146*4882a593Smuzhiyun 	else
147*4882a593Smuzhiyun 		return;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun static struct clk clk_swpkt_usb = {
151*4882a593Smuzhiyun 	.set	= swpkt_usb_set,
152*4882a593Smuzhiyun };
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /*
155*4882a593Smuzhiyun  * Ethernet switch clock
156*4882a593Smuzhiyun  */
enetsw_set(struct clk * clk,int enable)157*4882a593Smuzhiyun static void enetsw_set(struct clk *clk, int enable)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	if (BCMCPU_IS_6328()) {
160*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6328_ROBOSW_EN, enable);
161*4882a593Smuzhiyun 	} else if (BCMCPU_IS_6362()) {
162*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6362_ROBOSW_EN, enable);
163*4882a593Smuzhiyun 	} else if (BCMCPU_IS_6368()) {
164*4882a593Smuzhiyun 		if (enable) {
165*4882a593Smuzhiyun 			clk_enable_unlocked(&clk_swpkt_sar);
166*4882a593Smuzhiyun 			clk_enable_unlocked(&clk_swpkt_usb);
167*4882a593Smuzhiyun 		} else {
168*4882a593Smuzhiyun 			clk_disable_unlocked(&clk_swpkt_usb);
169*4882a593Smuzhiyun 			clk_disable_unlocked(&clk_swpkt_sar);
170*4882a593Smuzhiyun 		}
171*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6368_ROBOSW_EN, enable);
172*4882a593Smuzhiyun 	} else {
173*4882a593Smuzhiyun 		return;
174*4882a593Smuzhiyun 	}
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	if (enable) {
177*4882a593Smuzhiyun 		/* reset switch core afer clock change */
178*4882a593Smuzhiyun 		bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1);
179*4882a593Smuzhiyun 		msleep(10);
180*4882a593Smuzhiyun 		bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0);
181*4882a593Smuzhiyun 		msleep(10);
182*4882a593Smuzhiyun 	}
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun static struct clk clk_enetsw = {
186*4882a593Smuzhiyun 	.set	= enetsw_set,
187*4882a593Smuzhiyun };
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun /*
190*4882a593Smuzhiyun  * PCM clock
191*4882a593Smuzhiyun  */
pcm_set(struct clk * clk,int enable)192*4882a593Smuzhiyun static void pcm_set(struct clk *clk, int enable)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun 	if (BCMCPU_IS_3368())
195*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_3368_PCM_EN, enable);
196*4882a593Smuzhiyun 	if (BCMCPU_IS_6358())
197*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun static struct clk clk_pcm = {
201*4882a593Smuzhiyun 	.set	= pcm_set,
202*4882a593Smuzhiyun };
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun /*
205*4882a593Smuzhiyun  * USB host clock
206*4882a593Smuzhiyun  */
usbh_set(struct clk * clk,int enable)207*4882a593Smuzhiyun static void usbh_set(struct clk *clk, int enable)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	if (BCMCPU_IS_6328())
210*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
211*4882a593Smuzhiyun 	else if (BCMCPU_IS_6348())
212*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
213*4882a593Smuzhiyun 	else if (BCMCPU_IS_6362())
214*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6362_USBH_EN, enable);
215*4882a593Smuzhiyun 	else if (BCMCPU_IS_6368())
216*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun static struct clk clk_usbh = {
220*4882a593Smuzhiyun 	.set	= usbh_set,
221*4882a593Smuzhiyun };
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun /*
224*4882a593Smuzhiyun  * USB device clock
225*4882a593Smuzhiyun  */
usbd_set(struct clk * clk,int enable)226*4882a593Smuzhiyun static void usbd_set(struct clk *clk, int enable)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun 	if (BCMCPU_IS_6328())
229*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6328_USBD_EN, enable);
230*4882a593Smuzhiyun 	else if (BCMCPU_IS_6362())
231*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6362_USBD_EN, enable);
232*4882a593Smuzhiyun 	else if (BCMCPU_IS_6368())
233*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6368_USBD_EN, enable);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun static struct clk clk_usbd = {
237*4882a593Smuzhiyun 	.set	= usbd_set,
238*4882a593Smuzhiyun };
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun /*
241*4882a593Smuzhiyun  * SPI clock
242*4882a593Smuzhiyun  */
spi_set(struct clk * clk,int enable)243*4882a593Smuzhiyun static void spi_set(struct clk *clk, int enable)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	u32 mask;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	if (BCMCPU_IS_6338())
248*4882a593Smuzhiyun 		mask = CKCTL_6338_SPI_EN;
249*4882a593Smuzhiyun 	else if (BCMCPU_IS_6348())
250*4882a593Smuzhiyun 		mask = CKCTL_6348_SPI_EN;
251*4882a593Smuzhiyun 	else if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
252*4882a593Smuzhiyun 		mask = CKCTL_6358_SPI_EN;
253*4882a593Smuzhiyun 	else if (BCMCPU_IS_6362())
254*4882a593Smuzhiyun 		mask = CKCTL_6362_SPI_EN;
255*4882a593Smuzhiyun 	else
256*4882a593Smuzhiyun 		/* BCMCPU_IS_6368 */
257*4882a593Smuzhiyun 		mask = CKCTL_6368_SPI_EN;
258*4882a593Smuzhiyun 	bcm_hwclock_set(mask, enable);
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun static struct clk clk_spi = {
262*4882a593Smuzhiyun 	.set	= spi_set,
263*4882a593Smuzhiyun };
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun /*
266*4882a593Smuzhiyun  * HSSPI clock
267*4882a593Smuzhiyun  */
hsspi_set(struct clk * clk,int enable)268*4882a593Smuzhiyun static void hsspi_set(struct clk *clk, int enable)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun 	u32 mask;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	if (BCMCPU_IS_6328())
273*4882a593Smuzhiyun 		mask = CKCTL_6328_HSSPI_EN;
274*4882a593Smuzhiyun 	else if (BCMCPU_IS_6362())
275*4882a593Smuzhiyun 		mask = CKCTL_6362_HSSPI_EN;
276*4882a593Smuzhiyun 	else
277*4882a593Smuzhiyun 		return;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	bcm_hwclock_set(mask, enable);
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun static struct clk clk_hsspi = {
283*4882a593Smuzhiyun 	.set	= hsspi_set,
284*4882a593Smuzhiyun };
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun /*
287*4882a593Smuzhiyun  * HSSPI PLL
288*4882a593Smuzhiyun  */
289*4882a593Smuzhiyun static struct clk clk_hsspi_pll;
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun /*
292*4882a593Smuzhiyun  * XTM clock
293*4882a593Smuzhiyun  */
xtm_set(struct clk * clk,int enable)294*4882a593Smuzhiyun static void xtm_set(struct clk *clk, int enable)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun 	if (!BCMCPU_IS_6368())
297*4882a593Smuzhiyun 		return;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	if (enable)
300*4882a593Smuzhiyun 		clk_enable_unlocked(&clk_swpkt_sar);
301*4882a593Smuzhiyun 	else
302*4882a593Smuzhiyun 		clk_disable_unlocked(&clk_swpkt_sar);
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	bcm_hwclock_set(CKCTL_6368_SAR_EN, enable);
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	if (enable) {
307*4882a593Smuzhiyun 		/* reset sar core afer clock change */
308*4882a593Smuzhiyun 		bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1);
309*4882a593Smuzhiyun 		mdelay(1);
310*4882a593Smuzhiyun 		bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0);
311*4882a593Smuzhiyun 		mdelay(1);
312*4882a593Smuzhiyun 	}
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun static struct clk clk_xtm = {
317*4882a593Smuzhiyun 	.set	= xtm_set,
318*4882a593Smuzhiyun };
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun /*
321*4882a593Smuzhiyun  * IPsec clock
322*4882a593Smuzhiyun  */
ipsec_set(struct clk * clk,int enable)323*4882a593Smuzhiyun static void ipsec_set(struct clk *clk, int enable)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun 	if (BCMCPU_IS_6362())
326*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6362_IPSEC_EN, enable);
327*4882a593Smuzhiyun 	else if (BCMCPU_IS_6368())
328*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable);
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun static struct clk clk_ipsec = {
332*4882a593Smuzhiyun 	.set	= ipsec_set,
333*4882a593Smuzhiyun };
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun /*
336*4882a593Smuzhiyun  * PCIe clock
337*4882a593Smuzhiyun  */
338*4882a593Smuzhiyun 
pcie_set(struct clk * clk,int enable)339*4882a593Smuzhiyun static void pcie_set(struct clk *clk, int enable)
340*4882a593Smuzhiyun {
341*4882a593Smuzhiyun 	if (BCMCPU_IS_6328())
342*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable);
343*4882a593Smuzhiyun 	else if (BCMCPU_IS_6362())
344*4882a593Smuzhiyun 		bcm_hwclock_set(CKCTL_6362_PCIE_EN, enable);
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun static struct clk clk_pcie = {
348*4882a593Smuzhiyun 	.set	= pcie_set,
349*4882a593Smuzhiyun };
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun /*
352*4882a593Smuzhiyun  * Internal peripheral clock
353*4882a593Smuzhiyun  */
354*4882a593Smuzhiyun static struct clk clk_periph = {
355*4882a593Smuzhiyun 	.rate	= (50 * 1000 * 1000),
356*4882a593Smuzhiyun };
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun /*
360*4882a593Smuzhiyun  * Linux clock API implementation
361*4882a593Smuzhiyun  */
clk_enable(struct clk * clk)362*4882a593Smuzhiyun int clk_enable(struct clk *clk)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun 	mutex_lock(&clocks_mutex);
365*4882a593Smuzhiyun 	clk_enable_unlocked(clk);
366*4882a593Smuzhiyun 	mutex_unlock(&clocks_mutex);
367*4882a593Smuzhiyun 	return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun EXPORT_SYMBOL(clk_enable);
371*4882a593Smuzhiyun 
clk_disable(struct clk * clk)372*4882a593Smuzhiyun void clk_disable(struct clk *clk)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun 	if (!clk)
375*4882a593Smuzhiyun 		return;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	mutex_lock(&clocks_mutex);
378*4882a593Smuzhiyun 	clk_disable_unlocked(clk);
379*4882a593Smuzhiyun 	mutex_unlock(&clocks_mutex);
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun EXPORT_SYMBOL(clk_disable);
383*4882a593Smuzhiyun 
clk_get_parent(struct clk * clk)384*4882a593Smuzhiyun struct clk *clk_get_parent(struct clk *clk)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun 	return NULL;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun EXPORT_SYMBOL(clk_get_parent);
389*4882a593Smuzhiyun 
clk_set_parent(struct clk * clk,struct clk * parent)390*4882a593Smuzhiyun int clk_set_parent(struct clk *clk, struct clk *parent)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun 	return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun EXPORT_SYMBOL(clk_set_parent);
395*4882a593Smuzhiyun 
clk_get_rate(struct clk * clk)396*4882a593Smuzhiyun unsigned long clk_get_rate(struct clk *clk)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun 	if (!clk)
399*4882a593Smuzhiyun 		return 0;
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	return clk->rate;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun EXPORT_SYMBOL(clk_get_rate);
405*4882a593Smuzhiyun 
clk_set_rate(struct clk * clk,unsigned long rate)406*4882a593Smuzhiyun int clk_set_rate(struct clk *clk, unsigned long rate)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun 	return 0;
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(clk_set_rate);
411*4882a593Smuzhiyun 
clk_round_rate(struct clk * clk,unsigned long rate)412*4882a593Smuzhiyun long clk_round_rate(struct clk *clk, unsigned long rate)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun 	return 0;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(clk_round_rate);
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun static struct clk_lookup bcm3368_clks[] = {
419*4882a593Smuzhiyun 	/* fixed rate clocks */
420*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "periph", &clk_periph),
421*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
422*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
423*4882a593Smuzhiyun 	/* gated clocks */
424*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
425*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
426*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
427*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
428*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
429*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "spi", &clk_spi),
430*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "pcm", &clk_pcm),
431*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
432*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
433*4882a593Smuzhiyun };
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun static struct clk_lookup bcm6328_clks[] = {
436*4882a593Smuzhiyun 	/* fixed rate clocks */
437*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "periph", &clk_periph),
438*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
439*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
440*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
441*4882a593Smuzhiyun 	/* gated clocks */
442*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
443*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
444*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
445*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
446*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "pcie", &clk_pcie),
447*4882a593Smuzhiyun };
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun static struct clk_lookup bcm6338_clks[] = {
450*4882a593Smuzhiyun 	/* fixed rate clocks */
451*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "periph", &clk_periph),
452*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
453*4882a593Smuzhiyun 	/* gated clocks */
454*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
455*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
456*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
457*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
458*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
459*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "spi", &clk_spi),
460*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
461*4882a593Smuzhiyun };
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun static struct clk_lookup bcm6345_clks[] = {
464*4882a593Smuzhiyun 	/* fixed rate clocks */
465*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "periph", &clk_periph),
466*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
467*4882a593Smuzhiyun 	/* gated clocks */
468*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
469*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
470*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
471*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
472*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
473*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "spi", &clk_spi),
474*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
475*4882a593Smuzhiyun };
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun static struct clk_lookup bcm6348_clks[] = {
478*4882a593Smuzhiyun 	/* fixed rate clocks */
479*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "periph", &clk_periph),
480*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
481*4882a593Smuzhiyun 	/* gated clocks */
482*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
483*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
484*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
485*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
486*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
487*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "spi", &clk_spi),
488*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
489*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet_misc),
490*4882a593Smuzhiyun };
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun static struct clk_lookup bcm6358_clks[] = {
493*4882a593Smuzhiyun 	/* fixed rate clocks */
494*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "periph", &clk_periph),
495*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
496*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
497*4882a593Smuzhiyun 	/* gated clocks */
498*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
499*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
500*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
501*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
502*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
503*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "spi", &clk_spi),
504*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "pcm", &clk_pcm),
505*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "swpkt_sar", &clk_swpkt_sar),
506*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "swpkt_usb", &clk_swpkt_usb),
507*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
508*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
509*4882a593Smuzhiyun };
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun static struct clk_lookup bcm6362_clks[] = {
512*4882a593Smuzhiyun 	/* fixed rate clocks */
513*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "periph", &clk_periph),
514*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
515*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
516*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
517*4882a593Smuzhiyun 	/* gated clocks */
518*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
519*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
520*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
521*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "spi", &clk_spi),
522*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
523*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "pcie", &clk_pcie),
524*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
525*4882a593Smuzhiyun };
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun static struct clk_lookup bcm6368_clks[] = {
528*4882a593Smuzhiyun 	/* fixed rate clocks */
529*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "periph", &clk_periph),
530*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
531*4882a593Smuzhiyun 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
532*4882a593Smuzhiyun 	/* gated clocks */
533*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
534*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
535*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
536*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "spi", &clk_spi),
537*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "xtm", &clk_xtm),
538*4882a593Smuzhiyun 	CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
539*4882a593Smuzhiyun };
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun #define HSSPI_PLL_HZ_6328	133333333
542*4882a593Smuzhiyun #define HSSPI_PLL_HZ_6362	400000000
543*4882a593Smuzhiyun 
bcm63xx_clk_init(void)544*4882a593Smuzhiyun static int __init bcm63xx_clk_init(void)
545*4882a593Smuzhiyun {
546*4882a593Smuzhiyun 	switch (bcm63xx_get_cpu_id()) {
547*4882a593Smuzhiyun 	case BCM3368_CPU_ID:
548*4882a593Smuzhiyun 		clkdev_add_table(bcm3368_clks, ARRAY_SIZE(bcm3368_clks));
549*4882a593Smuzhiyun 		break;
550*4882a593Smuzhiyun 	case BCM6328_CPU_ID:
551*4882a593Smuzhiyun 		clk_hsspi_pll.rate = HSSPI_PLL_HZ_6328;
552*4882a593Smuzhiyun 		clkdev_add_table(bcm6328_clks, ARRAY_SIZE(bcm6328_clks));
553*4882a593Smuzhiyun 		break;
554*4882a593Smuzhiyun 	case BCM6338_CPU_ID:
555*4882a593Smuzhiyun 		clkdev_add_table(bcm6338_clks, ARRAY_SIZE(bcm6338_clks));
556*4882a593Smuzhiyun 		break;
557*4882a593Smuzhiyun 	case BCM6345_CPU_ID:
558*4882a593Smuzhiyun 		clkdev_add_table(bcm6345_clks, ARRAY_SIZE(bcm6345_clks));
559*4882a593Smuzhiyun 		break;
560*4882a593Smuzhiyun 	case BCM6348_CPU_ID:
561*4882a593Smuzhiyun 		clkdev_add_table(bcm6348_clks, ARRAY_SIZE(bcm6348_clks));
562*4882a593Smuzhiyun 		break;
563*4882a593Smuzhiyun 	case BCM6358_CPU_ID:
564*4882a593Smuzhiyun 		clkdev_add_table(bcm6358_clks, ARRAY_SIZE(bcm6358_clks));
565*4882a593Smuzhiyun 		break;
566*4882a593Smuzhiyun 	case BCM6362_CPU_ID:
567*4882a593Smuzhiyun 		clk_hsspi_pll.rate = HSSPI_PLL_HZ_6362;
568*4882a593Smuzhiyun 		clkdev_add_table(bcm6362_clks, ARRAY_SIZE(bcm6362_clks));
569*4882a593Smuzhiyun 		break;
570*4882a593Smuzhiyun 	case BCM6368_CPU_ID:
571*4882a593Smuzhiyun 		clkdev_add_table(bcm6368_clks, ARRAY_SIZE(bcm6368_clks));
572*4882a593Smuzhiyun 		break;
573*4882a593Smuzhiyun 	}
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 	return 0;
576*4882a593Smuzhiyun }
577*4882a593Smuzhiyun arch_initcall(bcm63xx_clk_init);
578