[PATCH v2 3/5] mmc: mmci: stm32: use the delay block above 100 MHz on stm32mp25 SoC
From: Mateusz Nowicki
Date: Wed Nov 04 2026 - 10:43:21 EST
From: Christophe Kerello <christophe.kerello@xxxxxxxxxxx>
On stm32mp25 SoC, the delay block has to be used only for an external
data frequency above 100 MHz. Skip the tuning up to that frequency, keep
50 MHz for stm32mp15 as before.
Fixes: b5c3eb385797 ("mmc: mmci: stm32: add delay block support for STM32MP25")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Christophe Kerello <christophe.kerello@xxxxxxxxxxx>
[Mateusz: reworded the commit message, check dlyb before reading
min_freq, added Fixes and Cc stable]
Signed-off-by: Mateusz Nowicki <mateusz.nowicki@xxxxxxxxxx>
---
Notes:
On the STM32MP257F-DK (SDMMC2 kernel clock 200 MHz, eMMC in HS200 at
100 MHz) the writes failed with I/O errors in all 9 test runs without
this change, with sdmmc2 pins_a or pins_b and with or without NEGEDGE.
With it all 6 runs were correct, on both pin groups.
drivers/mmc/host/mmci_stm32_sdmmc.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c
index bb058e0910ad..a50dc58336de 100644
--- a/drivers/mmc/host/mmci_stm32_sdmmc.c
+++ b/drivers/mmc/host/mmci_stm32_sdmmc.c
@@ -75,6 +75,7 @@ struct sdmmc_dlyb {
void __iomem *base;
u32 unit;
u32 max;
+ unsigned int min_freq;
struct sdmmc_tuning_ops *ops;
};
@@ -636,14 +637,16 @@ static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
u32 clk;
int ret;
- if ((host->mmc->ios.timing != MMC_TIMING_UHS_SDR104 &&
- host->mmc->ios.timing != MMC_TIMING_MMC_HS200) ||
- host->mmc->actual_clock <= 50000000)
+ if (host->mmc->ios.timing != MMC_TIMING_UHS_SDR104 &&
+ host->mmc->ios.timing != MMC_TIMING_MMC_HS200)
return 0;
if (!dlyb || !dlyb->base)
return -EINVAL;
+ if (host->mmc->actual_clock <= dlyb->min_freq)
+ return 0;
+
ret = dlyb->ops->dlyb_enable(dlyb);
if (ret)
return ret;
@@ -749,10 +752,13 @@ void sdmmc_variant_init(struct mmci_host *host)
return;
dlyb->base = base_dlyb;
- if (of_device_is_compatible(np, "st,stm32mp25-sdmmc2"))
+ if (of_device_is_compatible(np, "st,stm32mp25-sdmmc2")) {
dlyb->ops = &dlyb_tuning_mp25_ops;
- else
+ dlyb->min_freq = 100000000;
+ } else {
dlyb->ops = &dlyb_tuning_mp15_ops;
+ dlyb->min_freq = 50000000;
+ }
host->variant_priv = dlyb;
host->mmc_ops->execute_tuning = sdmmc_execute_tuning;
--
2.56.0