xref: /openbmc/linux/arch/mips/bcm63xx/clk.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1e7300d04SMaxime Bizon /*
2e7300d04SMaxime Bizon  * This file is subject to the terms and conditions of the GNU General Public
3e7300d04SMaxime Bizon  * License.  See the file "COPYING" in the main directory of this archive
4e7300d04SMaxime Bizon  * for more details.
5e7300d04SMaxime Bizon  *
6e7300d04SMaxime Bizon  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7e7300d04SMaxime Bizon  */
8e7300d04SMaxime Bizon 
926dd3e4fSPaul Gortmaker #include <linux/init.h>
1026dd3e4fSPaul Gortmaker #include <linux/export.h>
11e7300d04SMaxime Bizon #include <linux/mutex.h>
12e7300d04SMaxime Bizon #include <linux/err.h>
13e7300d04SMaxime Bizon #include <linux/clk.h>
14c5af3c2dSJonas Gorski #include <linux/clkdev.h>
1504712f3fSMaxime Bizon #include <linux/delay.h>
16e7300d04SMaxime Bizon #include <bcm63xx_cpu.h>
17e7300d04SMaxime Bizon #include <bcm63xx_io.h>
18e7300d04SMaxime Bizon #include <bcm63xx_regs.h>
19ba00e2e5SJonas Gorski #include <bcm63xx_reset.h>
20042df4faSJonas Gorski 
21042df4faSJonas Gorski struct clk {
22042df4faSJonas Gorski 	void		(*set)(struct clk *, int);
23042df4faSJonas Gorski 	unsigned int	rate;
24042df4faSJonas Gorski 	unsigned int	usage;
25042df4faSJonas Gorski 	int		id;
26042df4faSJonas Gorski };
27e7300d04SMaxime Bizon 
28e7300d04SMaxime Bizon static DEFINE_MUTEX(clocks_mutex);
29e7300d04SMaxime Bizon 
30e7300d04SMaxime Bizon 
clk_enable_unlocked(struct clk * clk)31e7300d04SMaxime Bizon static void clk_enable_unlocked(struct clk *clk)
32e7300d04SMaxime Bizon {
33e7300d04SMaxime Bizon 	if (clk->set && (clk->usage++) == 0)
34e7300d04SMaxime Bizon 		clk->set(clk, 1);
35e7300d04SMaxime Bizon }
36e7300d04SMaxime Bizon 
clk_disable_unlocked(struct clk * clk)37e7300d04SMaxime Bizon static void clk_disable_unlocked(struct clk *clk)
38e7300d04SMaxime Bizon {
39e7300d04SMaxime Bizon 	if (clk->set && (--clk->usage) == 0)
40e7300d04SMaxime Bizon 		clk->set(clk, 0);
41e7300d04SMaxime Bizon }
42e7300d04SMaxime Bizon 
bcm_hwclock_set(u32 mask,int enable)43e7300d04SMaxime Bizon static void bcm_hwclock_set(u32 mask, int enable)
44e7300d04SMaxime Bizon {
45e7300d04SMaxime Bizon 	u32 reg;
46e7300d04SMaxime Bizon 
47e7300d04SMaxime Bizon 	reg = bcm_perf_readl(PERF_CKCTL_REG);
48e7300d04SMaxime Bizon 	if (enable)
49e7300d04SMaxime Bizon 		reg |= mask;
50e7300d04SMaxime Bizon 	else
51e7300d04SMaxime Bizon 		reg &= ~mask;
52e7300d04SMaxime Bizon 	bcm_perf_writel(reg, PERF_CKCTL_REG);
53e7300d04SMaxime Bizon }
54e7300d04SMaxime Bizon 
55e7300d04SMaxime Bizon /*
56e7300d04SMaxime Bizon  * Ethernet MAC "misc" clock: dma clocks and main clock on 6348
57e7300d04SMaxime Bizon  */
enet_misc_set(struct clk * clk,int enable)58e7300d04SMaxime Bizon static void enet_misc_set(struct clk *clk, int enable)
59e7300d04SMaxime Bizon {
60e7300d04SMaxime Bizon 	u32 mask;
61e7300d04SMaxime Bizon 
62e7300d04SMaxime Bizon 	if (BCMCPU_IS_6338())
63e7300d04SMaxime Bizon 		mask = CKCTL_6338_ENET_EN;
64e7300d04SMaxime Bizon 	else if (BCMCPU_IS_6345())
65e7300d04SMaxime Bizon 		mask = CKCTL_6345_ENET_EN;
66e7300d04SMaxime Bizon 	else if (BCMCPU_IS_6348())
67e7300d04SMaxime Bizon 		mask = CKCTL_6348_ENET_EN;
68e7300d04SMaxime Bizon 	else
69e7300d04SMaxime Bizon 		/* BCMCPU_IS_6358 */
70e7300d04SMaxime Bizon 		mask = CKCTL_6358_EMUSB_EN;
71e7300d04SMaxime Bizon 	bcm_hwclock_set(mask, enable);
72e7300d04SMaxime Bizon }
73e7300d04SMaxime Bizon 
74e7300d04SMaxime Bizon static struct clk clk_enet_misc = {
75e7300d04SMaxime Bizon 	.set	= enet_misc_set,
76e7300d04SMaxime Bizon };
77e7300d04SMaxime Bizon 
78e7300d04SMaxime Bizon /*
79c024e8f6SBhaskar Chowdhury  * Ethernet MAC clocks: only relevant on 6358, silently enable misc
80e7300d04SMaxime Bizon  * clocks
81e7300d04SMaxime Bizon  */
enetx_set(struct clk * clk,int enable)82e7300d04SMaxime Bizon static void enetx_set(struct clk *clk, int enable)
83e7300d04SMaxime Bizon {
84e7300d04SMaxime Bizon 	if (enable)
85e7300d04SMaxime Bizon 		clk_enable_unlocked(&clk_enet_misc);
86e7300d04SMaxime Bizon 	else
87e7300d04SMaxime Bizon 		clk_disable_unlocked(&clk_enet_misc);
88e7300d04SMaxime Bizon 
897b933421SFlorian Fainelli 	if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
90e7300d04SMaxime Bizon 		u32 mask;
91e7300d04SMaxime Bizon 
92e7300d04SMaxime Bizon 		if (clk->id == 0)
93e7300d04SMaxime Bizon 			mask = CKCTL_6358_ENET0_EN;
94e7300d04SMaxime Bizon 		else
95e7300d04SMaxime Bizon 			mask = CKCTL_6358_ENET1_EN;
96e7300d04SMaxime Bizon 		bcm_hwclock_set(mask, enable);
97e7300d04SMaxime Bizon 	}
98e7300d04SMaxime Bizon }
99e7300d04SMaxime Bizon 
100e7300d04SMaxime Bizon static struct clk clk_enet0 = {
101e7300d04SMaxime Bizon 	.id	= 0,
102e7300d04SMaxime Bizon 	.set	= enetx_set,
103e7300d04SMaxime Bizon };
104e7300d04SMaxime Bizon 
105e7300d04SMaxime Bizon static struct clk clk_enet1 = {
106e7300d04SMaxime Bizon 	.id	= 1,
107e7300d04SMaxime Bizon 	.set	= enetx_set,
108e7300d04SMaxime Bizon };
109e7300d04SMaxime Bizon 
110e7300d04SMaxime Bizon /*
111e7300d04SMaxime Bizon  * Ethernet PHY clock
112e7300d04SMaxime Bizon  */
ephy_set(struct clk * clk,int enable)113e7300d04SMaxime Bizon static void ephy_set(struct clk *clk, int enable)
114e7300d04SMaxime Bizon {
1157b933421SFlorian Fainelli 	if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
116e7300d04SMaxime Bizon 		bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
117e7300d04SMaxime Bizon }
118e7300d04SMaxime Bizon 
119e7300d04SMaxime Bizon 
120e7300d04SMaxime Bizon static struct clk clk_ephy = {
121e7300d04SMaxime Bizon 	.set	= ephy_set,
122e7300d04SMaxime Bizon };
123e7300d04SMaxime Bizon 
124e7300d04SMaxime Bizon /*
125072916f5SJonas Gorski  * Ethernet switch SAR clock
126072916f5SJonas Gorski  */
swpkt_sar_set(struct clk * clk,int enable)127072916f5SJonas Gorski static void swpkt_sar_set(struct clk *clk, int enable)
128072916f5SJonas Gorski {
129072916f5SJonas Gorski 	if (BCMCPU_IS_6368())
130072916f5SJonas Gorski 		bcm_hwclock_set(CKCTL_6368_SWPKT_SAR_EN, enable);
131072916f5SJonas Gorski 	else
132072916f5SJonas Gorski 		return;
133072916f5SJonas Gorski }
134072916f5SJonas Gorski 
135072916f5SJonas Gorski static struct clk clk_swpkt_sar = {
136072916f5SJonas Gorski 	.set	= swpkt_sar_set,
137072916f5SJonas Gorski };
138072916f5SJonas Gorski 
139072916f5SJonas Gorski /*
140072916f5SJonas Gorski  * Ethernet switch USB clock
141072916f5SJonas Gorski  */
swpkt_usb_set(struct clk * clk,int enable)142072916f5SJonas Gorski static void swpkt_usb_set(struct clk *clk, int enable)
143072916f5SJonas Gorski {
144072916f5SJonas Gorski 	if (BCMCPU_IS_6368())
145072916f5SJonas Gorski 		bcm_hwclock_set(CKCTL_6368_SWPKT_USB_EN, enable);
146072916f5SJonas Gorski 	else
147072916f5SJonas Gorski 		return;
148072916f5SJonas Gorski }
149072916f5SJonas Gorski 
150072916f5SJonas Gorski static struct clk clk_swpkt_usb = {
151072916f5SJonas Gorski 	.set	= swpkt_usb_set,
152072916f5SJonas Gorski };
153072916f5SJonas Gorski 
154072916f5SJonas Gorski /*
15504712f3fSMaxime Bizon  * Ethernet switch clock
15604712f3fSMaxime Bizon  */
enetsw_set(struct clk * clk,int enable)15704712f3fSMaxime Bizon static void enetsw_set(struct clk *clk, int enable)
15804712f3fSMaxime Bizon {
159072916f5SJonas Gorski 	if (BCMCPU_IS_6328()) {
1601cd1c049SJonas Gorski 		bcm_hwclock_set(CKCTL_6328_ROBOSW_EN, enable);
161072916f5SJonas Gorski 	} else if (BCMCPU_IS_6362()) {
1621cd1c049SJonas Gorski 		bcm_hwclock_set(CKCTL_6362_ROBOSW_EN, enable);
163072916f5SJonas Gorski 	} else if (BCMCPU_IS_6368()) {
164072916f5SJonas Gorski 		if (enable) {
165072916f5SJonas Gorski 			clk_enable_unlocked(&clk_swpkt_sar);
166072916f5SJonas Gorski 			clk_enable_unlocked(&clk_swpkt_usb);
167072916f5SJonas Gorski 		} else {
168072916f5SJonas Gorski 			clk_disable_unlocked(&clk_swpkt_usb);
169072916f5SJonas Gorski 			clk_disable_unlocked(&clk_swpkt_sar);
170072916f5SJonas Gorski 		}
171072916f5SJonas Gorski 		bcm_hwclock_set(CKCTL_6368_ROBOSW_EN, enable);
172072916f5SJonas Gorski 	} else {
1731cd1c049SJonas Gorski 		return;
174072916f5SJonas Gorski 	}
1751cd1c049SJonas Gorski 
17604712f3fSMaxime Bizon 	if (enable) {
17704712f3fSMaxime Bizon 		/* reset switch core afer clock change */
178ba00e2e5SJonas Gorski 		bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1);
17904712f3fSMaxime Bizon 		msleep(10);
180ba00e2e5SJonas Gorski 		bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0);
18104712f3fSMaxime Bizon 		msleep(10);
18204712f3fSMaxime Bizon 	}
18304712f3fSMaxime Bizon }
18404712f3fSMaxime Bizon 
18504712f3fSMaxime Bizon static struct clk clk_enetsw = {
18604712f3fSMaxime Bizon 	.set	= enetsw_set,
18704712f3fSMaxime Bizon };
18804712f3fSMaxime Bizon 
18904712f3fSMaxime Bizon /*
190e7300d04SMaxime Bizon  * PCM clock
191e7300d04SMaxime Bizon  */
pcm_set(struct clk * clk,int enable)192e7300d04SMaxime Bizon static void pcm_set(struct clk *clk, int enable)
193e7300d04SMaxime Bizon {
1947b933421SFlorian Fainelli 	if (BCMCPU_IS_3368())
1957b933421SFlorian Fainelli 		bcm_hwclock_set(CKCTL_3368_PCM_EN, enable);
1967b933421SFlorian Fainelli 	if (BCMCPU_IS_6358())
197e7300d04SMaxime Bizon 		bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
198e7300d04SMaxime Bizon }
199e7300d04SMaxime Bizon 
200e7300d04SMaxime Bizon static struct clk clk_pcm = {
201e7300d04SMaxime Bizon 	.set	= pcm_set,
202e7300d04SMaxime Bizon };
203e7300d04SMaxime Bizon 
204e7300d04SMaxime Bizon /*
205e7300d04SMaxime Bizon  * USB host clock
206e7300d04SMaxime Bizon  */
usbh_set(struct clk * clk,int enable)207e7300d04SMaxime Bizon static void usbh_set(struct clk *clk, int enable)
208e7300d04SMaxime Bizon {
209dd89d60cSKevin Cernekee 	if (BCMCPU_IS_6328())
210dd89d60cSKevin Cernekee 		bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
211dd89d60cSKevin Cernekee 	else if (BCMCPU_IS_6348())
212e7300d04SMaxime Bizon 		bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
2131cd1c049SJonas Gorski 	else if (BCMCPU_IS_6362())
2141cd1c049SJonas Gorski 		bcm_hwclock_set(CKCTL_6362_USBH_EN, enable);
21504712f3fSMaxime Bizon 	else if (BCMCPU_IS_6368())
216d9831a41SFlorian Fainelli 		bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
217e7300d04SMaxime Bizon }
218e7300d04SMaxime Bizon 
219e7300d04SMaxime Bizon static struct clk clk_usbh = {
220e7300d04SMaxime Bizon 	.set	= usbh_set,
221e7300d04SMaxime Bizon };
222e7300d04SMaxime Bizon 
223e7300d04SMaxime Bizon /*
224dd89d60cSKevin Cernekee  * USB device clock
225dd89d60cSKevin Cernekee  */
usbd_set(struct clk * clk,int enable)226dd89d60cSKevin Cernekee static void usbd_set(struct clk *clk, int enable)
227dd89d60cSKevin Cernekee {
228dd89d60cSKevin Cernekee 	if (BCMCPU_IS_6328())
229dd89d60cSKevin Cernekee 		bcm_hwclock_set(CKCTL_6328_USBD_EN, enable);
2301cd1c049SJonas Gorski 	else if (BCMCPU_IS_6362())
2311cd1c049SJonas Gorski 		bcm_hwclock_set(CKCTL_6362_USBD_EN, enable);
232dd89d60cSKevin Cernekee 	else if (BCMCPU_IS_6368())
233dd89d60cSKevin Cernekee 		bcm_hwclock_set(CKCTL_6368_USBD_EN, enable);
234dd89d60cSKevin Cernekee }
235dd89d60cSKevin Cernekee 
236dd89d60cSKevin Cernekee static struct clk clk_usbd = {
237dd89d60cSKevin Cernekee 	.set	= usbd_set,
238dd89d60cSKevin Cernekee };
239dd89d60cSKevin Cernekee 
240dd89d60cSKevin Cernekee /*
241e7300d04SMaxime Bizon  * SPI clock
242e7300d04SMaxime Bizon  */
spi_set(struct clk * clk,int enable)243e7300d04SMaxime Bizon static void spi_set(struct clk *clk, int enable)
244e7300d04SMaxime Bizon {
245e7300d04SMaxime Bizon 	u32 mask;
246e7300d04SMaxime Bizon 
247e7300d04SMaxime Bizon 	if (BCMCPU_IS_6338())
248e7300d04SMaxime Bizon 		mask = CKCTL_6338_SPI_EN;
249e7300d04SMaxime Bizon 	else if (BCMCPU_IS_6348())
250e7300d04SMaxime Bizon 		mask = CKCTL_6348_SPI_EN;
2517b933421SFlorian Fainelli 	else if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
252e7300d04SMaxime Bizon 		mask = CKCTL_6358_SPI_EN;
25308a41d12SJonas Gorski 	else if (BCMCPU_IS_6362())
25408a41d12SJonas Gorski 		mask = CKCTL_6362_SPI_EN;
25519372b24SFlorian Fainelli 	else
25619372b24SFlorian Fainelli 		/* BCMCPU_IS_6368 */
25719372b24SFlorian Fainelli 		mask = CKCTL_6368_SPI_EN;
258e7300d04SMaxime Bizon 	bcm_hwclock_set(mask, enable);
259e7300d04SMaxime Bizon }
260e7300d04SMaxime Bizon 
261e7300d04SMaxime Bizon static struct clk clk_spi = {
262e7300d04SMaxime Bizon 	.set	= spi_set,
263e7300d04SMaxime Bizon };
264e7300d04SMaxime Bizon 
265e7300d04SMaxime Bizon /*
2660ebe8aaeSJonas Gorski  * HSSPI clock
2670ebe8aaeSJonas Gorski  */
hsspi_set(struct clk * clk,int enable)2680ebe8aaeSJonas Gorski static void hsspi_set(struct clk *clk, int enable)
2690ebe8aaeSJonas Gorski {
2700ebe8aaeSJonas Gorski 	u32 mask;
2710ebe8aaeSJonas Gorski 
2720ebe8aaeSJonas Gorski 	if (BCMCPU_IS_6328())
2730ebe8aaeSJonas Gorski 		mask = CKCTL_6328_HSSPI_EN;
2740ebe8aaeSJonas Gorski 	else if (BCMCPU_IS_6362())
2750ebe8aaeSJonas Gorski 		mask = CKCTL_6362_HSSPI_EN;
2760ebe8aaeSJonas Gorski 	else
2770ebe8aaeSJonas Gorski 		return;
2780ebe8aaeSJonas Gorski 
2790ebe8aaeSJonas Gorski 	bcm_hwclock_set(mask, enable);
2800ebe8aaeSJonas Gorski }
2810ebe8aaeSJonas Gorski 
2820ebe8aaeSJonas Gorski static struct clk clk_hsspi = {
2830ebe8aaeSJonas Gorski 	.set	= hsspi_set,
2840ebe8aaeSJonas Gorski };
2850ebe8aaeSJonas Gorski 
2865d691036SJonas Gorski /*
2875d691036SJonas Gorski  * HSSPI PLL
2885d691036SJonas Gorski  */
2895d691036SJonas Gorski static struct clk clk_hsspi_pll;
2900ebe8aaeSJonas Gorski 
2910ebe8aaeSJonas Gorski /*
29204712f3fSMaxime Bizon  * XTM clock
29304712f3fSMaxime Bizon  */
xtm_set(struct clk * clk,int enable)29404712f3fSMaxime Bizon static void xtm_set(struct clk *clk, int enable)
29504712f3fSMaxime Bizon {
29604712f3fSMaxime Bizon 	if (!BCMCPU_IS_6368())
29704712f3fSMaxime Bizon 		return;
29804712f3fSMaxime Bizon 
299072916f5SJonas Gorski 	if (enable)
300072916f5SJonas Gorski 		clk_enable_unlocked(&clk_swpkt_sar);
301072916f5SJonas Gorski 	else
302072916f5SJonas Gorski 		clk_disable_unlocked(&clk_swpkt_sar);
303072916f5SJonas Gorski 
304072916f5SJonas Gorski 	bcm_hwclock_set(CKCTL_6368_SAR_EN, enable);
30504712f3fSMaxime Bizon 
30604712f3fSMaxime Bizon 	if (enable) {
30704712f3fSMaxime Bizon 		/* reset sar core afer clock change */
308ba00e2e5SJonas Gorski 		bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1);
30904712f3fSMaxime Bizon 		mdelay(1);
310ba00e2e5SJonas Gorski 		bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0);
31104712f3fSMaxime Bizon 		mdelay(1);
31204712f3fSMaxime Bizon 	}
31304712f3fSMaxime Bizon }
31404712f3fSMaxime Bizon 
31504712f3fSMaxime Bizon 
31604712f3fSMaxime Bizon static struct clk clk_xtm = {
31704712f3fSMaxime Bizon 	.set	= xtm_set,
31804712f3fSMaxime Bizon };
31904712f3fSMaxime Bizon 
32004712f3fSMaxime Bizon /*
3210b55561bSFlorian Fainelli  * IPsec clock
3220b55561bSFlorian Fainelli  */
ipsec_set(struct clk * clk,int enable)3230b55561bSFlorian Fainelli static void ipsec_set(struct clk *clk, int enable)
3240b55561bSFlorian Fainelli {
3251cd1c049SJonas Gorski 	if (BCMCPU_IS_6362())
3261cd1c049SJonas Gorski 		bcm_hwclock_set(CKCTL_6362_IPSEC_EN, enable);
3271cd1c049SJonas Gorski 	else if (BCMCPU_IS_6368())
3280b55561bSFlorian Fainelli 		bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable);
3290b55561bSFlorian Fainelli }
3300b55561bSFlorian Fainelli 
3310b55561bSFlorian Fainelli static struct clk clk_ipsec = {
3320b55561bSFlorian Fainelli 	.set	= ipsec_set,
3330b55561bSFlorian Fainelli };
3340b55561bSFlorian Fainelli 
3350b55561bSFlorian Fainelli /*
336f2d1035eSJonas Gorski  * PCIe clock
337f2d1035eSJonas Gorski  */
338f2d1035eSJonas Gorski 
pcie_set(struct clk * clk,int enable)339f2d1035eSJonas Gorski static void pcie_set(struct clk *clk, int enable)
340f2d1035eSJonas Gorski {
3411cd1c049SJonas Gorski 	if (BCMCPU_IS_6328())
342f2d1035eSJonas Gorski 		bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable);
3431cd1c049SJonas Gorski 	else if (BCMCPU_IS_6362())
3441cd1c049SJonas Gorski 		bcm_hwclock_set(CKCTL_6362_PCIE_EN, enable);
345f2d1035eSJonas Gorski }
346f2d1035eSJonas Gorski 
347f2d1035eSJonas Gorski static struct clk clk_pcie = {
348f2d1035eSJonas Gorski 	.set	= pcie_set,
349f2d1035eSJonas Gorski };
350f2d1035eSJonas Gorski 
351f2d1035eSJonas Gorski /*
352e7300d04SMaxime Bizon  * Internal peripheral clock
353e7300d04SMaxime Bizon  */
354e7300d04SMaxime Bizon static struct clk clk_periph = {
355e7300d04SMaxime Bizon 	.rate	= (50 * 1000 * 1000),
356e7300d04SMaxime Bizon };
357e7300d04SMaxime Bizon 
358e7300d04SMaxime Bizon 
359e7300d04SMaxime Bizon /*
360e7300d04SMaxime Bizon  * Linux clock API implementation
361e7300d04SMaxime Bizon  */
clk_enable(struct clk * clk)362e7300d04SMaxime Bizon int clk_enable(struct clk *clk)
363e7300d04SMaxime Bizon {
364*ee9ef11bSAnastasia Belova 	if (!clk)
365*ee9ef11bSAnastasia Belova 		return 0;
366e7300d04SMaxime Bizon 	mutex_lock(&clocks_mutex);
367e7300d04SMaxime Bizon 	clk_enable_unlocked(clk);
368e7300d04SMaxime Bizon 	mutex_unlock(&clocks_mutex);
369e7300d04SMaxime Bizon 	return 0;
370e7300d04SMaxime Bizon }
371e7300d04SMaxime Bizon 
372e7300d04SMaxime Bizon EXPORT_SYMBOL(clk_enable);
373e7300d04SMaxime Bizon 
clk_disable(struct clk * clk)374e7300d04SMaxime Bizon void clk_disable(struct clk *clk)
375e7300d04SMaxime Bizon {
37600ca0250SMasahiro Yamada 	if (!clk)
37700ca0250SMasahiro Yamada 		return;
37800ca0250SMasahiro Yamada 
379e7300d04SMaxime Bizon 	mutex_lock(&clocks_mutex);
380e7300d04SMaxime Bizon 	clk_disable_unlocked(clk);
381e7300d04SMaxime Bizon 	mutex_unlock(&clocks_mutex);
382e7300d04SMaxime Bizon }
383e7300d04SMaxime Bizon 
384e7300d04SMaxime Bizon EXPORT_SYMBOL(clk_disable);
385e7300d04SMaxime Bizon 
clk_get_parent(struct clk * clk)386e8f67482SRandy Dunlap struct clk *clk_get_parent(struct clk *clk)
387e8f67482SRandy Dunlap {
388e8f67482SRandy Dunlap 	return NULL;
389e8f67482SRandy Dunlap }
390e8f67482SRandy Dunlap EXPORT_SYMBOL(clk_get_parent);
391e8f67482SRandy Dunlap 
clk_set_parent(struct clk * clk,struct clk * parent)3926f03055dSRandy Dunlap int clk_set_parent(struct clk *clk, struct clk *parent)
3936f03055dSRandy Dunlap {
3946f03055dSRandy Dunlap 	return 0;
3956f03055dSRandy Dunlap }
3966f03055dSRandy Dunlap EXPORT_SYMBOL(clk_set_parent);
3976f03055dSRandy Dunlap 
clk_get_rate(struct clk * clk)398e7300d04SMaxime Bizon unsigned long clk_get_rate(struct clk *clk)
399e7300d04SMaxime Bizon {
4001b495faeSJonas Gorski 	if (!clk)
4011b495faeSJonas Gorski 		return 0;
4021b495faeSJonas Gorski 
403e7300d04SMaxime Bizon 	return clk->rate;
404e7300d04SMaxime Bizon }
405e7300d04SMaxime Bizon 
406e7300d04SMaxime Bizon EXPORT_SYMBOL(clk_get_rate);
407e7300d04SMaxime Bizon 
clk_set_rate(struct clk * clk,unsigned long rate)4087aa2d052SMarkos Chandras int clk_set_rate(struct clk *clk, unsigned long rate)
4097aa2d052SMarkos Chandras {
4107aa2d052SMarkos Chandras 	return 0;
4117aa2d052SMarkos Chandras }
4127aa2d052SMarkos Chandras EXPORT_SYMBOL_GPL(clk_set_rate);
4137aa2d052SMarkos Chandras 
clk_round_rate(struct clk * clk,unsigned long rate)4147aa2d052SMarkos Chandras long clk_round_rate(struct clk *clk, unsigned long rate)
4157aa2d052SMarkos Chandras {
4167aa2d052SMarkos Chandras 	return 0;
4177aa2d052SMarkos Chandras }
4187aa2d052SMarkos Chandras EXPORT_SYMBOL_GPL(clk_round_rate);
4197aa2d052SMarkos Chandras 
420c5af3c2dSJonas Gorski static struct clk_lookup bcm3368_clks[] = {
421c5af3c2dSJonas Gorski 	/* fixed rate clocks */
422c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "periph", &clk_periph),
423243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
424243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
425c5af3c2dSJonas Gorski 	/* gated clocks */
426c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
427c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
428c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
429c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
430c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
431c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "spi", &clk_spi),
432c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "pcm", &clk_pcm),
433ef423515SJonas Gorski 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
434ef423515SJonas Gorski 	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
435c5af3c2dSJonas Gorski };
436e7300d04SMaxime Bizon 
437c5af3c2dSJonas Gorski static struct clk_lookup bcm6328_clks[] = {
438c5af3c2dSJonas Gorski 	/* fixed rate clocks */
439c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "periph", &clk_periph),
440243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
441243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
4425d691036SJonas Gorski 	CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
443c5af3c2dSJonas Gorski 	/* gated clocks */
444c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
445c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
446c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
447c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
448c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "pcie", &clk_pcie),
449c5af3c2dSJonas Gorski };
450e7300d04SMaxime Bizon 
451c5af3c2dSJonas Gorski static struct clk_lookup bcm6338_clks[] = {
452c5af3c2dSJonas Gorski 	/* fixed rate clocks */
453c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "periph", &clk_periph),
454243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
455c5af3c2dSJonas Gorski 	/* gated clocks */
456c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
457c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
458c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
459c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
460c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
461c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "spi", &clk_spi),
462ef423515SJonas Gorski 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
463c5af3c2dSJonas Gorski };
464e7300d04SMaxime Bizon 
465c5af3c2dSJonas Gorski static struct clk_lookup bcm6345_clks[] = {
466c5af3c2dSJonas Gorski 	/* fixed rate clocks */
467c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "periph", &clk_periph),
468243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
469c5af3c2dSJonas Gorski 	/* gated clocks */
470c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
471c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
472c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
473c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
474c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
475c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "spi", &clk_spi),
476ef423515SJonas Gorski 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
477c5af3c2dSJonas Gorski };
478c5af3c2dSJonas Gorski 
479c5af3c2dSJonas Gorski static struct clk_lookup bcm6348_clks[] = {
480c5af3c2dSJonas Gorski 	/* fixed rate clocks */
481c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "periph", &clk_periph),
482243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
483c5af3c2dSJonas Gorski 	/* gated clocks */
484c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
485c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
486c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
487c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
488c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
489c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "spi", &clk_spi),
490ef423515SJonas Gorski 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
491ef423515SJonas Gorski 	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet_misc),
492c5af3c2dSJonas Gorski };
493c5af3c2dSJonas Gorski 
494c5af3c2dSJonas Gorski static struct clk_lookup bcm6358_clks[] = {
495c5af3c2dSJonas Gorski 	/* fixed rate clocks */
496c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "periph", &clk_periph),
497243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
498243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
499c5af3c2dSJonas Gorski 	/* gated clocks */
500c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
501c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
502c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
503c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
504c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
505c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "spi", &clk_spi),
506c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "pcm", &clk_pcm),
507072916f5SJonas Gorski 	CLKDEV_INIT(NULL, "swpkt_sar", &clk_swpkt_sar),
508072916f5SJonas Gorski 	CLKDEV_INIT(NULL, "swpkt_usb", &clk_swpkt_usb),
509ef423515SJonas Gorski 	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
510ef423515SJonas Gorski 	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
511c5af3c2dSJonas Gorski };
512c5af3c2dSJonas Gorski 
513c5af3c2dSJonas Gorski static struct clk_lookup bcm6362_clks[] = {
514c5af3c2dSJonas Gorski 	/* fixed rate clocks */
515c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "periph", &clk_periph),
516243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
517243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
5185d691036SJonas Gorski 	CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
519c5af3c2dSJonas Gorski 	/* gated clocks */
520c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
521c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
522c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
523c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "spi", &clk_spi),
524c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
525c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "pcie", &clk_pcie),
526c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
527c5af3c2dSJonas Gorski };
528c5af3c2dSJonas Gorski 
529c5af3c2dSJonas Gorski static struct clk_lookup bcm6368_clks[] = {
530c5af3c2dSJonas Gorski 	/* fixed rate clocks */
531c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "periph", &clk_periph),
532243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
533243fa279SJonas Gorski 	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
534c5af3c2dSJonas Gorski 	/* gated clocks */
535c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
536c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
537c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
538c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "spi", &clk_spi),
539c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "xtm", &clk_xtm),
540c5af3c2dSJonas Gorski 	CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
541c5af3c2dSJonas Gorski };
54226b8c07fSJonas Gorski 
54326b8c07fSJonas Gorski #define HSSPI_PLL_HZ_6328	133333333
54426b8c07fSJonas Gorski #define HSSPI_PLL_HZ_6362	400000000
54526b8c07fSJonas Gorski 
bcm63xx_clk_init(void)54626b8c07fSJonas Gorski static int __init bcm63xx_clk_init(void)
54726b8c07fSJonas Gorski {
54826b8c07fSJonas Gorski 	switch (bcm63xx_get_cpu_id()) {
549c5af3c2dSJonas Gorski 	case BCM3368_CPU_ID:
550c5af3c2dSJonas Gorski 		clkdev_add_table(bcm3368_clks, ARRAY_SIZE(bcm3368_clks));
551c5af3c2dSJonas Gorski 		break;
55226b8c07fSJonas Gorski 	case BCM6328_CPU_ID:
5535d691036SJonas Gorski 		clk_hsspi_pll.rate = HSSPI_PLL_HZ_6328;
554c5af3c2dSJonas Gorski 		clkdev_add_table(bcm6328_clks, ARRAY_SIZE(bcm6328_clks));
555c5af3c2dSJonas Gorski 		break;
556c5af3c2dSJonas Gorski 	case BCM6338_CPU_ID:
557c5af3c2dSJonas Gorski 		clkdev_add_table(bcm6338_clks, ARRAY_SIZE(bcm6338_clks));
558c5af3c2dSJonas Gorski 		break;
559c5af3c2dSJonas Gorski 	case BCM6345_CPU_ID:
560c5af3c2dSJonas Gorski 		clkdev_add_table(bcm6345_clks, ARRAY_SIZE(bcm6345_clks));
561c5af3c2dSJonas Gorski 		break;
562c5af3c2dSJonas Gorski 	case BCM6348_CPU_ID:
563c5af3c2dSJonas Gorski 		clkdev_add_table(bcm6348_clks, ARRAY_SIZE(bcm6348_clks));
564c5af3c2dSJonas Gorski 		break;
565c5af3c2dSJonas Gorski 	case BCM6358_CPU_ID:
566c5af3c2dSJonas Gorski 		clkdev_add_table(bcm6358_clks, ARRAY_SIZE(bcm6358_clks));
56726b8c07fSJonas Gorski 		break;
56826b8c07fSJonas Gorski 	case BCM6362_CPU_ID:
5695d691036SJonas Gorski 		clk_hsspi_pll.rate = HSSPI_PLL_HZ_6362;
570c5af3c2dSJonas Gorski 		clkdev_add_table(bcm6362_clks, ARRAY_SIZE(bcm6362_clks));
571c5af3c2dSJonas Gorski 		break;
572c5af3c2dSJonas Gorski 	case BCM6368_CPU_ID:
573c5af3c2dSJonas Gorski 		clkdev_add_table(bcm6368_clks, ARRAY_SIZE(bcm6368_clks));
57426b8c07fSJonas Gorski 		break;
57526b8c07fSJonas Gorski 	}
57626b8c07fSJonas Gorski 
57726b8c07fSJonas Gorski 	return 0;
57826b8c07fSJonas Gorski }
57926b8c07fSJonas Gorski arch_initcall(bcm63xx_clk_init);
580