Lines Matching +full:mclk +full:- +full:div
1 // SPDX-License-Identifier: GPL-2.0-or-later
12 #include <linux/clk-provider.h>
21 #include <dt-bindings/clock/mpc512x-clock.h>
25 /* helpers to keep the MCLK intermediates "somewhere" in our table */
47 /* intermediates in div+gate combos or fractional dividers */
61 /* intermediates for the mux+gate+div+mux MCLK generation */
89 * interpretation, no CFM, different fourth PSC/CAN mux0 input -- yet
225 int mul, int div) in mpc512x_clk_factor() argument
231 mul, div); in mpc512x_clk_factor()
292 val &= (1 << len) - 1; in get_bit_field()
305 spmf = get_bit_field(&clkregs->spmr, 24, 4); in get_spmf_mult()
326 divcode = get_bit_field(&clkregs->scfr2, 26, 6); in get_sys_div_x2()
350 cpmf = get_bit_field(&clkregs->spmr, 16, 4); in get_cpmf_mult_x2()
366 { .val = 2, .div = 2, },
367 { .val = 3, .div = 3, },
368 { .val = 4, .div = 4, },
369 { .val = 6, .div = 6, },
370 { .div = 0, },
375 { .val = 1, .div = 1, },
376 { .val = 2, .div = 2, },
377 { .val = 3, .div = 3, },
378 { .val = 4, .div = 4, },
379 { .div = 0, },
389 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr"); in get_freq_from_dt()
404 clks[i] = ERR_PTR(-ENODEV); in mpc512x_clk_preset_data()
408 * - receives the "bus frequency" from the caller (that's the IPS clock
410 * - fetches the system PLL multiplier and divider values as well as the
412 * - determines the REF clock rate either from the XTAL/OSC spec (if
416 * - creates the "ref" clock item in the clock tree, such that
417 * subsequent code can create the remainder of the hierarchy (REF ->
418 * SYS -> CSB -> IPS) from the REF clock rate and the returned mul/div
428 /* fetch mul/div factors from the hardware */ in mpc512x_clk_setup_ref_clock()
432 *ips_div = get_bit_field(&clkregs->scfr1, 23, 3); in mpc512x_clk_setup_ref_clock()
457 calc_freq *= *ips_div; /* IPS -> CSB */ in mpc512x_clk_setup_ref_clock()
458 calc_freq *= 2; /* CSB -> SYS */ in mpc512x_clk_setup_ref_clock()
459 calc_freq *= *sys_div; /* SYS -> PLL out */ in mpc512x_clk_setup_ref_clock()
460 calc_freq /= *sys_mul; /* PLL out -> REF == OSC */ in mpc512x_clk_setup_ref_clock()
465 /* MCLK helpers {{{ */
468 * helper code for the MCLK subtree setup
472 * and that one might re-use the PSC setup for MSCAN clock generation
476 * the details (starting at page 5-20) show differences in the specific
478 * factual non-availability of the second mux stage (it's present yet
481 * the MSCAN clock related registers (starting at page 5-35) all
485 * TODO re-check the document, and clarify whether the RM is correct in
489 * it turns out that the RM rev4 as of 2012-06 talks about "can" for the
490 * PSCs while RM rev3 as of 2008-10 talks about "spdif", so I guess that
497 * it's the very data type dictated by <linux/clk-provider.h>,
501 "sys", "ref", "psc-mclk-in", "spdif-tx",
505 "sys", "ref", "psc-mclk-in", "can-clk-in",
527 "psc" #id "-mux0", \
528 "psc" #id "-en0", \
536 "mscan" #id "-mux0", \
537 "mscan" #id "-en0", \
545 "spdif-mux0", \
546 "spdif-en0", \
548 { "spdif_mclk_div", "spdif-rx", }, \
554 "out" #id "-mux0", \
555 "out" #id "-en0", \
594 /* setup the MCLK clock subtree of an individual PSC/MSCAN/SPDIF */
598 u32 __iomem *mccr_reg; /* MCLK control register (mux, en, div) */ in mpc512x_clk_setup_mclk()
599 int div; in mpc512x_clk_setup_mclk() local
602 switch (entry->type) { in mpc512x_clk_setup_mclk()
607 mccr_reg = &clkregs->psc_ccr[idx]; in mpc512x_clk_setup_mclk()
613 mccr_reg = &clkregs->mscan_ccr[idx]; in mpc512x_clk_setup_mclk()
619 mccr_reg = &clkregs->spccr; in mpc512x_clk_setup_mclk()
626 mccr_reg = &clkregs->out_ccr[idx]; in mpc512x_clk_setup_mclk()
634 * enforced a specific MCLK divider while the clock was gated in mpc512x_clk_setup_mclk()
638 * "MCLK <= IPS" constraint, the fixed divider value of 1 in mpc512x_clk_setup_mclk()
639 * results in a divider of 2 and thus MCLK = SYS/2 which equals in mpc512x_clk_setup_mclk()
645 * - MCLK 0 from SYS in mpc512x_clk_setup_mclk()
646 * - MCLK DIV such to not exceed the IPS clock in mpc512x_clk_setup_mclk()
647 * - MCLK 0 enabled in mpc512x_clk_setup_mclk()
648 * - MCLK 1 from MCLK DIV in mpc512x_clk_setup_mclk()
650 div = clk_get_rate(clks[MPC512x_CLK_SYS]); in mpc512x_clk_setup_mclk()
651 div /= clk_get_rate(clks[MPC512x_CLK_IPS]); in mpc512x_clk_setup_mclk()
653 out_be32(mccr_reg, (0 << 16) | ((div - 1) << 17)); in mpc512x_clk_setup_mclk()
654 out_be32(mccr_reg, (1 << 16) | ((div - 1) << 17)); in mpc512x_clk_setup_mclk()
657 * create the 'struct clk' items of the MCLK's clock subtree in mpc512x_clk_setup_mclk()
661 * - the "internal" MCLK_DIV and MCLK_OUT signal in turn are in mpc512x_clk_setup_mclk()
663 * the PSC/MSCAN/SPDIF (serial drivers et al) need the MCLK in mpc512x_clk_setup_mclk()
665 * - in the absence of "aliases" for clocks we need to create in mpc512x_clk_setup_mclk()
669 * - for easier future maintenance and for better reflection of in mpc512x_clk_setup_mclk()
675 entry->name_mux0, in mpc512x_clk_setup_mclk()
682 entry->name_en0, entry->name_mux0, in mpc512x_clk_setup_mclk()
685 entry->name_div0, in mpc512x_clk_setup_mclk()
686 entry->name_en0, CLK_SET_RATE_GATE, in mpc512x_clk_setup_mclk()
688 if (entry->has_mclk1) { in mpc512x_clk_setup_mclk()
690 entry->name_mclk, in mpc512x_clk_setup_mclk()
691 &entry->parent_names_mux1[0], in mpc512x_clk_setup_mclk()
692 ARRAY_SIZE(entry->parent_names_mux1), in mpc512x_clk_setup_mclk()
696 entry->name_mclk, in mpc512x_clk_setup_mclk()
697 entry->parent_names_mux1[0], in mpc512x_clk_setup_mclk()
702 /* }}} MCLK helpers */
707 int mul, div; in mpc512x_clk_setup_clock_tree() local
713 * - consider whether to handle clocks which have both gates and in mpc512x_clk_setup_clock_tree()
715 * - fractional dividers appear to not map well to composites in mpc512x_clk_setup_clock_tree()
718 * most one of a mux, div, and gate each into one 'struct clk' in mpc512x_clk_setup_clock_tree()
720 * - PSC/MSCAN/SPDIF clock generation OTOH already is very in mpc512x_clk_setup_clock_tree()
726 * - the current source layout appropriately reflects the in mpc512x_clk_setup_clock_tree()
734 /* now setup the REF -> SYS -> CSB -> IPS hierarchy */ in mpc512x_clk_setup_clock_tree()
739 &clkregs->scfr1, 23, 3, in mpc512x_clk_setup_clock_tree()
743 clks[MPC512x_CLK_DDR_UG] = mpc512x_clk_factor("ddr-ug", "sys", 1, 2); in mpc512x_clk_setup_clock_tree()
756 clks[MPC512x_CLK_SDHC_x4] = mpc512x_clk_factor("sdhc-x4", "csb", 2, 1); in mpc512x_clk_setup_clock_tree()
757 clks[MPC512x_CLK_SDHC_UG] = mpc512x_clk_divider("sdhc-ug", "sdhc-x4", 0, in mpc512x_clk_setup_clock_tree()
758 &clkregs->scfr2, 1, 7, in mpc512x_clk_setup_clock_tree()
762 "sdhc2-ug", "sdhc-x4", 0, &clkregs->scfr2, in mpc512x_clk_setup_clock_tree()
766 clks[MPC512x_CLK_DIU_x4] = mpc512x_clk_factor("diu-x4", "csb", 4, 1); in mpc512x_clk_setup_clock_tree()
767 clks[MPC512x_CLK_DIU_UG] = mpc512x_clk_divider("diu-ug", "diu-x4", 0, in mpc512x_clk_setup_clock_tree()
768 &clkregs->scfr1, 0, 8, in mpc512x_clk_setup_clock_tree()
779 div = 2; /* compensate for the fractional factor */ in mpc512x_clk_setup_clock_tree()
780 clks[MPC512x_CLK_E300] = mpc512x_clk_factor("e300", "csb", mul, div); in mpc512x_clk_setup_clock_tree()
784 "mbx-bus-ug", "csb", 1, 2); in mpc512x_clk_setup_clock_tree()
786 "mbx-ug", "mbx-bus-ug", &clkregs->scfr1, in mpc512x_clk_setup_clock_tree()
789 "mbx-3d-ug", "mbx-ug", 1, 1); in mpc512x_clk_setup_clock_tree()
793 "pci-ug", "csb", &clkregs->scfr1, in mpc512x_clk_setup_clock_tree()
799 * with high/low period counters in clkregs->scfr3, in mpc512x_clk_setup_clock_tree()
802 clks[MPC512x_CLK_NFC_UG] = ERR_PTR(-ENOTSUPP); in mpc512x_clk_setup_clock_tree()
805 "nfc-ug", "ips", &clkregs->scfr1, in mpc512x_clk_setup_clock_tree()
808 clks[MPC512x_CLK_LPC_UG] = mpc512x_clk_divtable("lpc-ug", "ips", in mpc512x_clk_setup_clock_tree()
809 &clkregs->scfr1, 11, 3, in mpc512x_clk_setup_clock_tree()
812 clks[MPC512x_CLK_LPC] = mpc512x_clk_gated("lpc", "lpc-ug", in mpc512x_clk_setup_clock_tree()
813 &clkregs->sccr1, 30); in mpc512x_clk_setup_clock_tree()
814 clks[MPC512x_CLK_NFC] = mpc512x_clk_gated("nfc", "nfc-ug", in mpc512x_clk_setup_clock_tree()
815 &clkregs->sccr1, 29); in mpc512x_clk_setup_clock_tree()
818 "pata", "ips", &clkregs->sccr1, 28); in mpc512x_clk_setup_clock_tree()
820 /* for PSCs there is a "registers" gate and a bitrate MCLK subtree */ in mpc512x_clk_setup_clock_tree()
825 name, "ips", &clkregs->sccr1, 27 - mclk_idx); in mpc512x_clk_setup_clock_tree()
828 clks[MPC512x_CLK_PSC_FIFO] = mpc512x_clk_gated("psc-fifo", "ips", in mpc512x_clk_setup_clock_tree()
829 &clkregs->sccr1, 15); in mpc512x_clk_setup_clock_tree()
832 "sata", "ips", &clkregs->sccr1, 14); in mpc512x_clk_setup_clock_tree()
835 &clkregs->sccr1, 13); in mpc512x_clk_setup_clock_tree()
838 "pci", "pci-ug", &clkregs->sccr1, 11); in mpc512x_clk_setup_clock_tree()
840 clks[MPC512x_CLK_DDR] = mpc512x_clk_gated("ddr", "ddr-ug", in mpc512x_clk_setup_clock_tree()
841 &clkregs->sccr1, 10); in mpc512x_clk_setup_clock_tree()
844 "fec2", "ips", &clkregs->sccr1, 9); in mpc512x_clk_setup_clock_tree()
847 clks[MPC512x_CLK_DIU] = mpc512x_clk_gated("diu", "diu-ug", in mpc512x_clk_setup_clock_tree()
848 &clkregs->sccr2, 31); in mpc512x_clk_setup_clock_tree()
851 "axe", "csb", &clkregs->sccr2, 30); in mpc512x_clk_setup_clock_tree()
854 &clkregs->sccr2, 29); in mpc512x_clk_setup_clock_tree()
856 &clkregs->sccr2, 28); in mpc512x_clk_setup_clock_tree()
858 &clkregs->sccr2, 27); in mpc512x_clk_setup_clock_tree()
860 &clkregs->sccr2, 26); in mpc512x_clk_setup_clock_tree()
863 &clkregs->sccr2, 25); in mpc512x_clk_setup_clock_tree()
866 clks[MPC512x_CLK_SDHC] = mpc512x_clk_gated("sdhc", "sdhc-ug", in mpc512x_clk_setup_clock_tree()
867 &clkregs->sccr2, 24); in mpc512x_clk_setup_clock_tree()
868 /* there is only one SPDIF component, which shares MCLK support code */ in mpc512x_clk_setup_clock_tree()
871 "spdif", "ips", &clkregs->sccr2, 23); in mpc512x_clk_setup_clock_tree()
876 "mbx-bus", "mbx-bus-ug", &clkregs->sccr2, 22); in mpc512x_clk_setup_clock_tree()
878 "mbx", "mbx-ug", &clkregs->sccr2, 21); in mpc512x_clk_setup_clock_tree()
880 "mbx-3d", "mbx-3d-ug", &clkregs->sccr2, 20); in mpc512x_clk_setup_clock_tree()
883 &clkregs->sccr2, 19); in mpc512x_clk_setup_clock_tree()
886 "viu", "csb", &clkregs->sccr2, 18); in mpc512x_clk_setup_clock_tree()
890 "sdhc-2", "sdhc2-ug", &clkregs->sccr2, 17); in mpc512x_clk_setup_clock_tree()
924 * pre-enable those "internal" clock items which never get in mpc512x_clk_setup_clock_tree()
937 * registers the set of public clocks (those listed in the dt-bindings/
955 * pre-enable those clock items which are not yet appropriately in mpc5121_clk_provide_migration_support()
964 * so we "pre-enable" the clock here, to not have the clock in mpc5121_clk_provide_migration_support()
967 * this PCI clock pre-enable workaround only applies when there in mpc5121_clk_provide_migration_support()
973 np = of_find_compatible_node(NULL, "pci", "fsl,mpc5121-pci"); in mpc5121_clk_provide_migration_support()
989 snprintf(devname, sizeof(devname), "%pa.%s", &res.start, np->name); \
999 clk_register_clkdev(clk, clkname, np->name); \
1041 NODE_CHK("mclk", clks[MPC512x_CLK_PSC0_MCLK + idx], 0, PSC); in mpc5121_clk_provide_backwards_compat()
1044 FOR_NODES("fsl,mpc5121-psc-fifo") { in mpc5121_clk_provide_backwards_compat()
1049 FOR_NODES("fsl,mpc5121-nfc") { in mpc5121_clk_provide_backwards_compat()
1054 FOR_NODES("fsl,mpc5121-mscan") { in mpc5121_clk_provide_backwards_compat()
1060 NODE_CHK("mclk", clks[MPC512x_CLK_MSCAN0_MCLK + idx], 0, CAN); in mpc5121_clk_provide_backwards_compat()
1066 * potential for a name conflict (in contrast to 'ipg' and 'mclk') in mpc5121_clk_provide_backwards_compat()
1074 FOR_NODES("fsl,mpc5121-i2c") { in mpc5121_clk_provide_backwards_compat()
1082 * which we cannot register an alias -- a _global_ 'ipg' alias that in mpc5121_clk_provide_backwards_compat()
1087 * silent and non-fatal, and pre-enable the clock item here such in mpc5121_clk_provide_backwards_compat()
1091 * details, adjusting s/NULL/"ipg"/ in i2c-mpc.c would make this in mpc5121_clk_provide_backwards_compat()
1097 FOR_NODES("fsl,mpc5121-diu") { in mpc5121_clk_provide_backwards_compat()
1102 FOR_NODES("fsl,mpc5121-viu") { in mpc5121_clk_provide_backwards_compat()
1110 * which most other nodes are using -- this is not a fatal thing in mpc5121_clk_provide_backwards_compat()
1112 * registration, it's a non-issue with up-to-date device tree data in mpc5121_clk_provide_backwards_compat()
1114 FOR_NODES("fsl,mpc5121-fec") { in mpc5121_clk_provide_backwards_compat()
1118 FOR_NODES("fsl,mpc5121-fec-mdio") { in mpc5121_clk_provide_backwards_compat()
1128 FOR_NODES("fsl,mpc5125-fec") { in mpc5121_clk_provide_backwards_compat()
1137 FOR_NODES("fsl,mpc5121-usb2-dr") { in mpc5121_clk_provide_backwards_compat()
1143 FOR_NODES("fsl,mpc5121-pata") { in mpc5121_clk_provide_backwards_compat()
1151 * absence of up-to-date device tree data -- backwards in mpc5121_clk_provide_backwards_compat()
1174 * The "fixed-clock" nodes (which includes the oscillator node if the board's
1184 clk_np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock"); in mpc5121_clk_init()
1186 return -ENODEV; in mpc5121_clk_init()
1207 busfreq = get_freq_from_dt("bus-frequency"); in mpc5121_clk_init()