From: Haibo Chen Date: Wed, 9 Apr 2025 07:55:46 +0000 (+0800) Subject: mmc: sdhci-esdhc-imx: reset async FIFO before sending manual tuning command X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=d0aac7d811775a2e98a02c7f172e0a9e97d9e004;p=users%2Fjedix%2Flinux-maple.git mmc: sdhci-esdhc-imx: reset async FIFO before sending manual tuning command During manual tuning, residual data in the async FIFO from previous commands may impact with the tuning process. To ensure a clean state: 1. Set the RST_FIFO bit (SYS_CTRL[22]) to reset the async FIFO. 2. Poll the bit until self-cleared, confirming reset completion. This hardening ensures the tuning command starts with a clean FIFO state, improving the reliability of the manual tuning procedure. Signed-off-by: Haibo Chen Signed-off-by: Luke Wang Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20250409075550.3413032-3-ziniu.wang_1@nxp.com Signed-off-by: Ulf Hansson --- diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 067f485987a6a..53c7b858b43c8 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -31,6 +31,7 @@ #include "cqhci.h" #define ESDHC_SYS_CTRL_DTOCV_MASK GENMASK(19, 16) +#define ESDHC_SYS_CTRL_RST_FIFO BIT(22) #define ESDHC_SYS_CTRL_IPP_RST_N BIT(23) #define ESDHC_SYS_CTRL_RESET_TUNING BIT(28) #define ESDHC_CTRL_D3CD 0x08 @@ -1154,7 +1155,7 @@ static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val) { - u32 reg; + u32 reg, sys_ctrl; u8 sw_rst; int ret; @@ -1178,6 +1179,16 @@ static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val) dev_dbg(mmc_dev(host->mmc), "tuning with delay 0x%x ESDHC_TUNE_CTRL_STATUS 0x%x\n", val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); + + /* set RST_FIFO to reset the async FIFO, and wat it to self-clear */ + sys_ctrl = readl(host->ioaddr + ESDHC_SYSTEM_CONTROL); + sys_ctrl |= ESDHC_SYS_CTRL_RST_FIFO; + writel(sys_ctrl, host->ioaddr + ESDHC_SYSTEM_CONTROL); + ret = readl_poll_timeout(host->ioaddr + ESDHC_SYSTEM_CONTROL, sys_ctrl, + !(sys_ctrl & ESDHC_SYS_CTRL_RST_FIFO), 10, 100); + if (ret == -ETIMEDOUT) + dev_warn(mmc_dev(host->mmc), + "warning! RST_FIFO not clear in 100us\n"); } static void esdhc_post_tuning(struct sdhci_host *host)