Re: [PATCH v5 07/11] clk: sunxi-ng: nkm: Support finding closest rate
From: Jernej Škrabec
Date: Sun Aug 06 2023 - 09:42:31 EST
Dne nedelja, 06. avgust 2023 ob 15:06:52 CEST je Frank Oltmanns napisal(a):
> When finding the best rate for a NKM clock, consider rates that are
> higher than the requested rate, if the CCU_FEATURE_CLOSEST_RATE flag is
> set by using the helper function ccu_is_better_rate().
>
> Accommodate ccu_mux_helper_determine_rate to this change.
>
> Acked-by: Maxime Ripard <mripard@xxxxxxxxxx>
> Signed-off-by: Frank Oltmanns <frank@xxxxxxxxxxxx>
Reviewed-by: Jernej Skrabec <jernej.skrabec@xxxxxxxxx>
Best regards,
Jernej
> ---
> drivers/clk/sunxi-ng/ccu_mux.c | 2 +-
> drivers/clk/sunxi-ng/ccu_nkm.c | 20 +++++++++-----------
> 2 files changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c
> index 1d557e323169..3ca695439620 100644
> --- a/drivers/clk/sunxi-ng/ccu_mux.c
> +++ b/drivers/clk/sunxi-ng/ccu_mux.c
> @@ -139,7 +139,7 @@ int ccu_mux_helper_determine_rate(struct ccu_common
> *common, goto out;
> }
>
> - if ((req->rate - tmp_rate) < (req->rate - best_rate)) {
> + if (ccu_is_better_rate(common, req->rate, tmp_rate,
best_rate)) {
> best_rate = tmp_rate;
> best_parent_rate = parent_rate;
> best_parent = parent;
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index ea1b77e9b57f..896bb1ef8642 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -17,7 +17,8 @@ struct _ccu_nkm {
> unsigned long m, min_m, max_m;
> };
>
> -static unsigned long ccu_nkm_find_best_with_parent_adj(struct clk_hw
> *parent_hw, +static unsigned long ccu_nkm_find_best_with_parent_adj(struct
> ccu_common *common, +
struct clk_hw *parent_hw,
>
unsigned long *parent, unsigned long rate,
>
struct _ccu_nkm *nkm)
> {
> @@ -33,10 +34,8 @@ static unsigned long
> ccu_nkm_find_best_with_parent_adj(struct clk_hw *parent_hw, tmp_parent =
> clk_hw_round_rate(parent_hw, rate * _m / (_n * _k));
>
> tmp_rate = tmp_parent * _n * _k /
_m;
> - if (tmp_rate > rate)
> - continue;
>
> - if ((rate - tmp_rate) < (rate -
best_rate)) {
> + if (ccu_is_better_rate(common,
rate, tmp_rate, best_rate)) {
> best_rate = tmp_rate;
> best_parent_rate =
tmp_parent;
> best_n = _n;
> @@ -57,7 +56,7 @@ static unsigned long
> ccu_nkm_find_best_with_parent_adj(struct clk_hw *parent_hw, }
>
> static unsigned long ccu_nkm_find_best(unsigned long parent, unsigned long
> rate, - struct _ccu_nkm *nkm)
> + struct _ccu_nkm *nkm,
struct ccu_common *common)
> {
> unsigned long best_rate = 0;
> unsigned long best_n = 0, best_k = 0, best_m = 0;
> @@ -70,9 +69,7 @@ static unsigned long ccu_nkm_find_best(unsigned long
> parent, unsigned long rate,
>
> tmp_rate = parent * _n * _k / _m;
>
> - if (tmp_rate > rate)
> - continue;
> - if ((rate - tmp_rate) < (rate -
best_rate)) {
> + if (ccu_is_better_rate(common,
rate, tmp_rate, best_rate)) {
> best_rate = tmp_rate;
> best_n = _n;
> best_k = _k;
> @@ -165,9 +162,10 @@ static unsigned long ccu_nkm_round_rate(struct
> ccu_mux_internal *mux, rate *= nkm->fixed_post_div;
>
> if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
> - rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm);
> + rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm-
>common);
> else
> - rate = ccu_nkm_find_best_with_parent_adj(parent_hw,
parent_rate, rate,
> &_nkm); + rate = ccu_nkm_find_best_with_parent_adj(&nkm->common,
> parent_hw, parent_rate, rate, +
&_nkm);
>
> if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
> rate /= nkm->fixed_post_div;
> @@ -202,7 +200,7 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned
> long rate, _nkm.min_m = 1;
> _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
>
> - ccu_nkm_find_best(parent_rate, rate, &_nkm);
> + ccu_nkm_find_best(parent_rate, rate, &_nkm, &nkm->common);
>
> spin_lock_irqsave(nkm->common.lock, flags);