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