Re: [PATCH 3/3] mmc: mmci: stm32: lock the STM32MP25 delay block again before tuning
From: Christophe KERELLO
Date: Mon Nov 02 2026 - 13:53:48 EST
Hello Mateusz,
This patch is similar with the one that we have on ST downstream.
mmc: mmci: stm32: release the delay block before enabling it (Commit 01d3cac)
If it is the case and if you are going to upstream ST downstream source code,
do not forget to keep ST signed-off author, please.
Regards,
Christophe Kerello.
On 10/31/26 13:07, Mateusz Nowicki wrote:
Once locked, the DLL of the delay block follows voltage and temperature
but not a change of the clock frequency. RM0457 requires the DLL to be
disabled and locked again after a frequency switch.
sdmmc_dlyb_mp25_enable() only sets EN, so a DLL left enabled by an
earlier tuning keeps its old lock. On the STM32MP257F-DK eMMC, switching
from DDR52 to HS200 then made the tuning pick a wrong phase in 9 of 18
tries. With this change the phase was correct in all 12 tries.
Clear EN and wait for LOCK to drop before enabling the DLL again.
Fixes: b5c3eb385797 ("mmc: mmci: stm32: add delay block support for STM32MP25")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Mateusz Nowicki <mateusz.nowicki@xxxxxxxxxx>
---
drivers/mmc/host/mmci_stm32_sdmmc.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c
index d74efdff6ac2..2310dba75c35 100644
--- a/drivers/mmc/host/mmci_stm32_sdmmc.c
+++ b/drivers/mmc/host/mmci_stm32_sdmmc.c
@@ -541,11 +541,21 @@ static int sdmmc_dlyb_mp15_prepare(struct mmci_host *host)
static int sdmmc_dlyb_mp25_enable(struct sdmmc_dlyb *dlyb)
{
u32 cr, sr;
+ int ret;
+ /*
+ * The DLL tracks voltage and temperature but not a frequency switch
+ * (RM0457), start the lock sequence again on the current clock
+ */
cr = readl_relaxed(dlyb->base + SYSCFG_DLYBSD_CR);
- cr |= DLYBSD_CR_EN;
+ writel_relaxed(cr & ~DLYBSD_CR_EN, dlyb->base + SYSCFG_DLYBSD_CR);
+ ret = readl_relaxed_poll_timeout(dlyb->base + SYSCFG_DLYBSD_SR,
+ sr, !(sr & DLYBSD_SR_LOCK), 1,
+ DLYBSD_TIMEOUT_1S_IN_US);
+ if (ret)
+ return ret;
- writel_relaxed(cr, dlyb->base + SYSCFG_DLYBSD_CR);
+ writel_relaxed(cr | DLYBSD_CR_EN, dlyb->base + SYSCFG_DLYBSD_CR);
return readl_relaxed_poll_timeout(dlyb->base + SYSCFG_DLYBSD_SR,
sr, sr & DLYBSD_SR_LOCK, 1,