Lines Matching +full:div +full:- +full:reg

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2013 - 2021 Xilinx
14 #include <linux/clk-provider.h>
88 /* Divider limits, from UG572 Table 3-4 for Ultrascale+ */
112 #define div_mask(width) ((1 << (width)) - 1)
125 * struct clk_wzrd - Clock wizard private data structure
148 * struct clk_wzrd_divider - clock divider specific to clk_wzrd
150 * @hw: handle between common and hardware-specific interfaces
156 * @table: array of value/divider pairs, last entry should have div = 0
200 void __iomem *div_addr = divider->base + divider->offset; in clk_wzrd_recalc_rate_ver()
201 u32 div, p5en, edge, prediv2, all; in clk_wzrd_recalc_rate_ver() local
214 div = 2 * all + prediv2 * p5en; in clk_wzrd_recalc_rate_ver()
216 div = all; in clk_wzrd_recalc_rate_ver()
218 return DIV_ROUND_UP_ULL((u64)parent_rate, div); in clk_wzrd_recalc_rate_ver()
225 void __iomem *div_addr = divider->base + divider->offset; in clk_wzrd_recalc_rate()
228 val = readl(div_addr) >> divider->shift; in clk_wzrd_recalc_rate()
229 val &= div_mask(divider->width); in clk_wzrd_recalc_rate()
231 return divider_recalc_rate(hw, parent_rate, val, divider->table, in clk_wzrd_recalc_rate()
232 divider->flags, divider->width); in clk_wzrd_recalc_rate()
239 void __iomem *div_addr = divider->base + divider->offset; in clk_wzrd_ver_dynamic_reconfig()
244 spin_lock_irqsave(divider->lock, flags); in clk_wzrd_ver_dynamic_reconfig()
264 err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET, in clk_wzrd_ver_dynamic_reconfig()
272 divider->base + WZRD_DR_INIT_VERSAL_OFFSET); in clk_wzrd_ver_dynamic_reconfig()
275 err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET, in clk_wzrd_ver_dynamic_reconfig()
279 spin_unlock_irqrestore(divider->lock, flags); in clk_wzrd_ver_dynamic_reconfig()
287 void __iomem *div_addr = divider->base + divider->offset; in clk_wzrd_dynamic_reconfig()
292 spin_lock_irqsave(divider->lock, flags); in clk_wzrd_dynamic_reconfig()
304 err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET, in clk_wzrd_dynamic_reconfig()
312 divider->base + WZRD_DR_INIT_REG_OFFSET); in clk_wzrd_dynamic_reconfig()
314 divider->base + WZRD_DR_INIT_REG_OFFSET); in clk_wzrd_dynamic_reconfig()
317 err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET, in clk_wzrd_dynamic_reconfig()
321 spin_unlock_irqrestore(divider->lock, flags); in clk_wzrd_dynamic_reconfig()
328 u8 div; in clk_wzrd_determine_rate() local
334 div = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate); in clk_wzrd_determine_rate()
336 req->rate = req->best_parent_rate / div; in clk_wzrd_determine_rate()
345 u64 vco_freq, freq, diff, vcomin, vcomax, best_diff = -1ULL; in clk_wzrd_get_divisors_ver()
368 diff = abs(freq - rate); in clk_wzrd_get_divisors_ver()
372 divider->m = m; in clk_wzrd_get_divisors_ver()
373 divider->d = d; in clk_wzrd_get_divisors_ver()
374 divider->o = o; in clk_wzrd_get_divisors_ver()
387 u64 vco_freq, freq, diff, vcomin, vcomax, best_diff = -1ULL; in clk_wzrd_get_divisors()
409 diff = freq - rate; in clk_wzrd_get_divisors()
412 divider->m = m >> 3; in clk_wzrd_get_divisors()
413 divider->m_frac = (m - (divider->m << 3)) * 125; in clk_wzrd_get_divisors()
414 divider->d = d; in clk_wzrd_get_divisors()
415 divider->o = o >> 3; in clk_wzrd_get_divisors()
416 divider->o_frac = (o - (divider->o << 3)) * 125; in clk_wzrd_get_divisors()
420 return best_diff < WZRD_MIN_ERR ? 0 : -EBUSY; in clk_wzrd_get_divisors()
429 err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET, value, in clk_wzrd_reconfig()
433 return -ETIMEDOUT; in clk_wzrd_reconfig()
438 return readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET, value, in clk_wzrd_reconfig()
455 writel(0, divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_4)); in clk_wzrd_dynamic_ver_all_nolock()
457 m = divider->m; in clk_wzrd_dynamic_ver_all_nolock()
460 regval1 = readl(divider->base + WZRD_CLK_CFG_REG(1, in clk_wzrd_dynamic_ver_all_nolock()
468 writel(regval1, divider->base + WZRD_CLK_CFG_REG(1, in clk_wzrd_dynamic_ver_all_nolock()
471 writel(regval1, divider->base + WZRD_CLK_CFG_REG(1, in clk_wzrd_dynamic_ver_all_nolock()
474 value2 = divider->d; in clk_wzrd_dynamic_ver_all_nolock()
478 writel(regval1, divider->base + WZRD_CLK_CFG_REG(1, in clk_wzrd_dynamic_ver_all_nolock()
481 writel(regval1, divider->base + WZRD_CLK_CFG_REG(1, WZRD_DIVCLK)); in clk_wzrd_dynamic_ver_all_nolock()
483 value = divider->o; in clk_wzrd_dynamic_ver_all_nolock()
485 regval1 = readl(divider->base + WZRD_CLK_CFG_REG(1, in clk_wzrd_dynamic_ver_all_nolock()
499 writel(regval1, divider->base + WZRD_CLK_CFG_REG(1, in clk_wzrd_dynamic_ver_all_nolock()
502 writel(regval, divider->base + WZRD_CLK_CFG_REG(1, in clk_wzrd_dynamic_ver_all_nolock()
504 div_addr = divider->base + WZRD_DR_INIT_VERSAL_OFFSET; in clk_wzrd_dynamic_ver_all_nolock()
514 u32 reg; in clk_wzrd_dynamic_all_nolock() local
521 reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, divider->o) | in clk_wzrd_dynamic_all_nolock()
522 FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, divider->o_frac); in clk_wzrd_dynamic_all_nolock()
524 writel(reg, divider->base + WZRD_CLK_CFG_REG(0, 2)); in clk_wzrd_dynamic_all_nolock()
525 reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->m) | in clk_wzrd_dynamic_all_nolock()
526 FIELD_PREP(WZRD_CLKFBOUT_MULT_FRAC_MASK, divider->m_frac) | in clk_wzrd_dynamic_all_nolock()
527 FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->d); in clk_wzrd_dynamic_all_nolock()
528 writel(reg, divider->base + WZRD_CLK_CFG_REG(0, 0)); in clk_wzrd_dynamic_all_nolock()
529 writel(0, divider->base + WZRD_CLK_CFG_REG(0, 3)); in clk_wzrd_dynamic_all_nolock()
530 div_addr = divider->base + WZRD_DR_INIT_REG_OFFSET; in clk_wzrd_dynamic_all_nolock()
541 spin_lock_irqsave(divider->lock, flags); in clk_wzrd_dynamic_all()
545 spin_unlock_irqrestore(divider->lock, flags); in clk_wzrd_dynamic_all()
557 spin_lock_irqsave(divider->lock, flags); in clk_wzrd_dynamic_all_ver()
561 spin_unlock_irqrestore(divider->lock, flags); in clk_wzrd_dynamic_all_ver()
570 u32 m, d, o, reg, f, mf; in clk_wzrd_recalc_rate_all() local
573 reg = readl(divider->base + WZRD_CLK_CFG_REG(0, 0)); in clk_wzrd_recalc_rate_all()
574 d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg); in clk_wzrd_recalc_rate_all()
575 m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg); in clk_wzrd_recalc_rate_all()
576 mf = FIELD_GET(WZRD_CLKFBOUT_MULT_FRAC_MASK, reg); in clk_wzrd_recalc_rate_all()
577 reg = readl(divider->base + WZRD_CLK_CFG_REG(0, 2)); in clk_wzrd_recalc_rate_all()
578 o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg); in clk_wzrd_recalc_rate_all()
579 f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg); in clk_wzrd_recalc_rate_all()
590 u32 div, reg; in clk_wzrd_recalc_rate_all_ver() local
592 edge = !!(readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_1)) & in clk_wzrd_recalc_rate_all_ver()
595 reg = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_2)); in clk_wzrd_recalc_rate_all_ver()
596 regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg); in clk_wzrd_recalc_rate_all_ver()
597 regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg); in clk_wzrd_recalc_rate_all_ver()
603 regl = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_4)) & in clk_wzrd_recalc_rate_all_ver()
606 regl = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_3)) in clk_wzrd_recalc_rate_all_ver()
615 reg = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKOUT0_1)); in clk_wzrd_recalc_rate_all_ver()
616 edged = FIELD_GET(WZRD_CLKFBOUT_EDGE, reg); in clk_wzrd_recalc_rate_all_ver()
617 p5en = FIELD_GET(WZRD_P5EN, reg); in clk_wzrd_recalc_rate_all_ver()
618 prediv2 = FIELD_GET(WZRD_CLKOUT0_PREDIV2, reg); in clk_wzrd_recalc_rate_all_ver()
620 reg = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKOUT0_2)); in clk_wzrd_recalc_rate_all_ver()
622 regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg); in clk_wzrd_recalc_rate_all_ver()
624 regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg); in clk_wzrd_recalc_rate_all_ver()
635 edged = !!(readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_DESKEW_2)) & in clk_wzrd_recalc_rate_all_ver()
637 reg = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_DIVCLK)); in clk_wzrd_recalc_rate_all_ver()
639 regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg); in clk_wzrd_recalc_rate_all_ver()
641 regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg); in clk_wzrd_recalc_rate_all_ver()
642 div = regl + regh + edged; in clk_wzrd_recalc_rate_all_ver()
643 if (!div) in clk_wzrd_recalc_rate_all_ver()
644 div = 1; in clk_wzrd_recalc_rate_all_ver()
646 div = div * div2; in clk_wzrd_recalc_rate_all_ver()
647 return divider_recalc_rate(hw, parent_rate, div, divider->table, in clk_wzrd_recalc_rate_all_ver()
648 divider->flags, divider->width); in clk_wzrd_recalc_rate_all_ver()
658 err = clk_wzrd_get_divisors(hw, req->rate, req->best_parent_rate); in clk_wzrd_determine_rate_all()
662 m = divider->m; in clk_wzrd_determine_rate_all()
663 d = divider->d; in clk_wzrd_determine_rate_all()
664 o = divider->o; in clk_wzrd_determine_rate_all()
666 req->rate = div_u64(req->best_parent_rate * (m * 1000 + divider->m_frac), in clk_wzrd_determine_rate_all()
667 d * (o * 1000 + divider->o_frac)); in clk_wzrd_determine_rate_all()
676 u32 m, d, o, div, f; in clk_wzrd_ver_determine_rate_all() local
679 err = clk_wzrd_get_divisors_ver(hw, req->rate, req->best_parent_rate); in clk_wzrd_ver_determine_rate_all()
683 m = divider->m; in clk_wzrd_ver_determine_rate_all()
684 d = divider->d; in clk_wzrd_ver_determine_rate_all()
685 o = divider->o; in clk_wzrd_ver_determine_rate_all()
687 div = d * o; in clk_wzrd_ver_determine_rate_all()
688 int_freq = divider_recalc_rate(hw, req->best_parent_rate * m, div, in clk_wzrd_ver_determine_rate_all()
689 divider->table, in clk_wzrd_ver_determine_rate_all()
690 divider->flags, divider->width); in clk_wzrd_ver_determine_rate_all()
692 if (req->rate > int_freq) { in clk_wzrd_ver_determine_rate_all()
693 f = DIV_ROUND_CLOSEST_ULL(req->rate * WZRD_FRAC_POINTS, in clk_wzrd_ver_determine_rate_all()
695 req->rate = DIV_ROUND_CLOSEST(int_freq * f, WZRD_FRAC_POINTS); in clk_wzrd_ver_determine_rate_all()
728 u32 div, frac; in clk_wzrd_recalc_ratef() local
730 void __iomem *div_addr = divider->base + divider->offset; in clk_wzrd_recalc_ratef()
733 div = val & div_mask(divider->width); in clk_wzrd_recalc_ratef()
736 return mult_frac(parent_rate, 1000, (div * 1000) + frac); in clk_wzrd_recalc_ratef()
746 void __iomem *div_addr = divider->base + divider->offset; in clk_wzrd_dynamic_reconfig_f()
752 f = (u32)(pre - (clockout0_div * 1000)); in clk_wzrd_dynamic_reconfig_f()
763 err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, value, in clk_wzrd_dynamic_reconfig_f()
771 divider->base + WZRD_DR_INIT_REG_OFFSET); in clk_wzrd_dynamic_reconfig_f()
773 divider->base + WZRD_DR_INIT_REG_OFFSET); in clk_wzrd_dynamic_reconfig_f()
776 return readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, value, in clk_wzrd_dynamic_reconfig_f()
803 struct clk_wzrd_divider *div; in clk_wzrd_register_divf() local
808 div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); in clk_wzrd_register_divf()
809 if (!div) in clk_wzrd_register_divf()
810 return ERR_PTR(-ENOMEM); in clk_wzrd_register_divf()
820 div->base = base; in clk_wzrd_register_divf()
821 div->offset = offset; in clk_wzrd_register_divf()
822 div->shift = shift; in clk_wzrd_register_divf()
823 div->width = width; in clk_wzrd_register_divf()
824 div->flags = clk_divider_flags; in clk_wzrd_register_divf()
825 div->lock = lock; in clk_wzrd_register_divf()
826 div->hw.init = &init; in clk_wzrd_register_divf()
828 hw = &div->hw; in clk_wzrd_register_divf()
847 struct clk_wzrd_divider *div; in clk_wzrd_ver_register_divider() local
852 div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); in clk_wzrd_ver_register_divider()
853 if (!div) in clk_wzrd_ver_register_divider()
854 return ERR_PTR(-ENOMEM); in clk_wzrd_ver_register_divider()
867 div->base = base; in clk_wzrd_ver_register_divider()
868 div->offset = offset; in clk_wzrd_ver_register_divider()
869 div->shift = shift; in clk_wzrd_ver_register_divider()
870 div->width = width; in clk_wzrd_ver_register_divider()
871 div->flags = clk_divider_flags; in clk_wzrd_ver_register_divider()
872 div->lock = lock; in clk_wzrd_ver_register_divider()
873 div->hw.init = &init; in clk_wzrd_ver_register_divider()
875 hw = &div->hw; in clk_wzrd_ver_register_divider()
893 struct clk_wzrd_divider *div; in clk_wzrd_register_divider() local
898 div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); in clk_wzrd_register_divider()
899 if (!div) in clk_wzrd_register_divider()
900 return ERR_PTR(-ENOMEM); in clk_wzrd_register_divider()
913 div->base = base; in clk_wzrd_register_divider()
914 div->offset = offset; in clk_wzrd_register_divider()
915 div->shift = shift; in clk_wzrd_register_divider()
916 div->width = width; in clk_wzrd_register_divider()
917 div->flags = clk_divider_flags; in clk_wzrd_register_divider()
918 div->lock = lock; in clk_wzrd_register_divider()
919 div->hw.init = &init; in clk_wzrd_register_divider()
921 hw = &div->hw; in clk_wzrd_register_divider()
936 if (clk_wzrd->suspended) in clk_wzrd_clk_notifier()
939 if (ndata->clk == clk_wzrd->clk_in1) in clk_wzrd_clk_notifier()
940 max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1]; in clk_wzrd_clk_notifier()
941 else if (ndata->clk == clk_wzrd->axi_clk) in clk_wzrd_clk_notifier()
948 if (ndata->new_rate > max) in clk_wzrd_clk_notifier()
962 clk_disable_unprepare(clk_wzrd->axi_clk); in clk_wzrd_suspend()
963 clk_wzrd->suspended = true; in clk_wzrd_suspend()
973 ret = clk_prepare_enable(clk_wzrd->axi_clk); in clk_wzrd_resume()
979 clk_wzrd->suspended = false; in clk_wzrd_resume()
995 u32 regl, regh, edge, regld, reghd, edged, div; in clk_wzrd_register_output_clocks() local
1000 u32 reg, reg_f, mult; in clk_wzrd_register_output_clocks() local
1005 is_versal = data->is_versal; in clk_wzrd_register_output_clocks()
1009 return -ENOMEM; in clk_wzrd_register_output_clocks()
1013 clk_wzrd->clk_data.hws[0] = clk_wzrd_ver_register_divider in clk_wzrd_register_output_clocks()
1015 __clk_get_name(clk_wzrd->clk_in1), 0, in clk_wzrd_register_output_clocks()
1016 clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3), in clk_wzrd_register_output_clocks()
1025 edge = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)) & in clk_wzrd_register_output_clocks()
1027 regl = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 1)) & in clk_wzrd_register_output_clocks()
1029 regh = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 1)) & in clk_wzrd_register_output_clocks()
1036 regl = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 51)) & in clk_wzrd_register_output_clocks()
1039 regl = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 48)) & in clk_wzrd_register_output_clocks()
1043 div = 64; in clk_wzrd_register_output_clocks()
1046 clk_wzrd->clk_data.hws[0] = clk_wzrd_register_divider in clk_wzrd_register_output_clocks()
1048 __clk_get_name(clk_wzrd->clk_in1), 0, in clk_wzrd_register_output_clocks()
1049 clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3), in clk_wzrd_register_output_clocks()
1057 reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)); in clk_wzrd_register_output_clocks()
1058 reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK; in clk_wzrd_register_output_clocks()
1061 reg = reg & WZRD_CLKFBOUT_MULT_MASK; in clk_wzrd_register_output_clocks()
1062 reg = reg >> WZRD_CLKFBOUT_MULT_SHIFT; in clk_wzrd_register_output_clocks()
1063 mult = (reg * 1000) + reg_f; in clk_wzrd_register_output_clocks()
1064 div = 1000; in clk_wzrd_register_output_clocks()
1068 return -ENOMEM; in clk_wzrd_register_output_clocks()
1069 clk_wzrd->clks_internal[wzrd_clk_mul] = devm_clk_hw_register_fixed_factor in clk_wzrd_register_output_clocks()
1071 __clk_get_name(clk_wzrd->clk_in1), in clk_wzrd_register_output_clocks()
1072 0, mult, div); in clk_wzrd_register_output_clocks()
1073 if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) { in clk_wzrd_register_output_clocks()
1074 dev_err(dev, "unable to register fixed-factor clock\n"); in clk_wzrd_register_output_clocks()
1075 return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]); in clk_wzrd_register_output_clocks()
1080 return -ENOMEM; in clk_wzrd_register_output_clocks()
1083 edged = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 20)) & in clk_wzrd_register_output_clocks()
1085 regld = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 21)) & in clk_wzrd_register_output_clocks()
1087 reghd = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 21)) & in clk_wzrd_register_output_clocks()
1089 div = (regld + reghd + edged); in clk_wzrd_register_output_clocks()
1090 if (!div) in clk_wzrd_register_output_clocks()
1091 div = 1; in clk_wzrd_register_output_clocks()
1093 clk_mul_name = clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]); in clk_wzrd_register_output_clocks()
1094 clk_wzrd->clks_internal[wzrd_clk_mul_div] = in clk_wzrd_register_output_clocks()
1095 devm_clk_hw_register_fixed_factor(dev, clk_name, clk_mul_name, 0, 1, div); in clk_wzrd_register_output_clocks()
1097 ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0); in clk_wzrd_register_output_clocks()
1098 clk_wzrd->clks_internal[wzrd_clk_mul_div] = devm_clk_hw_register_divider in clk_wzrd_register_output_clocks()
1100 clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), in clk_wzrd_register_output_clocks()
1104 if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) { in clk_wzrd_register_output_clocks()
1106 return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]); in clk_wzrd_register_output_clocks()
1109 /* register div per output */ in clk_wzrd_register_output_clocks()
1110 for (i = nr_outputs - 1; i >= 0 ; i--) { in clk_wzrd_register_output_clocks()
1113 return -ENOMEM; in clk_wzrd_register_output_clocks()
1116 clk_wzrd->clk_data.hws[i] = clk_wzrd_ver_register_divider in clk_wzrd_register_output_clocks()
1119 clk_wzrd->base, in clk_wzrd_register_output_clocks()
1128 clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divf in clk_wzrd_register_output_clocks()
1129 (dev, clkout_name, clk_name, flags, clk_wzrd->base, in clk_wzrd_register_output_clocks()
1136 clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divider in clk_wzrd_register_output_clocks()
1137 (dev, clkout_name, clk_name, 0, clk_wzrd->base, in clk_wzrd_register_output_clocks()
1144 if (IS_ERR(clk_wzrd->clk_data.hws[i])) { in clk_wzrd_register_output_clocks()
1146 return PTR_ERR(clk_wzrd->clk_data.hws[i]); in clk_wzrd_register_output_clocks()
1155 struct device_node *np = pdev->dev.of_node; in clk_wzrd_probe()
1161 ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs); in clk_wzrd_probe()
1163 return -EINVAL; in clk_wzrd_probe()
1165 clk_wzrd = devm_kzalloc(&pdev->dev, struct_size(clk_wzrd, clk_data.hws, nr_outputs), in clk_wzrd_probe()
1168 return -ENOMEM; in clk_wzrd_probe()
1171 clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0); in clk_wzrd_probe()
1172 if (IS_ERR(clk_wzrd->base)) in clk_wzrd_probe()
1173 return PTR_ERR(clk_wzrd->base); in clk_wzrd_probe()
1175 clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); in clk_wzrd_probe()
1176 if (IS_ERR(clk_wzrd->axi_clk)) in clk_wzrd_probe()
1177 return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk), in clk_wzrd_probe()
1179 rate = clk_get_rate(clk_wzrd->axi_clk); in clk_wzrd_probe()
1181 dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", rate); in clk_wzrd_probe()
1182 return -EINVAL; in clk_wzrd_probe()
1185 if (!of_property_present(np, "xlnx,static-config")) { in clk_wzrd_probe()
1186 ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade); in clk_wzrd_probe()
1188 if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { in clk_wzrd_probe()
1189 dev_warn(&pdev->dev, "invalid speed grade '%d'\n", in clk_wzrd_probe()
1190 clk_wzrd->speed_grade); in clk_wzrd_probe()
1191 clk_wzrd->speed_grade = 0; in clk_wzrd_probe()
1195 clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); in clk_wzrd_probe()
1196 if (IS_ERR(clk_wzrd->clk_in1)) in clk_wzrd_probe()
1197 return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1), in clk_wzrd_probe()
1200 ret = clk_wzrd_register_output_clocks(&pdev->dev, nr_outputs); in clk_wzrd_probe()
1204 clk_wzrd->clk_data.num = nr_outputs; in clk_wzrd_probe()
1205 ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, in clk_wzrd_probe()
1206 &clk_wzrd->clk_data); in clk_wzrd_probe()
1208 dev_err(&pdev->dev, "unable to register clock provider\n"); in clk_wzrd_probe()
1212 if (clk_wzrd->speed_grade) { in clk_wzrd_probe()
1213 clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; in clk_wzrd_probe()
1215 ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->clk_in1, in clk_wzrd_probe()
1216 &clk_wzrd->nb); in clk_wzrd_probe()
1218 dev_warn(&pdev->dev, in clk_wzrd_probe()
1221 ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->axi_clk, in clk_wzrd_probe()
1222 &clk_wzrd->nb); in clk_wzrd_probe()
1224 dev_warn(&pdev->dev, in clk_wzrd_probe()
1233 { .compatible = "xlnx,versal-clk-wizard", .data = &versal_data },
1234 { .compatible = "xlnx,clocking-wizard" },
1235 { .compatible = "xlnx,clocking-wizard-v5.2" },
1236 { .compatible = "xlnx,clocking-wizard-v6.0" },
1243 .name = "clk-wizard",