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