@@ -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
@@ -1149,7 +1150,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;
@@ -1173,6 +1174,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)