Skip to content

Commit

Permalink
mmc: dw_mmc: Fix the DTO timeout calculation
Browse files Browse the repository at this point in the history
Just like the CTO timeout calculation introduced recently, the DTO
timeout calculation was incorrect.  It used "bus_hz" but, as far as I
can tell, it's supposed to use the card clock.  Let's account for the
div value, which is documented as 2x the value stored in the register,
or 1 if the register is 0.

NOTE: This was likely not terribly important until commit 16a3457
("mmc: dw_mmc: remove the quirks flags") landed because "DIV" is
documented on Rockchip SoCs (the ones that used to define the quirk)
to always be 0 or 1.  ...and, in fact, it's documented to only be 1
with EMMC in 8-bit DDR52 mode.  Thus before the quirk was applied to
everyone it was mostly OK to ignore the DIV value.

I haven't personally observed any problems that are fixed by this
patch but I also haven't tested this anywhere with a DIV other an 0.
AKA: this problem was found simply by code inspection and I have no
failing test cases that are fixed by it.  Presumably this could fix
real bugs for someone out there, though.

Fixes: 16a3457 ("mmc: dw_mmc: remove the quirks flags")
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
  • Loading branch information
dianders authored and storulf committed Nov 1, 2017
1 parent 8892b70 commit 9d9491a
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion drivers/mmc/host/dw_mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1936,10 +1936,15 @@ static int dw_mci_data_complete(struct dw_mci *host, struct mmc_data *data)
static void dw_mci_set_drto(struct dw_mci *host)
{
unsigned int drto_clks;
unsigned int drto_div;
unsigned int drto_ms;

drto_clks = mci_readl(host, TMOUT) >> 8;
drto_ms = DIV_ROUND_UP(drto_clks, host->bus_hz / 1000);
drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2;
if (drto_div == 0)
drto_div = 1;
drto_ms = DIV_ROUND_UP(MSEC_PER_SEC * drto_clks * drto_div,
host->bus_hz);

/* add a bit spare time */
drto_ms += 10;
Expand Down

0 comments on commit 9d9491a

Please sign in to comment.