In message: [linux-yocto][v6.1/standard/preempt-rt/sdkv6.1/xlnx-soc][PATCH] 
Revert "drivers: clk: zynqmp: update divider round rate logic"
on 10/07/2024 [email protected] wrote:

> From: Quanyang Wang <[email protected]>
> 
> This patch reverts the commit c249ef9d0978a ("drivers: clk: zynqmp:
> update divider round rate logic").
> 
> This is because that there has been a similar commit efe0d3640f6ff
> ("drivers: clk: zynqmp: update divider round rate logic") which is
> picked from SDK. This commit introduces some problem and the SDK patch
> 7e6654b576a00 ("drivers: clk: zynqmp: add hack to use old algorithm
> for divider round rate") is to fix it. But when merging, the content of
> the commit 7e6654b576a00 is missing. So we need to revert the commit
> c249ef9d0978a and bring the content of the commit 7e6654b576a00 back.
> 
> Signed-off-by: Quanyang Wang <[email protected]>
> ---
> Hi Bruce,
> Would you please help merge this patch to the branches:
>       v6.1/standard/preempt-rt/sdkv6.1/xlnx-soc
>       v6.1/standard/sdkv6.1/xlnx-soc

merged.

Bruce

> Thanks,
> Quanyang
> ---
>  drivers/clk/zynqmp/divider.c | 88 ++++++++++++++++++++++++++++++++++--
>  1 file changed, 83 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
> index a491f19ef7f8b..0ed124ba0ea6b 100644
> --- a/drivers/clk/zynqmp/divider.c
> +++ b/drivers/clk/zynqmp/divider.c
> @@ -111,6 +111,51 @@ static unsigned long 
> zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
>       return DIV_ROUND_UP_ULL(parent_rate, value);
>  }
>  
> +static void zynqmp_get_divider2_val(struct clk_hw *hw, unsigned long rate,
> +                                 struct zynqmp_clk_divider *divider,
> +                                 u32 *bestdiv)
> +{
> +     int div1;
> +     int div2;
> +     long error = LONG_MAX;
> +     unsigned long div1_prate;
> +     struct clk_hw *div1_parent_hw;
> +     struct zynqmp_clk_divider *pdivider;
> +     struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw);
> +
> +     if (!div2_parent_hw)
> +             return;
> +
> +     pdivider = to_zynqmp_clk_divider(div2_parent_hw);
> +     if (!pdivider)
> +             return;
> +
> +     div1_parent_hw = clk_hw_get_parent(div2_parent_hw);
> +     if (!div1_parent_hw)
> +             return;
> +
> +     div1_prate = clk_hw_get_rate(div1_parent_hw);
> +     *bestdiv = 1;
> +     for (div1 = 1; div1 <= pdivider->max_div;) {
> +             for (div2 = 1; div2 <= divider->max_div;) {
> +                     long new_error = ((div1_prate / div1) / div2) - rate;
> +
> +                     if (abs(new_error) < abs(error)) {
> +                             *bestdiv = div2;
> +                             error = new_error;
> +                     }
> +                     if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
> +                             div2 = div2 << 1;
> +                     else
> +                             div2++;
> +             }
> +             if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO)
> +                     div1 = div1 << 1;
> +             else
> +                     div1++;
> +     }
> +}
> +
>  /**
>   * zynqmp_clk_divider_round_rate() - Round rate of divider clock
>   * @hw:                      handle between common and hardware-specific 
> interfaces
> @@ -129,7 +174,8 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw 
> *hw,
>       u32 div_type = divider->div_type;
>       u32 bestdiv;
>       int ret;
> -     u8 width = 0;
> +     u8 width;
> +     struct device_node *np;
>  
>       /* if read only, just return current value */
>       if (divider->flags & CLK_DIVIDER_READ_ONLY) {
> @@ -149,12 +195,44 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw 
> *hw,
>               return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
>       }
>  
> -     width = fls(divider->max_div);
> +     /*
> +      * Hack to use old algorithm for round rate div clocks. Currently PL
> +      * rate is getting changed because RPLL_TO_FPD clock is changing RPLL
> +      * rate for DP audio driver. Using old algorithm RPLL rate change is
> +      * less and its not affecting PL clocks more so as a temporary solution
> +      * use old algorithm for Versal and ZynqMP platforms.
> +      *
> +      * TBD: Remove this hack and use new algorithm for all platform once PL
> +      * clock issue is fixed with better way.
> +      */
> +     np = of_find_compatible_node(NULL, NULL, "xlnx,versal-net");
> +     if (np) {
> +             width = fls(divider->max_div);
>  
> -     rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags);
> +             rate = divider_round_rate(hw, rate, prate, NULL, width, 
> divider->flags);
>  
> -     if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && 
> (rate % *prate))
> -             *prate = rate;
> +             if (divider->is_frac && (clk_hw_get_flags(hw) & 
> CLK_SET_RATE_PARENT) &&
> +                 (rate % *prate))
> +                     *prate = rate;
> +     } else {
> +             bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags);
> +
> +             /*
> +              * In case of two divisors, compute best divider values and 
> return
> +              * divider2 value based on compute value. div1 will  be 
> automatically
> +              * set to optimum based on required total divider value.
> +              */
> +             if (div_type == TYPE_DIV2 && (clk_hw_get_flags(hw) &
> +                 CLK_SET_RATE_PARENT))
> +                     zynqmp_get_divider2_val(hw, rate, divider, &bestdiv);
> +
> +             if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) &&
> +                 divider->is_frac)
> +                     bestdiv = rate % *prate ? 1 : bestdiv;
> +
> +             bestdiv = min_t(u32, bestdiv, divider->max_div);
> +             *prate = rate * bestdiv;
> +     }
>  
>       return rate;
>  }
> -- 
> 2.36.1
> 
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#14142): 
https://lists.yoctoproject.org/g/linux-yocto/message/14142
Mute This Topic: https://lists.yoctoproject.org/mt/107138006/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to