[PATCH 1/4] mmc: core: fix timing selection for 1-bit bus width

From: ziniu . wang_1

Date: Mon Mar 02 2026 - 03:02:06 EST


From: Luke Wang <ziniu.wang_1@xxxxxxx>

When 1-bit bus width is used with HS200/HS400 capabilities set,
mmc_select_hs200() returns 0 without actually switching. This
causes mmc_select_timing() to skip mmc_select_hs(), leaving eMMC
in legacy mode (26MHz) instead of High Speed SDR (52MHz).

Per JEDEC eMMC spec section 5.3.2, 1-bit width supports High Speed
SDR. Drop incompatible HS200/HS400/UHS/DDR caps early so timing
selection falls through to mmc_select_hs() correctly.

Signed-off-by: Luke Wang <ziniu.wang_1@xxxxxxx>
---
drivers/mmc/core/host.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 88c95dbfd9cf..18b9c3174e1f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -617,17 +617,26 @@ EXPORT_SYMBOL(devm_mmc_alloc_host);
static int mmc_validate_host_caps(struct mmc_host *host)
{
struct device *dev = host->parent;
- u32 caps = host->caps, caps2 = host->caps2;

- if (caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) {
+ if (host->caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) {
dev_warn(dev, "missing ->enable_sdio_irq() ops\n");
return -EINVAL;
}

- if (caps2 & (MMC_CAP2_HS400_ES | MMC_CAP2_HS400) &&
- !(caps & MMC_CAP_8_BIT_DATA) && !(caps2 & MMC_CAP2_NO_MMC)) {
+ /* UHS/DDR/HS200/HS400 modes require at least 4-bit bus */
+ if (!(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) &&
+ ((host->caps & (MMC_CAP_UHS | MMC_CAP_DDR)) ||
+ (host->caps2 & (MMC_CAP2_HS200 | MMC_CAP2_HS400_ES | MMC_CAP2_HS400)))) {
+ dev_warn(dev, "drop UHS/DDR/HS200/HS400 support since 1-bit bus only\n");
+ host->caps &= ~(MMC_CAP_UHS | MMC_CAP_DDR);
+ host->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400_ES | MMC_CAP2_HS400);
+ }
+
+ if (host->caps2 & (MMC_CAP2_HS400_ES | MMC_CAP2_HS400) &&
+ !(host->caps & MMC_CAP_8_BIT_DATA) &&
+ !(host->caps2 & MMC_CAP2_NO_MMC)) {
dev_warn(dev, "drop HS400 support since no 8-bit bus\n");
- host->caps2 = caps2 & ~MMC_CAP2_HS400_ES & ~MMC_CAP2_HS400;
+ host->caps2 &= ~(MMC_CAP2_HS400_ES | MMC_CAP2_HS400);
}

return 0;
--
2.34.1