492ae99d026ca62e341ddb1fa1296ca3592abfc0
[openwrt/staging/981213.git] /
1 From 0f5cf5dcc3ca4f8e610ebe1e62e3d3546b9d09ca Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Mon, 16 Sep 2019 19:17:44 +0800
4 Subject: [PATCH] mmc: sdhci-of-esdhc: poll ESDHC_FLUSH_ASYNC_FIFO bit until
5 completion
6
7 The ESDHC_FLUSH_ASYNC_FIFO bit which is set to flush asynchronous FIFO
8 should be polled until it's auto cleared by hardware.
9
10 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
11 ---
12 drivers/mmc/host/sdhci-of-esdhc.c | 35 ++++++++++++++++++++++++++++-------
13 1 file changed, 28 insertions(+), 7 deletions(-)
14
15 --- a/drivers/mmc/host/sdhci-of-esdhc.c
16 +++ b/drivers/mmc/host/sdhci-of-esdhc.c
17 @@ -591,6 +591,32 @@ static void esdhc_clock_enable(struct sd
18 }
19 }
20
21 +static void esdhc_flush_async_fifo(struct sdhci_host *host)
22 +{
23 + ktime_t timeout;
24 + u32 val;
25 +
26 + val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
27 + val |= ESDHC_FLUSH_ASYNC_FIFO;
28 + sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
29 +
30 + /* Wait max 20 ms */
31 + timeout = ktime_add_ms(ktime_get(), 20);
32 + while (1) {
33 + bool timedout = ktime_after(ktime_get(), timeout);
34 +
35 + if (!(sdhci_readl(host, ESDHC_DMA_SYSCTL) &
36 + ESDHC_FLUSH_ASYNC_FIFO))
37 + break;
38 + if (timedout) {
39 + pr_err("%s: flushing asynchronous FIFO timeout.\n",
40 + mmc_hostname(host->mmc));
41 + break;
42 + }
43 + usleep_range(10, 20);
44 + }
45 +}
46 +
47 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
48 {
49 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
50 @@ -683,9 +709,7 @@ static void esdhc_of_set_clock(struct sd
51 sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
52
53 esdhc_clock_enable(host, false);
54 - temp = sdhci_readl(host, ESDHC_DMA_SYSCTL);
55 - temp |= ESDHC_FLUSH_ASYNC_FIFO;
56 - sdhci_writel(host, temp, ESDHC_DMA_SYSCTL);
57 + esdhc_flush_async_fifo(host);
58 }
59
60 /* Wait max 20 ms */
61 @@ -887,10 +911,7 @@ static void esdhc_tuning_block_enable(st
62 u32 val;
63
64 esdhc_clock_enable(host, false);
65 -
66 - val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
67 - val |= ESDHC_FLUSH_ASYNC_FIFO;
68 - sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
69 + esdhc_flush_async_fifo(host);
70
71 val = sdhci_readl(host, ESDHC_TBCTL);
72 if (enable)