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