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