Re: [PATCH RESEND 2/2] drivers: clk: zynqmp: update divider round rate logic

From: Stephen Boyd
Date: Mon Oct 23 2023 - 23:37:56 EST


Quoting Jay Buddhabhatti (2023-10-16 04:30:02)
> Currently zynqmp divider round rate is considering single parent and
> calculating rate and parent rate accordingly. But if divider clock flag
> is set to SET_RATE_PARENT then its not trying to traverse through all
> parent rate and not selecting best parent rate from that. So use common
> divider_round_rate() which is traversing through all clock parents and
> its rate and calculating proper parent rate.
>
> Signed-off-by: Jay Buddhabhatti <jay.buddhabhatti@xxxxxxx>
> ---
> drivers/clk/zynqmp/divider.c | 70 ++++++------------------------------
> 1 file changed, 10 insertions(+), 60 deletions(-)

Can't argue against removing that many lines!

>
> diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
> index 33a3b2a22659..a42c183d7e5d 100644
> --- a/drivers/clk/zynqmp/divider.c
> +++ b/drivers/clk/zynqmp/divider.c
> @@ -193,23 +149,17 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
> return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
> }
>
> - 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);
> + max = divider->max_div;
> + while (max != 0) {
> + if ((max & 1) == 1)
> + width++;
> + max = max >> 1;

Is this ffs()?

> }
>
> - if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
> - bestdiv = rate % *prate ? 1 : bestdiv;
> + rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags);
>
> - bestdiv = min_t(u32, bestdiv, divider->max_div);
> - *prate = rate * bestdiv;
> + if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (rate % *prate))
> + *prate = rate;