Merge tag 'fsnotify_for_v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / arch / mips / bcm63xx / clk.c
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
9 #include <linux/init.h>
10 #include <linux/export.h>
11 #include <linux/mutex.h>
12 #include <linux/err.h>
13 #include <linux/clk.h>
14 #include <linux/clkdev.h>
15 #include <linux/delay.h>
16 #include <bcm63xx_cpu.h>
17 #include <bcm63xx_io.h>
18 #include <bcm63xx_regs.h>
19 #include <bcm63xx_reset.h>
20
21 struct clk {
22         void            (*set)(struct clk *, int);
23         unsigned int    rate;
24         unsigned int    usage;
25         int             id;
26 };
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 /*
79  * Ethernet MAC clocks: only revelant on 6358, silently enable misc
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
89         if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
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 {
115         if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
116                 bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
117 }
118
119
120 static struct clk clk_ephy = {
121         .set    = ephy_set,
122 };
123
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
154 /*
155  * Ethernet switch clock
156  */
157 static void enetsw_set(struct clk *clk, int enable)
158 {
159         if (BCMCPU_IS_6328()) {
160                 bcm_hwclock_set(CKCTL_6328_ROBOSW_EN, enable);
161         } else if (BCMCPU_IS_6362()) {
162                 bcm_hwclock_set(CKCTL_6362_ROBOSW_EN, enable);
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 {
173                 return;
174         }
175
176         if (enable) {
177                 /* reset switch core afer clock change */
178                 bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1);
179                 msleep(10);
180                 bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0);
181                 msleep(10);
182         }
183 }
184
185 static struct clk clk_enetsw = {
186         .set    = enetsw_set,
187 };
188
189 /*
190  * PCM clock
191  */
192 static void pcm_set(struct clk *clk, int enable)
193 {
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);
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 {
209         if (BCMCPU_IS_6328())
210                 bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
211         else if (BCMCPU_IS_6348())
212                 bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
213         else if (BCMCPU_IS_6362())
214                 bcm_hwclock_set(CKCTL_6362_USBH_EN, enable);
215         else if (BCMCPU_IS_6368())
216                 bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
217 }
218
219 static struct clk clk_usbh = {
220         .set    = usbh_set,
221 };
222
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);
230         else if (BCMCPU_IS_6362())
231                 bcm_hwclock_set(CKCTL_6362_USBD_EN, enable);
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
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;
251         else if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
252                 mask = CKCTL_6358_SPI_EN;
253         else if (BCMCPU_IS_6362())
254                 mask = CKCTL_6362_SPI_EN;
255         else
256                 /* BCMCPU_IS_6368 */
257                 mask = CKCTL_6368_SPI_EN;
258         bcm_hwclock_set(mask, enable);
259 }
260
261 static struct clk clk_spi = {
262         .set    = spi_set,
263 };
264
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
286 /*
287  * HSSPI PLL
288  */
289 static struct clk clk_hsspi_pll;
290
291 /*
292  * XTM clock
293  */
294 static void xtm_set(struct clk *clk, int enable)
295 {
296         if (!BCMCPU_IS_6368())
297                 return;
298
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);
305
306         if (enable) {
307                 /* reset sar core afer clock change */
308                 bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1);
309                 mdelay(1);
310                 bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0);
311                 mdelay(1);
312         }
313 }
314
315
316 static struct clk clk_xtm = {
317         .set    = xtm_set,
318 };
319
320 /*
321  * IPsec clock
322  */
323 static void ipsec_set(struct clk *clk, int enable)
324 {
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);
329 }
330
331 static struct clk clk_ipsec = {
332         .set    = ipsec_set,
333 };
334
335 /*
336  * PCIe clock
337  */
338
339 static void pcie_set(struct clk *clk, int enable)
340 {
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);
345 }
346
347 static struct clk clk_pcie = {
348         .set    = pcie_set,
349 };
350
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 {
374         if (!clk)
375                 return;
376
377         mutex_lock(&clocks_mutex);
378         clk_disable_unlocked(clk);
379         mutex_unlock(&clocks_mutex);
380 }
381
382 EXPORT_SYMBOL(clk_disable);
383
384 unsigned long clk_get_rate(struct clk *clk)
385 {
386         if (!clk)
387                 return 0;
388
389         return clk->rate;
390 }
391
392 EXPORT_SYMBOL(clk_get_rate);
393
394 int clk_set_rate(struct clk *clk, unsigned long rate)
395 {
396         return 0;
397 }
398 EXPORT_SYMBOL_GPL(clk_set_rate);
399
400 long clk_round_rate(struct clk *clk, unsigned long rate)
401 {
402         return 0;
403 }
404 EXPORT_SYMBOL_GPL(clk_round_rate);
405
406 static struct clk_lookup bcm3368_clks[] = {
407         /* fixed rate clocks */
408         CLKDEV_INIT(NULL, "periph", &clk_periph),
409         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
410         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
411         /* gated clocks */
412         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
413         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
414         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
415         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
416         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
417         CLKDEV_INIT(NULL, "spi", &clk_spi),
418         CLKDEV_INIT(NULL, "pcm", &clk_pcm),
419         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
420         CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
421 };
422
423 static struct clk_lookup bcm6328_clks[] = {
424         /* fixed rate clocks */
425         CLKDEV_INIT(NULL, "periph", &clk_periph),
426         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
427         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
428         CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
429         /* gated clocks */
430         CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
431         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
432         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
433         CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
434         CLKDEV_INIT(NULL, "pcie", &clk_pcie),
435 };
436
437 static struct clk_lookup bcm6338_clks[] = {
438         /* fixed rate clocks */
439         CLKDEV_INIT(NULL, "periph", &clk_periph),
440         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
441         /* gated clocks */
442         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
443         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
444         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
445         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
446         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
447         CLKDEV_INIT(NULL, "spi", &clk_spi),
448         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
449 };
450
451 static struct clk_lookup bcm6345_clks[] = {
452         /* fixed rate clocks */
453         CLKDEV_INIT(NULL, "periph", &clk_periph),
454         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
455         /* gated clocks */
456         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
457         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
458         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
459         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
460         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
461         CLKDEV_INIT(NULL, "spi", &clk_spi),
462         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
463 };
464
465 static struct clk_lookup bcm6348_clks[] = {
466         /* fixed rate clocks */
467         CLKDEV_INIT(NULL, "periph", &clk_periph),
468         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
469         /* gated clocks */
470         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
471         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
472         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
473         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
474         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
475         CLKDEV_INIT(NULL, "spi", &clk_spi),
476         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
477         CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet_misc),
478 };
479
480 static struct clk_lookup bcm6358_clks[] = {
481         /* fixed rate clocks */
482         CLKDEV_INIT(NULL, "periph", &clk_periph),
483         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
484         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
485         /* gated clocks */
486         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
487         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
488         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
489         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
490         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
491         CLKDEV_INIT(NULL, "spi", &clk_spi),
492         CLKDEV_INIT(NULL, "pcm", &clk_pcm),
493         CLKDEV_INIT(NULL, "swpkt_sar", &clk_swpkt_sar),
494         CLKDEV_INIT(NULL, "swpkt_usb", &clk_swpkt_usb),
495         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
496         CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
497 };
498
499 static struct clk_lookup bcm6362_clks[] = {
500         /* fixed rate clocks */
501         CLKDEV_INIT(NULL, "periph", &clk_periph),
502         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
503         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
504         CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
505         /* gated clocks */
506         CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
507         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
508         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
509         CLKDEV_INIT(NULL, "spi", &clk_spi),
510         CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
511         CLKDEV_INIT(NULL, "pcie", &clk_pcie),
512         CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
513 };
514
515 static struct clk_lookup bcm6368_clks[] = {
516         /* fixed rate clocks */
517         CLKDEV_INIT(NULL, "periph", &clk_periph),
518         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
519         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
520         /* gated clocks */
521         CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
522         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
523         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
524         CLKDEV_INIT(NULL, "spi", &clk_spi),
525         CLKDEV_INIT(NULL, "xtm", &clk_xtm),
526         CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
527 };
528
529 #define HSSPI_PLL_HZ_6328       133333333
530 #define HSSPI_PLL_HZ_6362       400000000
531
532 static int __init bcm63xx_clk_init(void)
533 {
534         switch (bcm63xx_get_cpu_id()) {
535         case BCM3368_CPU_ID:
536                 clkdev_add_table(bcm3368_clks, ARRAY_SIZE(bcm3368_clks));
537                 break;
538         case BCM6328_CPU_ID:
539                 clk_hsspi_pll.rate = HSSPI_PLL_HZ_6328;
540                 clkdev_add_table(bcm6328_clks, ARRAY_SIZE(bcm6328_clks));
541                 break;
542         case BCM6338_CPU_ID:
543                 clkdev_add_table(bcm6338_clks, ARRAY_SIZE(bcm6338_clks));
544                 break;
545         case BCM6345_CPU_ID:
546                 clkdev_add_table(bcm6345_clks, ARRAY_SIZE(bcm6345_clks));
547                 break;
548         case BCM6348_CPU_ID:
549                 clkdev_add_table(bcm6348_clks, ARRAY_SIZE(bcm6348_clks));
550                 break;
551         case BCM6358_CPU_ID:
552                 clkdev_add_table(bcm6358_clks, ARRAY_SIZE(bcm6358_clks));
553                 break;
554         case BCM6362_CPU_ID:
555                 clk_hsspi_pll.rate = HSSPI_PLL_HZ_6362;
556                 clkdev_add_table(bcm6362_clks, ARRAY_SIZE(bcm6362_clks));
557                 break;
558         case BCM6368_CPU_ID:
559                 clkdev_add_table(bcm6368_clks, ARRAY_SIZE(bcm6368_clks));
560                 break;
561         }
562
563         return 0;
564 }
565 arch_initcall(bcm63xx_clk_init);