[PATCH 3/3] mmc: mmci: stm32: lock the STM32MP25 delay block again before tuning
Christophe KERELLO
christophe.kerello at foss.st.com
Mon Nov 2 09:13:09 PST 2026
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 at vger.kernel.org
> Signed-off-by: Mateusz Nowicki <mateusz.nowicki at posteo.net>
> ---
> 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,
More information about the linux-arm-kernel
mailing list