All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Masney <bmasney@redhat.com>
To: Joey Lu <a0987203069@gmail.com>
Cc: mturquette@baylibre.com, sboyd@kernel.org, ychuang3@nuvoton.com,
	schung@nuvoton.com, yclu4@nuvoton.com,
	linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/1] clk: nuvoton: ma35d1: fix PLL frequency calculation
Date: Mon, 11 May 2026 11:54:16 -0400	[thread overview]
Message-ID: <agH7qJypv48vkZOr@redhat.com> (raw)
In-Reply-To: <20260511031600.31929-2-a0987203069@gmail.com>

Hi Joey,

On Mon, May 11, 2026 at 11:15:59AM +0800, Joey Lu wrote:
> Fix four bugs in the MA35D1 PLL driver:
> 
> 1. PLL_CTL1_FRAC was defined as GENMASK(31, 24) (8 bits), but the
>    hardware fractional field spans bits [31:8] (24 bits). This caused
>    wrong frequency calculation in fractional and spread-spectrum modes.
> 
> 2. div_u64() does not modify its argument in-place; the quotient must
>    be assigned from the return value. Both ma35d1_calc_smic_pll_freq()
>    and ma35d1_calc_pll_freq() discarded the return value, leaving
>    pll_freq undivided and orders of magnitude too high.
> 
> 3. The fractional-mode calculation divided x by FIELD_MAX(PLL_CTL1_FRAC)
>    to get 2 decimal digits. After correcting the mask to 24 bits, update
>    the arithmetic to use 3 decimal digits with proper 24-bit fixed-point
>    rounding.
> 
> 4. ma35d1_clk_pll_determine_rate() called ma35d1_pll_find_closest()
>    unconditionally before the switch, but then overwrote its result by
>    reading the current hardware registers for every PLL type. Move the
>    find_closest() call inside the configurable-PLL branch (APLL, EPLL,
>    VPLL). CAPLL and DDRPLL do not support runtime rate changes and
>    correctly return the current hardware rate.
> 
> Fixes: 691521a367cf ("clk: nuvoton: Add clock driver for ma35d1 clock controller")
> Signed-off-by: Joey Lu <a0987203069@gmail.com>

Thanks for the patch, however this should really be broken up into more
patches. If possible, one patch for each of the fixes.

Brian


> ---
>  drivers/clk/nuvoton/clk-ma35d1-pll.c | 34 +++++++++++++--------------
>  1 file changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/clk/nuvoton/clk-ma35d1-pll.c b/drivers/clk/nuvoton/clk-ma35d1-pll.c
> index 4620acfe47e8..314b81e7727c 100644
> --- a/drivers/clk/nuvoton/clk-ma35d1-pll.c
> +++ b/drivers/clk/nuvoton/clk-ma35d1-pll.c
> @@ -48,7 +48,7 @@
>  #define PLL_CTL1_PD		BIT(0)
>  #define PLL_CTL1_BP		BIT(1)
>  #define PLL_CTL1_OUTDIV		GENMASK(6, 4)
> -#define PLL_CTL1_FRAC		GENMASK(31, 24)
> +#define PLL_CTL1_FRAC		GENMASK(31, 8)
>  #define PLL_CTL2_SLOPE		GENMASK(23, 0)
>  
>  #define INDIV_MIN		1
> @@ -92,7 +92,7 @@ static unsigned long ma35d1_calc_smic_pll_freq(u32 pll0_ctl0,
>  	p = FIELD_GET(SPLL0_CTL0_OUTDIV, pll0_ctl0);
>  	outdiv = 1 << p;
>  	pll_freq = (u64)parent_rate * n;
> -	div_u64(pll_freq, m * outdiv);
> +	pll_freq = div_u64(pll_freq, m * outdiv);
>  	return pll_freq;
>  }
>  
> @@ -110,12 +110,12 @@ static unsigned long ma35d1_calc_pll_freq(u8 mode, u32 *reg_ctl, unsigned long p
>  
>  	if (mode == PLL_MODE_INT) {
>  		pll_freq = (u64)parent_rate * n;
> -		div_u64(pll_freq, m * p);
> +		pll_freq = div_u64(pll_freq, m * p);
>  	} else {
>  		x = FIELD_GET(PLL_CTL1_FRAC, reg_ctl[1]);
> -		/* 2 decimal places floating to integer (ex. 1.23 to 123) */
> -		n = n * 100 + ((x * 100) / FIELD_MAX(PLL_CTL1_FRAC));
> -		pll_freq = div_u64(parent_rate * n, 100 * m * p);
> +		/* x is 24-bit fractional part, convert to 3 decimal digits */
> +		n = n * 1000 + (u32)(((u64)x * 1000 + 500) >> 24);
> +		pll_freq = div_u64((u64)parent_rate * n, 1000 * m * p);
>  	}
>  	return pll_freq;
>  }
> @@ -255,32 +255,32 @@ static int ma35d1_clk_pll_determine_rate(struct clk_hw *hw,
>  	if (req->best_parent_rate < PLL_FREF_MIN_FREQ || req->best_parent_rate > PLL_FREF_MAX_FREQ)
>  		return -EINVAL;
>  
> -	ret = ma35d1_pll_find_closest(pll, req->rate, req->best_parent_rate,
> -				      reg_ctl, &pll_freq);
> -	if (ret < 0)
> -		return ret;
> -
>  	switch (pll->id) {
>  	case CAPLL:
> +	case DDRPLL:
> +		/* Read-only PLLs: return current rate */
>  		reg_ctl[0] = readl_relaxed(pll->ctl0_base);
> -		pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], req->best_parent_rate);
> +		if (pll->id == CAPLL) {
> +			pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], req->best_parent_rate);
> +		} else {
> +			reg_ctl[1] = readl_relaxed(pll->ctl1_base);
> +			pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, req->best_parent_rate);
> +		}
>  		req->rate = pll_freq;
> -
>  		return 0;
> -	case DDRPLL:
>  	case APLL:
>  	case EPLL:
>  	case VPLL:
> -		reg_ctl[0] = readl_relaxed(pll->ctl0_base);
> -		reg_ctl[1] = readl_relaxed(pll->ctl1_base);
> -		pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, req->best_parent_rate);
> +		/* Configurable PLLs: find closest achievable rate */
> +		ret = ma35d1_pll_find_closest(pll, req->rate, req->best_parent_rate,
> +					      reg_ctl, &pll_freq);
> +		if (ret < 0)
> +			return ret;
>  		req->rate = pll_freq;
> -
>  		return 0;
>  	}
>  
>  	req->rate = 0;
> -
>  	return 0;
>  }
>  
> -- 
> 2.49.0


  reply	other threads:[~2026-05-11 15:54 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-11  3:15 [PATCH 0/1] clk: nuvoton: ma35d1: fix PLL frequency calculation Joey Lu
2026-05-11  3:15 ` [PATCH 1/1] " Joey Lu
2026-05-11 15:54   ` Brian Masney [this message]
2026-05-12  3:49     ` Joey Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=agH7qJypv48vkZOr@redhat.com \
    --to=bmasney@redhat.com \
    --cc=a0987203069@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=sboyd@kernel.org \
    --cc=schung@nuvoton.com \
    --cc=ychuang3@nuvoton.com \
    --cc=yclu4@nuvoton.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.