All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adam Ford <aford173@gmail.com>
To: linux-mmc <linux-mmc@vger.kernel.org>,
	Wolfram Sang <wsa+renesas@sang-engineering.com>,
	Ulf Hansson <ulf.hansson@linaro.org>,
	Geert Uytterhoeven <geert+renesas@glider.be>
Subject: RZ/G2M Hangs when booting some SD cards
Date: Mon, 11 Apr 2022 08:07:17 -0500	[thread overview]
Message-ID: <CAHCN7xK_fr_gREVsOzN=atcS08mwufr-=7q1JAN=CCyVk_k-dA@mail.gmail.com> (raw)

I have a small collection of microSD cards that appear to hang when
booting.  It affects Renesas' 4.19 CIP kernel as well as 5.18.0-rc2
with the following:

[    2.717601] mmc1: tuning execution failed: -5
[    2.721979] mmc1: error -5 whilst initialising SD card
[    2.839001] mmc1: tuning execution failed: -5
[    2.843378] mmc1: error -5 whilst initialising SD card

I can use these same cards on a different platform like NXP IXM8M, and
they enumerate and mount just fine on a Linux machine, and my boot
vFAT partition mounts just fine on a Windows machine, so it seems
limited to just Renesas on Linux.

I did some testing, and I found that U-Boot on the same board can also
properly initialize the microSD card and it emuerates at sdr104.

Manufacturer ID: 1d
OEM: 4144
Name: USDBus Speed: 199999992
Mode: UHS SDR104 (208MHz)
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 29.8 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
=>

This lead me to believe that U-Boot is initializing the micro SD card
differently than Linux, so I investigated the drivers in both to
compare what's happening differently.

The drivers between U-Boot [1] and Linux [2] appear very similar to
each other, but I noticed that U-Boot does something that Linux does
not do.

In U-Boot, renesas_sdhi_select_tuning checks a series of bits in
priv->smcmp and clears them.

renesas_sdhi_select_tuning()
<snip>

for (i = 0; i < priv->tap_num * 2; i++) {
    if (!(taps & BIT(i))) {
        taps &= ~BIT(i % priv->tap_num);
        taps &= ~BIT((i % priv->tap_num) + priv->tap_num);
    }
    if (!(priv->smpcmp & BIT(i))) {
        priv->smpcmp &= ~BIT(i % priv->tap_num);
        priv->smpcmp &= ~BIT((i % priv->tap_num) + priv->tap_num);
    }
}

Later in the code, it checks to see if various bits in priv->smcmp are set

for (i = 0; i < priv->tap_num * 2; i++) {
    if (priv->smpcmp & BIT(i))
        ntap++;
    else {
        if (ntap > match_cnt) {
            tap_start = i - ntap;
            tap_end = i - 1;
            match_cnt = ntap;
        }

<snip>

In Linux, the driver is split into multiple parts, so it's a little
harder to follow, but it appears to do something similar in
renesas_sdhi_select_tuning where it checks bits and clears various
bits in priv-smpcmp:

for (i = 0; i < taps_size; i++) {
    int offset = priv->tap_num * (i < priv->tap_num ? 1 : -1);

    if (!test_bit(i, priv->taps))
        clear_bit(i + offset, priv->taps);

    if (!test_bit(i, priv->smpcmp))
        clear_bit(i + offset, priv->smpcmp);
}

So far, these look fairly similar.

However,  a bit later, the code that checks the smcmp in U-Boot
appears dramatically different in Linux, and I don't understand the
tuning phase nor do  I have the sd card spec.

In U-BOot there is a comment (with some corresponding code) that states:

/*
* Find the longest consecutive run of successful probes.  If that
* is more than RENESAS_SDHI_MAX_TAP probes long then use the
* center index as the tap.
*/

This chunk of code appears drastically different from the Linux side,
but maybe it's ok.

Then later, U-Boot has a for loop which either increases the ntap if
priv->smpcmp & BIT(it) is set or does some math on adjusting
tap_start, end and match_cnt.  It's covered by a comment that reads:

/*
* If all of the TAP is OK, the sampling clock position is selected by
* identifying the change point of data.
*/

I don't understand the logic on the Linux side, but when we get down a
bit further, we end with

if (tap_cnt >= min_tap_row)
    priv->tap_set = (tap_start + tap_end) / 2 % priv->tap_num;
else
    return -EIO;

Which I believe yields the failure  of

"error -5 whilst initialising SD card" that I mentioned above.

I was thinking about taking the math from the U-Boot and porting it to
Linux to see if the issue goes away, but before I did that, I was
hoping someone might have some insights to see if that's the right
direction to go.

thanks

adam

[1] - https://source.denx.de/u-boot/u-boot/-/blob/master/drivers/mmc/renesas-sdhi.c
[2] - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mmc/host/renesas_sdhi_core.c?h=v5.18-rc2

             reply	other threads:[~2022-04-11 13:07 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-11 13:07 Adam Ford [this message]
2022-04-11 19:11 ` RZ/G2M Hangs when booting some SD cards Wolfram Sang
2022-04-11 19:38   ` Adam Ford
2022-04-12  9:04     ` Wolfram Sang
2022-04-12 15:01       ` Wolfram Sang
2022-04-12 21:38         ` Adam Ford
2022-04-19 12:50         ` Adam Ford
2023-05-31  6:51           ` Wolfram Sang
2023-05-31 10:23             ` Adam Ford

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='CAHCN7xK_fr_gREVsOzN=atcS08mwufr-=7q1JAN=CCyVk_k-dA@mail.gmail.com' \
    --to=aford173@gmail.com \
    --cc=geert+renesas@glider.be \
    --cc=linux-mmc@vger.kernel.org \
    --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.