1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/bitops.h>
15#include <linux/clk.h>
16#include <linux/clk-provider.h>
17#include <linux/clkdev.h>
18#include <linux/device.h>
19#include <linux/errno.h>
20#include <linux/io.h>
21#include <linux/of.h>
22#include <linux/of_address.h>
23
24#include <asm/mpc5121.h>
25#include <dt-bindings/clock/mpc512x-clock.h>
26
27#include "mpc512x.h"
28
29
30enum {
31 MCLK_IDX_MUX0,
32 MCLK_IDX_EN0,
33 MCLK_IDX_DIV0,
34 MCLK_MAX_IDX,
35};
36
37#define NR_PSCS 12
38#define NR_MSCANS 4
39#define NR_SPDIFS 1
40#define NR_OUTCLK 4
41#define NR_MCLKS (NR_PSCS + NR_MSCANS + NR_SPDIFS + NR_OUTCLK)
42
43
44enum {
45
46 MPC512x_CLK_START_PRIVATE = MPC512x_CLK_LAST_PUBLIC,
47
48 MPC512x_CLK_DDR,
49 MPC512x_CLK_MEM,
50 MPC512x_CLK_IIM,
51
52 MPC512x_CLK_DDR_UG,
53 MPC512x_CLK_SDHC_x4,
54 MPC512x_CLK_SDHC_UG,
55 MPC512x_CLK_SDHC2_UG,
56 MPC512x_CLK_DIU_x4,
57 MPC512x_CLK_DIU_UG,
58 MPC512x_CLK_MBX_BUS_UG,
59 MPC512x_CLK_MBX_UG,
60 MPC512x_CLK_MBX_3D_UG,
61 MPC512x_CLK_PCI_UG,
62 MPC512x_CLK_NFC_UG,
63 MPC512x_CLK_LPC_UG,
64 MPC512x_CLK_SPDIF_TX_IN,
65
66 MPC512x_CLK_MCLKS_FIRST,
67 MPC512x_CLK_MCLKS_LAST = MPC512x_CLK_MCLKS_FIRST
68 + NR_MCLKS * MCLK_MAX_IDX,
69
70 MPC512x_CLK_LAST_PRIVATE,
71};
72
73
74static struct clk *clks[MPC512x_CLK_LAST_PRIVATE];
75static struct clk_onecell_data clk_data;
76
77
78static struct mpc512x_ccm __iomem *clkregs;
79static DEFINE_SPINLOCK(clklock);
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98static enum soc_type {
99 MPC512x_SOC_MPC5121,
100 MPC512x_SOC_MPC5123,
101 MPC512x_SOC_MPC5125,
102} soc;
103
104static void mpc512x_clk_determine_soc(void)
105{
106 if (of_machine_is_compatible("fsl,mpc5121")) {
107 soc = MPC512x_SOC_MPC5121;
108 return;
109 }
110 if (of_machine_is_compatible("fsl,mpc5123")) {
111 soc = MPC512x_SOC_MPC5123;
112 return;
113 }
114 if (of_machine_is_compatible("fsl,mpc5125")) {
115 soc = MPC512x_SOC_MPC5125;
116 return;
117 }
118}
119
120static bool soc_has_mbx(void)
121{
122 if (soc == MPC512x_SOC_MPC5121)
123 return true;
124 return false;
125}
126
127static bool soc_has_axe(void)
128{
129 if (soc == MPC512x_SOC_MPC5125)
130 return false;
131 return true;
132}
133
134static bool soc_has_viu(void)
135{
136 if (soc == MPC512x_SOC_MPC5125)
137 return false;
138 return true;
139}
140
141static bool soc_has_spdif(void)
142{
143 if (soc == MPC512x_SOC_MPC5125)
144 return false;
145 return true;
146}
147
148static bool soc_has_pata(void)
149{
150 if (soc == MPC512x_SOC_MPC5125)
151 return false;
152 return true;
153}
154
155static bool soc_has_sata(void)
156{
157 if (soc == MPC512x_SOC_MPC5125)
158 return false;
159 return true;
160}
161
162static bool soc_has_pci(void)
163{
164 if (soc == MPC512x_SOC_MPC5125)
165 return false;
166 return true;
167}
168
169static bool soc_has_fec2(void)
170{
171 if (soc == MPC512x_SOC_MPC5125)
172 return true;
173 return false;
174}
175
176static int soc_max_pscnum(void)
177{
178 if (soc == MPC512x_SOC_MPC5125)
179 return 10;
180 return 12;
181}
182
183static bool soc_has_sdhc2(void)
184{
185 if (soc == MPC512x_SOC_MPC5125)
186 return true;
187 return false;
188}
189
190static bool soc_has_nfc_5125(void)
191{
192 if (soc == MPC512x_SOC_MPC5125)
193 return true;
194 return false;
195}
196
197static bool soc_has_outclk(void)
198{
199 if (soc == MPC512x_SOC_MPC5125)
200 return true;
201 return false;
202}
203
204static bool soc_has_cpmf_0_bypass(void)
205{
206 if (soc == MPC512x_SOC_MPC5125)
207 return true;
208 return false;
209}
210
211static bool soc_has_mclk_mux0_canin(void)
212{
213 if (soc == MPC512x_SOC_MPC5125)
214 return true;
215 return false;
216}
217
218
219
220
221
222static inline struct clk *mpc512x_clk_fixed(const char *name, int rate)
223{
224 return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
225}
226
227static inline struct clk *mpc512x_clk_factor(
228 const char *name, const char *parent_name,
229 int mul, int div)
230{
231 int clkflags;
232
233 clkflags = CLK_SET_RATE_PARENT;
234 return clk_register_fixed_factor(NULL, name, parent_name, clkflags,
235 mul, div);
236}
237
238static inline struct clk *mpc512x_clk_divider(
239 const char *name, const char *parent_name, u8 clkflags,
240 u32 __iomem *reg, u8 pos, u8 len, int divflags)
241{
242 return clk_register_divider(NULL, name, parent_name, clkflags,
243 reg, pos, len, divflags, &clklock);
244}
245
246static inline struct clk *mpc512x_clk_divtable(
247 const char *name, const char *parent_name,
248 u32 __iomem *reg, u8 pos, u8 len,
249 const struct clk_div_table *divtab)
250{
251 u8 divflags;
252
253 divflags = 0;
254 return clk_register_divider_table(NULL, name, parent_name, 0,
255 reg, pos, len, divflags,
256 divtab, &clklock);
257}
258
259static inline struct clk *mpc512x_clk_gated(
260 const char *name, const char *parent_name,
261 u32 __iomem *reg, u8 pos)
262{
263 int clkflags;
264
265 clkflags = CLK_SET_RATE_PARENT;
266 return clk_register_gate(NULL, name, parent_name, clkflags,
267 reg, pos, 0, &clklock);
268}
269
270static inline struct clk *mpc512x_clk_muxed(const char *name,
271 const char **parent_names, int parent_count,
272 u32 __iomem *reg, u8 pos, u8 len)
273{
274 int clkflags;
275 u8 muxflags;
276
277 clkflags = CLK_SET_RATE_PARENT;
278 muxflags = 0;
279 return clk_register_mux(NULL, name,
280 parent_names, parent_count, clkflags,
281 reg, pos, len, muxflags, &clklock);
282}
283
284
285
286
287static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint8_t len)
288{
289 uint32_t val;
290
291 val = in_be32(reg);
292 val >>= pos;
293 val &= (1 << len) - 1;
294 return val;
295}
296
297
298static int get_spmf_mult(void)
299{
300 static int spmf_to_mult[] = {
301 68, 1, 12, 16, 20, 24, 28, 32,
302 36, 40, 44, 48, 52, 56, 60, 64,
303 };
304 int spmf;
305
306 spmf = get_bit_field(&clkregs->spmr, 24, 4);
307 return spmf_to_mult[spmf];
308}
309
310
311
312
313
314
315
316static int get_sys_div_x2(void)
317{
318 static int sysdiv_code_to_x2[] = {
319 4, 5, 6, 7, 8, 9, 10, 14,
320 12, 16, 18, 22, 20, 24, 26, 30,
321 28, 32, 34, 38, 36, 40, 42, 46,
322 44, 48, 50, 54, 52, 56, 58, 62,
323 60, 64, 66,
324 };
325 int divcode;
326
327 divcode = get_bit_field(&clkregs->scfr2, 26, 6);
328 return sysdiv_code_to_x2[divcode];
329}
330
331
332
333
334
335
336
337static int get_cpmf_mult_x2(void)
338{
339 static int cpmf_to_mult_x36[] = {
340
341 72, 2, 2, 3, 4, 5, 6, 7,
342 };
343 static int cpmf_to_mult_0by[] = {
344
345 2, 2, 2, 3, 4, 5, 6, 7,
346 };
347
348 int *cpmf_to_mult;
349 int cpmf;
350
351 cpmf = get_bit_field(&clkregs->spmr, 16, 4);
352 if (soc_has_cpmf_0_bypass())
353 cpmf_to_mult = cpmf_to_mult_0by;
354 else
355 cpmf_to_mult = cpmf_to_mult_x36;
356 return cpmf_to_mult[cpmf];
357}
358
359
360
361
362
363
364
365
366static const struct clk_div_table divtab_2346[] = {
367 { .val = 2, .div = 2, },
368 { .val = 3, .div = 3, },
369 { .val = 4, .div = 4, },
370 { .val = 6, .div = 6, },
371 { .div = 0, },
372};
373
374
375static const struct clk_div_table divtab_1234[] = {
376 { .val = 1, .div = 1, },
377 { .val = 2, .div = 2, },
378 { .val = 3, .div = 3, },
379 { .val = 4, .div = 4, },
380 { .div = 0, },
381};
382
383static int get_freq_from_dt(char *propname)
384{
385 struct device_node *np;
386 const unsigned int *prop;
387 int val;
388
389 val = 0;
390 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr");
391 if (np) {
392 prop = of_get_property(np, propname, NULL);
393 if (prop)
394 val = *prop;
395 of_node_put(np);
396 }
397 return val;
398}
399
400static void mpc512x_clk_preset_data(void)
401{
402 size_t i;
403
404 for (i = 0; i < ARRAY_SIZE(clks); i++)
405 clks[i] = ERR_PTR(-ENODEV);
406}
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422static void mpc512x_clk_setup_ref_clock(struct device_node *np, int bus_freq,
423 int *sys_mul, int *sys_div,
424 int *ips_div)
425{
426 struct clk *osc_clk;
427 int calc_freq;
428
429
430 *sys_mul = get_spmf_mult();
431 *sys_mul *= 2;
432 *sys_div = get_sys_div_x2();
433 *ips_div = get_bit_field(&clkregs->scfr1, 23, 3);
434
435
436 osc_clk = of_clk_get_by_name(np, "osc");
437
438
439
440
441
442
443
444
445
446 if (!IS_ERR(osc_clk)) {
447 clks[MPC512x_CLK_REF] = mpc512x_clk_factor("ref", "osc", 1, 1);
448 calc_freq = clk_get_rate(clks[MPC512x_CLK_REF]);
449 calc_freq *= *sys_mul;
450 calc_freq /= *sys_div;
451 calc_freq /= 2;
452 calc_freq /= *ips_div;
453 if (bus_freq && calc_freq != bus_freq)
454 pr_warn("calc rate %d != OF spec %d\n",
455 calc_freq, bus_freq);
456 } else {
457 calc_freq = bus_freq;
458 calc_freq *= *ips_div;
459 calc_freq *= 2;
460 calc_freq *= *sys_div;
461 calc_freq /= *sys_mul;
462 clks[MPC512x_CLK_REF] = mpc512x_clk_fixed("ref", calc_freq);
463 }
464}
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501static const char *parent_names_mux0_spdif[] = {
502 "sys", "ref", "psc-mclk-in", "spdif-tx",
503};
504
505static const char *parent_names_mux0_canin[] = {
506 "sys", "ref", "psc-mclk-in", "can-clk-in",
507};
508
509enum mclk_type {
510 MCLK_TYPE_PSC,
511 MCLK_TYPE_MSCAN,
512 MCLK_TYPE_SPDIF,
513 MCLK_TYPE_OUTCLK,
514};
515
516struct mclk_setup_data {
517 enum mclk_type type;
518 bool has_mclk1;
519 const char *name_mux0;
520 const char *name_en0;
521 const char *name_div0;
522 const char *parent_names_mux1[2];
523 const char *name_mclk;
524};
525
526#define MCLK_SETUP_DATA_PSC(id) { \
527 MCLK_TYPE_PSC, 0, \
528 "psc" #id "-mux0", \
529 "psc" #id "-en0", \
530 "psc" #id "_mclk_div", \
531 { "psc" #id "_mclk_div", "dummy", }, \
532 "psc" #id "_mclk", \
533}
534
535#define MCLK_SETUP_DATA_MSCAN(id) { \
536 MCLK_TYPE_MSCAN, 0, \
537 "mscan" #id "-mux0", \
538 "mscan" #id "-en0", \
539 "mscan" #id "_mclk_div", \
540 { "mscan" #id "_mclk_div", "dummy", }, \
541 "mscan" #id "_mclk", \
542}
543
544#define MCLK_SETUP_DATA_SPDIF { \
545 MCLK_TYPE_SPDIF, 1, \
546 "spdif-mux0", \
547 "spdif-en0", \
548 "spdif_mclk_div", \
549 { "spdif_mclk_div", "spdif-rx", }, \
550 "spdif_mclk", \
551}
552
553#define MCLK_SETUP_DATA_OUTCLK(id) { \
554 MCLK_TYPE_OUTCLK, 0, \
555 "out" #id "-mux0", \
556 "out" #id "-en0", \
557 "out" #id "_mclk_div", \
558 { "out" #id "_mclk_div", "dummy", }, \
559 "out" #id "_clk", \
560}
561
562static struct mclk_setup_data mclk_psc_data[] = {
563 MCLK_SETUP_DATA_PSC(0),
564 MCLK_SETUP_DATA_PSC(1),
565 MCLK_SETUP_DATA_PSC(2),
566 MCLK_SETUP_DATA_PSC(3),
567 MCLK_SETUP_DATA_PSC(4),
568 MCLK_SETUP_DATA_PSC(5),
569 MCLK_SETUP_DATA_PSC(6),
570 MCLK_SETUP_DATA_PSC(7),
571 MCLK_SETUP_DATA_PSC(8),
572 MCLK_SETUP_DATA_PSC(9),
573 MCLK_SETUP_DATA_PSC(10),
574 MCLK_SETUP_DATA_PSC(11),
575};
576
577static struct mclk_setup_data mclk_mscan_data[] = {
578 MCLK_SETUP_DATA_MSCAN(0),
579 MCLK_SETUP_DATA_MSCAN(1),
580 MCLK_SETUP_DATA_MSCAN(2),
581 MCLK_SETUP_DATA_MSCAN(3),
582};
583
584static struct mclk_setup_data mclk_spdif_data[] = {
585 MCLK_SETUP_DATA_SPDIF,
586};
587
588static struct mclk_setup_data mclk_outclk_data[] = {
589 MCLK_SETUP_DATA_OUTCLK(0),
590 MCLK_SETUP_DATA_OUTCLK(1),
591 MCLK_SETUP_DATA_OUTCLK(2),
592 MCLK_SETUP_DATA_OUTCLK(3),
593};
594
595
596static void mpc512x_clk_setup_mclk(struct mclk_setup_data *entry, size_t idx)
597{
598 size_t clks_idx_pub, clks_idx_int;
599 u32 __iomem *mccr_reg;
600 int div;
601
602
603 switch (entry->type) {
604 case MCLK_TYPE_PSC:
605 clks_idx_pub = MPC512x_CLK_PSC0_MCLK + idx;
606 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
607 + (idx) * MCLK_MAX_IDX;
608 mccr_reg = &clkregs->psc_ccr[idx];
609 break;
610 case MCLK_TYPE_MSCAN:
611 clks_idx_pub = MPC512x_CLK_MSCAN0_MCLK + idx;
612 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
613 + (NR_PSCS + idx) * MCLK_MAX_IDX;
614 mccr_reg = &clkregs->mscan_ccr[idx];
615 break;
616 case MCLK_TYPE_SPDIF:
617 clks_idx_pub = MPC512x_CLK_SPDIF_MCLK;
618 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
619 + (NR_PSCS + NR_MSCANS) * MCLK_MAX_IDX;
620 mccr_reg = &clkregs->spccr;
621 break;
622 case MCLK_TYPE_OUTCLK:
623 clks_idx_pub = MPC512x_CLK_OUT0_CLK + idx;
624 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
625 + (NR_PSCS + NR_MSCANS + NR_SPDIFS + idx)
626 * MCLK_MAX_IDX;
627 mccr_reg = &clkregs->out_ccr[idx];
628 break;
629 default:
630 return;
631 }
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651 div = clk_get_rate(clks[MPC512x_CLK_SYS]);
652 div /= clk_get_rate(clks[MPC512x_CLK_IPS]);
653 out_be32(mccr_reg, (0 << 16));
654 out_be32(mccr_reg, (0 << 16) | ((div - 1) << 17));
655 out_be32(mccr_reg, (1 << 16) | ((div - 1) << 17));
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675 clks[clks_idx_int + MCLK_IDX_MUX0] = mpc512x_clk_muxed(
676 entry->name_mux0,
677 soc_has_mclk_mux0_canin()
678 ? &parent_names_mux0_canin[0]
679 : &parent_names_mux0_spdif[0],
680 ARRAY_SIZE(parent_names_mux0_spdif),
681 mccr_reg, 14, 2);
682 clks[clks_idx_int + MCLK_IDX_EN0] = mpc512x_clk_gated(
683 entry->name_en0, entry->name_mux0,
684 mccr_reg, 16);
685 clks[clks_idx_int + MCLK_IDX_DIV0] = mpc512x_clk_divider(
686 entry->name_div0,
687 entry->name_en0, CLK_SET_RATE_GATE,
688 mccr_reg, 17, 15, 0);
689 if (entry->has_mclk1) {
690 clks[clks_idx_pub] = mpc512x_clk_muxed(
691 entry->name_mclk,
692 &entry->parent_names_mux1[0],
693 ARRAY_SIZE(entry->parent_names_mux1),
694 mccr_reg, 7, 1);
695 } else {
696 clks[clks_idx_pub] = mpc512x_clk_factor(
697 entry->name_mclk,
698 entry->parent_names_mux1[0],
699 1, 1);
700 }
701}
702
703
704
705static void mpc512x_clk_setup_clock_tree(struct device_node *np, int busfreq)
706{
707 int sys_mul, sys_div, ips_div;
708 int mul, div;
709 size_t mclk_idx;
710 int freq;
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733 mpc512x_clk_setup_ref_clock(np, busfreq, &sys_mul, &sys_div, &ips_div);
734
735
736 clks[MPC512x_CLK_SYS] = mpc512x_clk_factor("sys", "ref",
737 sys_mul, sys_div);
738 clks[MPC512x_CLK_CSB] = mpc512x_clk_factor("csb", "sys", 1, 2);
739 clks[MPC512x_CLK_IPS] = mpc512x_clk_divtable("ips", "csb",
740 &clkregs->scfr1, 23, 3,
741 divtab_2346);
742
743
744 clks[MPC512x_CLK_DDR_UG] = mpc512x_clk_factor("ddr-ug", "sys", 1, 2);
745
746
747
748
749
750
751
752
753
754
755
756
757 clks[MPC512x_CLK_SDHC_x4] = mpc512x_clk_factor("sdhc-x4", "csb", 2, 1);
758 clks[MPC512x_CLK_SDHC_UG] = mpc512x_clk_divider("sdhc-ug", "sdhc-x4", 0,
759 &clkregs->scfr2, 1, 7,
760 CLK_DIVIDER_ONE_BASED);
761 if (soc_has_sdhc2()) {
762 clks[MPC512x_CLK_SDHC2_UG] = mpc512x_clk_divider(
763 "sdhc2-ug", "sdhc-x4", 0, &clkregs->scfr2,
764 9, 7, CLK_DIVIDER_ONE_BASED);
765 }
766
767 clks[MPC512x_CLK_DIU_x4] = mpc512x_clk_factor("diu-x4", "csb", 4, 1);
768 clks[MPC512x_CLK_DIU_UG] = mpc512x_clk_divider("diu-ug", "diu-x4", 0,
769 &clkregs->scfr1, 0, 8,
770 CLK_DIVIDER_ONE_BASED);
771
772
773
774
775
776
777
778
779 mul = get_cpmf_mult_x2();
780 div = 2;
781 clks[MPC512x_CLK_E300] = mpc512x_clk_factor("e300", "csb", mul, div);
782
783 if (soc_has_mbx()) {
784 clks[MPC512x_CLK_MBX_BUS_UG] = mpc512x_clk_factor(
785 "mbx-bus-ug", "csb", 1, 2);
786 clks[MPC512x_CLK_MBX_UG] = mpc512x_clk_divtable(
787 "mbx-ug", "mbx-bus-ug", &clkregs->scfr1,
788 14, 3, divtab_1234);
789 clks[MPC512x_CLK_MBX_3D_UG] = mpc512x_clk_factor(
790 "mbx-3d-ug", "mbx-ug", 1, 1);
791 }
792 if (soc_has_pci()) {
793 clks[MPC512x_CLK_PCI_UG] = mpc512x_clk_divtable(
794 "pci-ug", "csb", &clkregs->scfr1,
795 20, 3, divtab_2346);
796 }
797 if (soc_has_nfc_5125()) {
798
799
800
801
802
803 clks[MPC512x_CLK_NFC_UG] = ERR_PTR(-ENOTSUPP);
804 } else {
805 clks[MPC512x_CLK_NFC_UG] = mpc512x_clk_divtable(
806 "nfc-ug", "ips", &clkregs->scfr1,
807 8, 3, divtab_1234);
808 }
809 clks[MPC512x_CLK_LPC_UG] = mpc512x_clk_divtable("lpc-ug", "ips",
810 &clkregs->scfr1, 11, 3,
811 divtab_1234);
812
813 clks[MPC512x_CLK_LPC] = mpc512x_clk_gated("lpc", "lpc-ug",
814 &clkregs->sccr1, 30);
815 clks[MPC512x_CLK_NFC] = mpc512x_clk_gated("nfc", "nfc-ug",
816 &clkregs->sccr1, 29);
817 if (soc_has_pata()) {
818 clks[MPC512x_CLK_PATA] = mpc512x_clk_gated(
819 "pata", "ips", &clkregs->sccr1, 28);
820 }
821
822 for (mclk_idx = 0; mclk_idx < soc_max_pscnum(); mclk_idx++) {
823 char name[12];
824 snprintf(name, sizeof(name), "psc%d", mclk_idx);
825 clks[MPC512x_CLK_PSC0 + mclk_idx] = mpc512x_clk_gated(
826 name, "ips", &clkregs->sccr1, 27 - mclk_idx);
827 mpc512x_clk_setup_mclk(&mclk_psc_data[mclk_idx], mclk_idx);
828 }
829 clks[MPC512x_CLK_PSC_FIFO] = mpc512x_clk_gated("psc-fifo", "ips",
830 &clkregs->sccr1, 15);
831 if (soc_has_sata()) {
832 clks[MPC512x_CLK_SATA] = mpc512x_clk_gated(
833 "sata", "ips", &clkregs->sccr1, 14);
834 }
835 clks[MPC512x_CLK_FEC] = mpc512x_clk_gated("fec", "ips",
836 &clkregs->sccr1, 13);
837 if (soc_has_pci()) {
838 clks[MPC512x_CLK_PCI] = mpc512x_clk_gated(
839 "pci", "pci-ug", &clkregs->sccr1, 11);
840 }
841 clks[MPC512x_CLK_DDR] = mpc512x_clk_gated("ddr", "ddr-ug",
842 &clkregs->sccr1, 10);
843 if (soc_has_fec2()) {
844 clks[MPC512x_CLK_FEC2] = mpc512x_clk_gated(
845 "fec2", "ips", &clkregs->sccr1, 9);
846 }
847
848 clks[MPC512x_CLK_DIU] = mpc512x_clk_gated("diu", "diu-ug",
849 &clkregs->sccr2, 31);
850 if (soc_has_axe()) {
851 clks[MPC512x_CLK_AXE] = mpc512x_clk_gated(
852 "axe", "csb", &clkregs->sccr2, 30);
853 }
854 clks[MPC512x_CLK_MEM] = mpc512x_clk_gated("mem", "ips",
855 &clkregs->sccr2, 29);
856 clks[MPC512x_CLK_USB1] = mpc512x_clk_gated("usb1", "csb",
857 &clkregs->sccr2, 28);
858 clks[MPC512x_CLK_USB2] = mpc512x_clk_gated("usb2", "csb",
859 &clkregs->sccr2, 27);
860 clks[MPC512x_CLK_I2C] = mpc512x_clk_gated("i2c", "ips",
861 &clkregs->sccr2, 26);
862
863 clks[MPC512x_CLK_BDLC] = mpc512x_clk_gated("bdlc", "ips",
864 &clkregs->sccr2, 25);
865 for (mclk_idx = 0; mclk_idx < ARRAY_SIZE(mclk_mscan_data); mclk_idx++)
866 mpc512x_clk_setup_mclk(&mclk_mscan_data[mclk_idx], mclk_idx);
867 clks[MPC512x_CLK_SDHC] = mpc512x_clk_gated("sdhc", "sdhc-ug",
868 &clkregs->sccr2, 24);
869
870 if (soc_has_spdif()) {
871 clks[MPC512x_CLK_SPDIF] = mpc512x_clk_gated(
872 "spdif", "ips", &clkregs->sccr2, 23);
873 mpc512x_clk_setup_mclk(&mclk_spdif_data[0], 0);
874 }
875 if (soc_has_mbx()) {
876 clks[MPC512x_CLK_MBX_BUS] = mpc512x_clk_gated(
877 "mbx-bus", "mbx-bus-ug", &clkregs->sccr2, 22);
878 clks[MPC512x_CLK_MBX] = mpc512x_clk_gated(
879 "mbx", "mbx-ug", &clkregs->sccr2, 21);
880 clks[MPC512x_CLK_MBX_3D] = mpc512x_clk_gated(
881 "mbx-3d", "mbx-3d-ug", &clkregs->sccr2, 20);
882 }
883 clks[MPC512x_CLK_IIM] = mpc512x_clk_gated("iim", "csb",
884 &clkregs->sccr2, 19);
885 if (soc_has_viu()) {
886 clks[MPC512x_CLK_VIU] = mpc512x_clk_gated(
887 "viu", "csb", &clkregs->sccr2, 18);
888 }
889 if (soc_has_sdhc2()) {
890 clks[MPC512x_CLK_SDHC2] = mpc512x_clk_gated(
891 "sdhc-2", "sdhc2-ug", &clkregs->sccr2, 17);
892 }
893
894 if (soc_has_outclk()) {
895 size_t idx;
896 for (idx = 0; idx < ARRAY_SIZE(mclk_outclk_data); idx++)
897 mpc512x_clk_setup_mclk(&mclk_outclk_data[idx], idx);
898 }
899
900
901
902
903
904 freq = get_freq_from_dt("psc_mclk_in");
905 if (!freq)
906 freq = 25000000;
907 clks[MPC512x_CLK_PSC_MCLK_IN] = mpc512x_clk_fixed("psc_mclk_in", freq);
908 if (soc_has_mclk_mux0_canin()) {
909 freq = get_freq_from_dt("can_clk_in");
910 clks[MPC512x_CLK_CAN_CLK_IN] = mpc512x_clk_fixed(
911 "can_clk_in", freq);
912 } else {
913 freq = get_freq_from_dt("spdif_tx_in");
914 clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed(
915 "spdif_tx_in", freq);
916 freq = get_freq_from_dt("spdif_rx_in");
917 clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed(
918 "spdif_rx_in", freq);
919 }
920
921
922 clks[MPC512x_CLK_AC97] = mpc512x_clk_fixed("ac97", 24567000);
923
924
925
926
927
928
929 clk_prepare_enable(clks[MPC512x_CLK_DUMMY]);
930 clk_prepare_enable(clks[MPC512x_CLK_E300]);
931 clk_prepare_enable(clks[MPC512x_CLK_DDR]);
932 clk_prepare_enable(clks[MPC512x_CLK_MEM]);
933 clk_prepare_enable(clks[MPC512x_CLK_IPS]);
934 clk_prepare_enable(clks[MPC512x_CLK_LPC]);
935}
936
937
938
939
940
941static void mpc5121_clk_register_of_provider(struct device_node *np)
942{
943 clk_data.clks = clks;
944 clk_data.clk_num = MPC512x_CLK_LAST_PUBLIC + 1;
945 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
946}
947
948
949
950
951
952static void mpc5121_clk_provide_migration_support(void)
953{
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973 clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);
974 if (of_find_compatible_node(NULL, "pci", "fsl,mpc5121-pci"))
975 clk_prepare_enable(clks[MPC512x_CLK_PCI]);
976}
977
978
979
980
981
982
983#define FOR_NODES(compatname) \
984 for_each_compatible_node(np, NULL, compatname)
985
986#define NODE_PREP do { \
987 of_address_to_resource(np, 0, &res); \
988 snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \
989} while (0)
990
991#define NODE_CHK(clkname, clkitem, regnode, regflag) do { \
992 struct clk *clk; \
993 clk = of_clk_get_by_name(np, clkname); \
994 if (IS_ERR(clk)) { \
995 clk = clkitem; \
996 clk_register_clkdev(clk, clkname, devname); \
997 if (regnode) \
998 clk_register_clkdev(clk, clkname, np->name); \
999 did_register |= DID_REG_ ## regflag; \
1000 pr_debug("clock alias name '%s' for dev '%s' pointer %p\n", \
1001 clkname, devname, clk); \
1002 } else { \
1003 clk_put(clk); \
1004 } \
1005} while (0)
1006
1007
1008
1009
1010
1011
1012
1013static void mpc5121_clk_provide_backwards_compat(void)
1014{
1015 enum did_reg_flags {
1016 DID_REG_PSC = BIT(0),
1017 DID_REG_PSCFIFO = BIT(1),
1018 DID_REG_NFC = BIT(2),
1019 DID_REG_CAN = BIT(3),
1020 DID_REG_I2C = BIT(4),
1021 DID_REG_DIU = BIT(5),
1022 DID_REG_VIU = BIT(6),
1023 DID_REG_FEC = BIT(7),
1024 DID_REG_USB = BIT(8),
1025 DID_REG_PATA = BIT(9),
1026 };
1027
1028 int did_register;
1029 struct device_node *np;
1030 struct resource res;
1031 int idx;
1032 char devname[32];
1033
1034 did_register = 0;
1035
1036 FOR_NODES(mpc512x_select_psc_compat()) {
1037 NODE_PREP;
1038 idx = (res.start >> 8) & 0xf;
1039 NODE_CHK("ipg", clks[MPC512x_CLK_PSC0 + idx], 0, PSC);
1040 NODE_CHK("mclk", clks[MPC512x_CLK_PSC0_MCLK + idx], 0, PSC);
1041 }
1042
1043 FOR_NODES("fsl,mpc5121-psc-fifo") {
1044 NODE_PREP;
1045 NODE_CHK("ipg", clks[MPC512x_CLK_PSC_FIFO], 1, PSCFIFO);
1046 }
1047
1048 FOR_NODES("fsl,mpc5121-nfc") {
1049 NODE_PREP;
1050 NODE_CHK("ipg", clks[MPC512x_CLK_NFC], 0, NFC);
1051 }
1052
1053 FOR_NODES("fsl,mpc5121-mscan") {
1054 NODE_PREP;
1055 idx = 0;
1056 idx += (res.start & 0x2000) ? 2 : 0;
1057 idx += (res.start & 0x0080) ? 1 : 0;
1058 NODE_CHK("ipg", clks[MPC512x_CLK_BDLC], 0, CAN);
1059 NODE_CHK("mclk", clks[MPC512x_CLK_MSCAN0_MCLK + idx], 0, CAN);
1060 }
1061
1062
1063
1064
1065
1066
1067 if (did_register & DID_REG_CAN) {
1068 clk_register_clkdev(clks[MPC512x_CLK_IPS], "ips", NULL);
1069 clk_register_clkdev(clks[MPC512x_CLK_SYS], "sys", NULL);
1070 clk_register_clkdev(clks[MPC512x_CLK_REF], "ref", NULL);
1071 }
1072
1073 FOR_NODES("fsl,mpc5121-i2c") {
1074 NODE_PREP;
1075 NODE_CHK("ipg", clks[MPC512x_CLK_I2C], 0, I2C);
1076 }
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093 if (did_register & DID_REG_I2C)
1094 clk_prepare_enable(clks[MPC512x_CLK_I2C]);
1095
1096 FOR_NODES("fsl,mpc5121-diu") {
1097 NODE_PREP;
1098 NODE_CHK("ipg", clks[MPC512x_CLK_DIU], 1, DIU);
1099 }
1100
1101 FOR_NODES("fsl,mpc5121-viu") {
1102 NODE_PREP;
1103 NODE_CHK("ipg", clks[MPC512x_CLK_VIU], 0, VIU);
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113 FOR_NODES("fsl,mpc5121-fec") {
1114 NODE_PREP;
1115 NODE_CHK("per", clks[MPC512x_CLK_FEC], 0, FEC);
1116 }
1117 FOR_NODES("fsl,mpc5121-fec-mdio") {
1118 NODE_PREP;
1119 NODE_CHK("per", clks[MPC512x_CLK_FEC], 0, FEC);
1120 }
1121
1122
1123
1124
1125
1126
1127 FOR_NODES("fsl,mpc5125-fec") {
1128 NODE_PREP;
1129 if (res.start & 0x4000)
1130 idx = MPC512x_CLK_FEC2;
1131 else
1132 idx = MPC512x_CLK_FEC;
1133 NODE_CHK("per", clks[idx], 0, FEC);
1134 }
1135
1136 FOR_NODES("fsl,mpc5121-usb2-dr") {
1137 NODE_PREP;
1138 idx = (res.start & 0x4000) ? 1 : 0;
1139 NODE_CHK("ipg", clks[MPC512x_CLK_USB1 + idx], 0, USB);
1140 }
1141
1142 FOR_NODES("fsl,mpc5121-pata") {
1143 NODE_PREP;
1144 NODE_CHK("ipg", clks[MPC512x_CLK_PATA], 0, PATA);
1145 }
1146
1147
1148
1149
1150
1151
1152
1153
1154 if (did_register) {
1155 pr_notice("device tree lacks clock specs, adding fallbacks (0x%x,%s%s%s%s%s%s%s%s%s%s)\n",
1156 did_register,
1157 (did_register & DID_REG_PSC) ? " PSC" : "",
1158 (did_register & DID_REG_PSCFIFO) ? " PSCFIFO" : "",
1159 (did_register & DID_REG_NFC) ? " NFC" : "",
1160 (did_register & DID_REG_CAN) ? " CAN" : "",
1161 (did_register & DID_REG_I2C) ? " I2C" : "",
1162 (did_register & DID_REG_DIU) ? " DIU" : "",
1163 (did_register & DID_REG_VIU) ? " VIU" : "",
1164 (did_register & DID_REG_FEC) ? " FEC" : "",
1165 (did_register & DID_REG_USB) ? " USB" : "",
1166 (did_register & DID_REG_PATA) ? " PATA" : "");
1167 } else {
1168 pr_debug("device tree has clock specs, no fallbacks added\n");
1169 }
1170}
1171
1172
1173
1174
1175
1176
1177int __init mpc5121_clk_init(void)
1178{
1179 struct device_node *clk_np;
1180 int busfreq;
1181
1182
1183 clk_np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
1184 if (!clk_np)
1185 return -ENODEV;
1186 clkregs = of_iomap(clk_np, 0);
1187 WARN_ON(!clkregs);
1188
1189
1190 mpc512x_clk_determine_soc();
1191
1192
1193 mpc512x_clk_preset_data();
1194
1195
1196
1197
1198
1199 clks[MPC512x_CLK_DUMMY] = mpc512x_clk_fixed("dummy", 0);
1200
1201
1202
1203
1204
1205
1206 busfreq = get_freq_from_dt("bus-frequency");
1207 mpc512x_clk_setup_clock_tree(clk_np, busfreq);
1208
1209
1210 mpc5121_clk_register_of_provider(clk_np);
1211
1212
1213
1214
1215
1216
1217 mpc5121_clk_provide_migration_support();
1218 mpc5121_clk_provide_backwards_compat();
1219
1220 return 0;
1221}
1222