From aaa824499d257713d33de573dfd4aec5cfdca07d Mon Sep 17 00:00:00 2001 From: Yifeng Zhao Date: Wed, 20 Sep 2023 14:33:56 +0800 Subject: [PATCH] mmc: dw_mmc: Fix some TF card write data errors in RV1106 Before sending the stop command, there may still be some valid data in the fifo that has not been transmitted to the TF card. Therefore, it is necessary to increase the determination of fifo count and reset the controller before send the stop command. Fixes: 6eca689b99ed ("mmc: dw_mmc: Workaround for RV1106/1103 sdmmc") Signed-off-by: Yifeng Zhao Change-Id: I766673b25157a77018ac127e2ad9fb3f9672904b --- drivers/mmc/host/dw_mmc.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 472f0db1a779..205102e68be4 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -124,6 +124,8 @@ void rv1106_sdmmc_put_lock(void) EXPORT_SYMBOL(rv1106_sdmmc_put_lock); #endif +#define RV1106_RAMDON_DATA_SIZE 508 + #if defined(CONFIG_DEBUG_FS) static int dw_mci_req_show(struct seq_file *s, void *v) { @@ -739,7 +741,7 @@ static inline int dw_mci_prepare_desc32(struct dw_mci *host, if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) { desc->des0 = desc_last->des0; desc->des2 = desc_last->des2; - desc->des1 = 0x8; /* Random dirty data for last one desc */ + desc->des1 = RV1106_RAMDON_DATA_SIZE; /* Random dirty data for last one desc */ desc_last = desc; } @@ -1447,13 +1449,6 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) return; } - if (host->is_rv1106_sd) { - u32 reg; - - readl_poll_timeout(host->regs + SDMMC_STATUS, reg, - reg & BIT(2), USEC_PER_MSEC, 500 * USEC_PER_MSEC); - } - spin_lock_bh(&host->lock); if (host->is_rv1106_sd) @@ -2227,8 +2222,18 @@ static void dw_mci_tasklet_func(unsigned long priv) } /* stop command for open-ended transfer*/ - if (data->stop) + if (data->stop) { + if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) { + int fifo_count; + + if (readl_poll_timeout_atomic(host->regs + SDMMC_STATUS, fifo_count, + ((fifo_count >> 17) & 0x7FF) <= RV1106_RAMDON_DATA_SIZE / 4, + 0, 5000 * USEC_PER_MSEC)) + data->error = -ETIMEDOUT; + dw_mci_reset(host); + } send_stop_abort(host, data); + } } else { /* * If we don't have a command complete now we'll