aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/816-sdhc-0001-mmc-sdhci-of-esdhc-poll-ESDHC_FLUSH_ASYNC_FIFO-bit-u.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/816-sdhc-0001-mmc-sdhci-of-esdhc-poll-ESDHC_FLUSH_ASYNC_FIFO-bit-u.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/816-sdhc-0001-mmc-sdhci-of-esdhc-poll-ESDHC_FLUSH_ASYNC_FIFO-bit-u.patch72
1 files changed, 72 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/816-sdhc-0001-mmc-sdhci-of-esdhc-poll-ESDHC_FLUSH_ASYNC_FIFO-bit-u.patch b/target/linux/layerscape/patches-5.4/816-sdhc-0001-mmc-sdhci-of-esdhc-poll-ESDHC_FLUSH_ASYNC_FIFO-bit-u.patch
new file mode 100644
index 0000000000..91d1f2ce6f
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/816-sdhc-0001-mmc-sdhci-of-esdhc-poll-ESDHC_FLUSH_ASYNC_FIFO-bit-u.patch
@@ -0,0 +1,72 @@
+From 0f5cf5dcc3ca4f8e610ebe1e62e3d3546b9d09ca Mon Sep 17 00:00:00 2001
+From: Yangbo Lu <yangbo.lu@nxp.com>
+Date: Mon, 16 Sep 2019 19:17:44 +0800
+Subject: [PATCH] mmc: sdhci-of-esdhc: poll ESDHC_FLUSH_ASYNC_FIFO bit until
+ completion
+
+The ESDHC_FLUSH_ASYNC_FIFO bit which is set to flush asynchronous FIFO
+should be polled until it's auto cleared by hardware.
+
+Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+---
+ drivers/mmc/host/sdhci-of-esdhc.c | 35 ++++++++++++++++++++++++++++-------
+ 1 file changed, 28 insertions(+), 7 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-of-esdhc.c
++++ b/drivers/mmc/host/sdhci-of-esdhc.c
+@@ -591,6 +591,32 @@ static void esdhc_clock_enable(struct sd
+ }
+ }
+
++static void esdhc_flush_async_fifo(struct sdhci_host *host)
++{
++ ktime_t timeout;
++ u32 val;
++
++ val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
++ val |= ESDHC_FLUSH_ASYNC_FIFO;
++ sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
++
++ /* Wait max 20 ms */
++ timeout = ktime_add_ms(ktime_get(), 20);
++ while (1) {
++ bool timedout = ktime_after(ktime_get(), timeout);
++
++ if (!(sdhci_readl(host, ESDHC_DMA_SYSCTL) &
++ ESDHC_FLUSH_ASYNC_FIFO))
++ break;
++ if (timedout) {
++ pr_err("%s: flushing asynchronous FIFO timeout.\n",
++ mmc_hostname(host->mmc));
++ break;
++ }
++ usleep_range(10, 20);
++ }
++}
++
+ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
+ {
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+@@ -683,9 +709,7 @@ static void esdhc_of_set_clock(struct sd
+ sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
+
+ esdhc_clock_enable(host, false);
+- temp = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+- temp |= ESDHC_FLUSH_ASYNC_FIFO;
+- sdhci_writel(host, temp, ESDHC_DMA_SYSCTL);
++ esdhc_flush_async_fifo(host);
+ }
+
+ /* Wait max 20 ms */
+@@ -852,10 +876,7 @@ static void esdhc_tuning_block_enable(st
+ u32 val;
+
+ esdhc_clock_enable(host, false);
+-
+- val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+- val |= ESDHC_FLUSH_ASYNC_FIFO;
+- sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
++ esdhc_flush_async_fifo(host);
+
+ val = sdhci_readl(host, ESDHC_TBCTL);
+ if (enable)