All of lore.kernel.org
 help / color / mirror / Atom feed
From: Biju Das <biju.das.jz@bp.renesas.com>
To: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>,
	Wolfram Sang <wsa+renesas@sang-engineering.com>,
	"linux-mmc@vger.kernel.org" <linux-mmc@vger.kernel.org>,
	"linux-renesas-soc@vger.kernel.org" 
	<linux-renesas-soc@vger.kernel.org>,
	Chris Paterson <Chris.Paterson2@renesas.com>,
	Biju Das <biju.das@bp.renesas.com>,
	Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>
Subject: RE: [PATCH] mmc: renesas_sdhi: Add margins for main clock and hs clock
Date: Fri, 16 Sep 2022 18:14:46 +0000	[thread overview]
Message-ID: <OS0PR01MB592274E1073EDEB237A615B186489@OS0PR01MB5922.jpnprd01.prod.outlook.com> (raw)
In-Reply-To: <OS0PR01MB5922B3C19E9806BD30A8FAEB86489@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi Geert,

> Subject: RE: [PATCH] mmc: renesas_sdhi: Add margins for main clock and
> hs clock
> 
> Hi Geert,
> 
> > Subject: RE: [PATCH] mmc: renesas_sdhi: Add margins for main clock
> and
> > hs clock
> >
> > Hi Geert,
> >
> > Thanks for the feedback.
> >
> > > Subject: Re: [PATCH] mmc: renesas_sdhi: Add margins for main clock
> > and
> > > hs clock
> > >
> > > Hi Biju,
> > >
> > > On Wed, Sep 14, 2022 at 6:44 AM Biju Das
> > <biju.das.jz@bp.renesas.com>
> > > wrote:
> > > > > Subject: RE: [PATCH] mmc: renesas_sdhi: Add margins for main
> > clock
> > > > > and hs clock
> > > > > > Subject: Re: [PATCH] mmc: renesas_sdhi: Add margins for main
> > > clock
> > > > > > and hs clock On Tue, Sep 13, 2022 at 5:15 PM Biju Das
> > > > > > <biju.das.jz@bp.renesas.com>
> > > > > > wrote:
> > > > > > > The SDHI high speed clock is 4 times that of the main
> clock.
> > > > > > > Currently, there is no margin added for setting the rate
> > > > > > > associated with these clocks. On RZ/G2L platforms, the
> lack
> > of
> > > > > > > these margins leads to the selection of a clock source
> with
> > a
> > > > > > > lower clock rate compared to a higher one.
> > > > > > >
> > > > > > > RZ/G2L example case:
> > > > > > > SD0 hs clock is 533333333 Hz and SD0 main clock is
> 133333333
> > > Hz.
> > > > > > > When we set the rate for the main clock 133333333, the
> > request
> > > > > > > rate for the parent becomes 533333332 (133333333 * 4) and
> > the
> > > > > > > SD0 hs clock is set as 400000000 Hz.
> > > > > > >
> > > > > > > This patch adds a margin of (1/1024) higher hs clock and
> > main
> > > > > > > clock
> > > > > > rate.
> > > > > > >
> > > > > > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> > > > > >
> > > > > > Thanks for your patch!
> > > > > >
> > > > > > > --- a/drivers/mmc/host/renesas_sdhi_core.c
> > > > > > > +++ b/drivers/mmc/host/renesas_sdhi_core.c
> > > > > > > @@ -147,6 +147,7 @@ static unsigned int
> > > > > > > renesas_sdhi_clk_update(struct
> > > > > > tmio_mmc_host *host,
> > > > > > >         }
> > > > > > >
> > > > > > >         new_clock = wanted_clock << clkh_shift;
> > > > > > > +       new_clock += new_clock >> 10;
> > > > > >
> > > > > > This changes the requested clock rate. Is that really a good
> > > idea?
> > > > > >
> > > > > > Isn't it sufficient to change the test "if (freq >
> (new_clock
> > <<
> > > i))"
> > > > > > slightly?
> > > > >
> > > > > We hardly enter this test, after it request for proper
> > wanted_clk.
> > > > >
> > > > > freq is clk_round_rate(ref_clk, new_clock << i);  and it
> > compares
> > > > > 400MHz vs 533.332 MHz.
> > > > >
> > > > > Basically wanted_clock= 133.33333 MHz and is scaled to power
> of
> > 2
> > > > > and then each iteration it scale down to power of 2 compare
> with
> > > > > round rate value.
> > > > >
> > > > > [    4.020781] ####rzg2l_cpg_sd_clk_mux_determine_rate#######
> > req-
> > > > > >rate=4266666656
> > > > > [    4.028013] ####rzg2l_cpg_sd_clk_mux_determine_rate#######
> > req-
> > > > > >rate=2133333328
> > > > > [    4.035330] ####rzg2l_cpg_sd_clk_mux_determine_rate#######
> > req-
> > > > > >rate=1066666664
> > > > > [    4.042639] ####rzg2l_cpg_sd_clk_mux_determine_rate#######
> > req-
> > > > > >rate=533333332
> > > > >
> > > > > >
> > > > > > >
> > > > > > >         /*
> > > > > > >          * We want the bus clock to be as close as
> possible
> > > to,
> > > > > > > but no @@ -172,6 +173,7 @@ static unsigned int
> > > > > > > renesas_sdhi_clk_update(struct tmio_mmc_host *host,
> > > > > > >
> > > > > > >         clk_set_rate(ref_clk, best_freq);
> > > > > > >
> > > > > > > +       best_freq += best_freq >> 10;
> > > > > >
> > > > > > Can you please elaborate why this is needed?
> > > > > > It looks counter-intuitive to me.
> > > > >
> > > > > When we try to set 133.333 MHz clk, the determine rate
> > calculates
> > > > > req-
> > > > > >rate for sd clk as 533.332 and since available clock source
> for
> > > sd0
> > > > > >clks
> > > > > are 266.6666, 400 and
> > > > > 533.333 MHz, so it select the clock source as 400MHz.
> > > >
> > > > Just to add here the main issue is coming from math calculation.
> > > >
> > > > Consider any value A
> > > >
> > > > B = A / 4
> > > > C = B * 4
> > > >
> > > > Ideally, we expect A = C, But in the below example It is not the
> > > case
> > > > (it is A != C).
> > > >
> > > > A = 533333333 (1600/3 MHz)
> > > > B = 533333333/4 = 133333333
> > > > C = 133333333 * 4 = 533333332
> > > >
> > > > Since A != C we are ending up in this situation.
> > >
> > > I am fully aware of that ;-)
> > >
> > > However, clk_round_rate() is supposed to return the closest
> matching
> > > rate.  Hence when passed 533333332, it should return 533333333.
> >
> > No, it is returning 400000000.as ref_clk->rate=400000000, and new
> clk
> > rate 533333332
> >
> > [    4.524188] ###renesas_sdhi_clk_update ++ ###
> > 400000000/533333333/533333332
> > [    4.531217] ###renesas_sdhi_clk_update -- ###
> > 400000000/400000000/533333332
> >
> > +               pr_err("###%s ++ ### %llu/%llu/%llu", __func__,
> > + clk_get_rate(ref_clk),freq, new_clock << i);
> >                 freq = clk_round_rate(ref_clk, new_clock << i);
> > +               pr_err("###%s -- ### %llu/%llu/%llu", __func__,
> > + clk_get_rate(ref_clk),freq, new_clock << i);
> >
> > > AFAIU, this is then rejected by "if (freq > (new_clock << i))",
> due
> > to
> > > being slightly too large, causing 400000000 to be picked instead.
> > >
> > > Am I missing something?
> >
> > With the above, it skips the if statement
> >
> > > I'm currently not in the position to test/verify what is actually
> > > happening.
> >
> > OK Will check.
> 
> I have patched SDHI driver to allow margin, so that it won't set a
> lower clock and added round clock operation in Clock driver for
> rounding operation.
> with that I get proper rates.
> 
> Is this solution acceptable or not?
> 
> [1]
> diff --git a/drivers/mmc/host/renesas_sdhi_core.c
> b/drivers/mmc/host/renesas_sdhi_core.c
> index 6edbf5c161ab..bb7a736d46a2 100644
> --- a/drivers/mmc/host/renesas_sdhi_core.c
> +++ b/drivers/mmc/host/renesas_sdhi_core.c
> @@ -128,6 +128,7 @@ static unsigned int renesas_sdhi_clk_update(struct
> tmio_mmc_host *host,
>         struct clk *ref_clk = priv->clk;
>         unsigned int freq, diff, best_freq = 0, diff_min = ~0;
>         unsigned int new_clock, clkh_shift = 0;
> +       unsigned int new_clock_margin;
>         int i;
> 
>         /*
> @@ -155,8 +156,13 @@ static unsigned int
> renesas_sdhi_clk_update(struct tmio_mmc_host *host,
>          * possible, but no greater than, new_clock << i.
>          */
>         for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
> -               freq = clk_round_rate(ref_clk, new_clock << i);
> -               if (freq > (new_clock << i)) {
> +               if (freq <= (new_clock << i))
> +                       freq = clk_round_rate(ref_clk, new_clock <<
> i);
> +
> +               new_clock_margin = (new_clock << i);
> +               new_clock_margin += new_clock_margin >> 10;
> +
> +               if (freq > new_clock_margin) {
>                         /* Too fast; look for a slightly slower option
> */
>                         freq = clk_round_rate(ref_clk, (new_clock <<
> i) / 4 * 3);
>                         if (freq > (new_clock << i))

Looks like for SDHI, the below clock margin change should be sufficient.
As the round operation in RZ/G2L clk driver changes[2] rounds to 
nearest clk(ie,533.332MHZ to 533.333MHz)

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 6edbf5c161ab..539521f84e2f 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -128,6 +128,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
        struct clk *ref_clk = priv->clk;
        unsigned int freq, diff, best_freq = 0, diff_min = ~0;
        unsigned int new_clock, clkh_shift = 0;
+       unsigned int new_clock_margin;
        int i;
 
        /*
@@ -156,7 +157,9 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
         */
        for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
                freq = clk_round_rate(ref_clk, new_clock << i);
-               if (freq > (new_clock << i)) {
+               new_clock_margin = (new_clock << i) + ((new_clock << i) >> 10);
+
+               if (freq > new_clock_margin) {

Cheers,
Biju

  reply	other threads:[~2022-09-16 18:14 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-13 16:15 [PATCH] mmc: renesas_sdhi: Add margins for main clock and hs clock Biju Das
2022-09-13 17:12 ` Geert Uytterhoeven
2022-09-13 17:31   ` Biju Das
2022-09-14  5:44     ` Biju Das
2022-09-14 15:44       ` Geert Uytterhoeven
2022-09-16 11:47         ` Biju Das
2022-09-16 16:04           ` Biju Das
2022-09-16 18:14             ` Biju Das [this message]
2022-09-16 18:40               ` Wolfram Sang
2022-09-19  8:33                 ` Biju Das

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=OS0PR01MB592274E1073EDEB237A615B186489@OS0PR01MB5922.jpnprd01.prod.outlook.com \
    --to=biju.das.jz@bp.renesas.com \
    --cc=Chris.Paterson2@renesas.com \
    --cc=biju.das@bp.renesas.com \
    --cc=geert@linux-m68k.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=prabhakar.mahadev-lad.rj@bp.renesas.com \
    --cc=ulf.hansson@linaro.org \
    --cc=wsa+renesas@sang-engineering.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.