All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marten Lindahl <martenli@axis.com>
To: Doug Anderson <dianders@google.com>
Cc: "Mårten Lindahl" <Marten.Lindahl@axis.com>,
	"Jaehoon Chung" <jh80.chung@samsung.com>,
	"Ulf Hansson" <ulf.hansson@linaro.org>, kernel <kernel@axis.com>,
	"linux-mmc@vger.kernel.org" <linux-mmc@vger.kernel.org>
Subject: Re: [PATCH] mmc: dw_mmc: Allow lower TMOUT value than maximum
Date: Mon, 8 Nov 2021 11:30:42 +0100	[thread overview]
Message-ID: <20211108103042.GA28891@axis.com> (raw)
In-Reply-To: <CAD=FV=WsSPcs3ggGWNp5J288B+TBoSYuY7JmEWDii05w4tTdgw@mail.gmail.com>

On Sat, Nov 06, 2021 at 01:14:48AM +0100, Doug Anderson wrote:
> Hi,

Hi Doug!

> 
> On Wed, Nov 3, 2021 at 8:24 AM Mårten Lindahl <marten.lindahl@axis.com> wrote:
> >
> > The TMOUT register is always set with a full value for every transfer,
> > which (with a 200MHz clock) will give a full DRTO of ~84 milliseconds.
> > Since the software dto_timer acts as a backup in cases when this timeout
> > is not long enough, it is normally not a problem. But setting a full
> > value makes it impossible to test shorter timeouts, when for example
> > testing data read times on different SD cards.
> >
> > Add a function to set any value smaller than the maximum of 0xFFFFFF.
> >
> > Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
> > ---
> >  drivers/mmc/host/dw_mmc.c | 29 ++++++++++++++++++++++++++++-
> >  1 file changed, 28 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> > index 6578cc64ae9e..0d23b8ed9403 100644
> > --- a/drivers/mmc/host/dw_mmc.c
> > +++ b/drivers/mmc/host/dw_mmc.c
> > @@ -54,6 +54,7 @@
> >
> >  #define DW_MCI_FREQ_MAX        200000000       /* unit: HZ */
> >  #define DW_MCI_FREQ_MIN        100000          /* unit: HZ */
> > +#define DW_MCI_DATA_TMOUT_NS_MAX       83886075
> >
> >  #define IDMAC_INT_CLR          (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
> >                                  SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
> > @@ -1283,6 +1284,32 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
> >         mci_writel(host, CTYPE, (slot->ctype << slot->id));
> >  }
> >
> > +static void dw_mci_set_data_timeout(struct dw_mci *host, u32 timeout_ns)
> 
> The type of "timeout_ns" should match `struct mmc_data`, which is
> unsigned int, not u32.

Will fix.

> 
> 
> > +{
> > +       u32 timeout, freq_mhz, tmp, tmout;
> > +
> > +       if (!timeout_ns || timeout_ns > DW_MCI_DATA_TMOUT_NS_MAX) {
> > +               /* Set maximum */
> > +               tmout = 0xFFFFFFFF;
> > +               goto tmout_done;
> > +       }
> 
> I don't think that the above is right. If the card clock is 50 Hz
> instead of 200 Hz then 0xffffffff is actually ~83 ms * 4 = ~332 ms. It
> would be better to attempt to program it correctly.
> 
> Can you just do the math below and if the number is greater than can
> be represented then you can just put in the max?
> 

Yes. Good point. Much better way to do it.

> Interestingly enough, in `struct mmc_data` this is documented as a max
> of 80 ms, though I don't think your code should care about that. Just
> cap to the maximum value after your math.
> 
> 
> > +       timeout = timeout_ns;
> > +       freq_mhz = DIV_ROUND_UP(host->bus_hz, NSEC_PER_MSEC);
> > +
> > +       /* TMOUT[7:0] (RESPONSE_TIMEOUT) */
> > +       tmout = 0xFF; /* Set maximum */
> > +
> > +       /* TMOUT[31:8] (DATA_TIMEOUT) */
> > +       tmp = DIV_ROUND_UP_ULL((u64)timeout * freq_mhz, MSEC_PER_SEC);
> > +       tmout |= (tmp & 0xFFFFFF) << 8;
> 
> Combining your two calculations, I guess you have:
> 
> tmp = timeout * (bus_hz / 1000000) / 1000
> 
> Why isn't this just:
> 
> tmp = (timeout * bus_hz) / 1000000000
> 
> Since you're doing 64-bit math anyway I don't think you need to worry
> about that calculation overflowing. Multiplying two 32-bit numbers
> can't exceed 64-bits, right?

Will do so.
> 
> 
> Also: I think "bus_hz" is the wrong thing to be using here. You need
> to take CLKDIV into account like dw_mci_set_drto() does.
> 

Will do so.
Good comments. Thanks!

Kind regards
Mårten
> 
> -Doug

      reply	other threads:[~2021-11-08 10:30 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-03 15:23 [PATCH] mmc: dw_mmc: Allow lower TMOUT value than maximum Mårten Lindahl
2021-11-06  0:14 ` Doug Anderson
2021-11-08 10:30   ` Marten Lindahl [this message]

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=20211108103042.GA28891@axis.com \
    --to=martenli@axis.com \
    --cc=Marten.Lindahl@axis.com \
    --cc=dianders@google.com \
    --cc=jh80.chung@samsung.com \
    --cc=kernel@axis.com \
    --cc=linux-mmc@vger.kernel.org \
    --cc=ulf.hansson@linaro.org \
    /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.