[U-Boot] [PATCH] mmc: dwmmc: Poll for iDMAC TX/RX interrupt

Poll for iDMAC TX/RX interrupt before disable DMA. This to prevent disable DMA before data is transfer completed.
Signed-off-by: Ley Foon Tan ley.foon.tan@intel.com --- drivers/mmc/dw_mmc.c | 19 +++++++++++++++++++ include/dwmmc.h | 7 +++++++ 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 7544b84..93a836e 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -12,6 +12,7 @@ #include <memalign.h> #include <mmc.h> #include <dwmmc.h> +#include <wait_bit.h>
#define PAGE_SIZE 4096
@@ -55,6 +56,9 @@ static void dwmci_prepare_data(struct dwmci_host *host,
dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
+ /* Clear IDMAC interrupt */ + dwmci_writel(host, DWMCI_IDSTS, 0xFFFFFFFF); + data_start = (ulong)cur_idmac; dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac);
@@ -340,6 +344,18 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
/* only dma mode need it */ if (!host->fifo_mode) { + if (data->flags == MMC_DATA_READ) + mask = DWMCI_IDINTEN_RI; + else + mask = DWMCI_IDINTEN_TI; + ret = wait_for_bit_le32(host->ioaddr + DWMCI_IDSTS, + mask, true, 1000, false); + if (ret) + debug("%s: DWMCI_IDINTEN mask 0x%x timeout.\n", + __func__, mask); + /* clear interrupts */ + dwmci_writel(host, DWMCI_IDSTS, DWMCI_IDINTEN_MASK); + ctrl = dwmci_readl(host, DWMCI_CTRL); ctrl &= ~(DWMCI_DMA_EN); dwmci_writel(host, DWMCI_CTRL, ctrl); @@ -494,6 +510,9 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_CLKENA, 0); dwmci_writel(host, DWMCI_CLKSRC, 0);
+ if (!host->fifo_mode) + dwmci_writel(host, DWMCI_IDINTEN, DWMCI_IDINTEN_MASK); + return 0; }
diff --git a/include/dwmmc.h b/include/dwmmc.h index 4ceda5e..f06720d 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -130,6 +130,13 @@ /* UHS register */ #define DWMCI_DDR_MODE (1 << 16)
+/* Internal IDMAC interrupt defines */ +#define DWMCI_IDINTEN_RI BIT(1) +#define DWMCI_IDINTEN_TI BIT(0) + +#define DWMCI_IDINTEN_MASK (DWMCI_IDINTEN_TI | \ + DWMCI_IDINTEN_RI) + /* quirks */ #define DWMCI_QUIRK_DISABLE_SMU (1 << 0)

On 12/20/2018 10:55 AM, Ley Foon Tan wrote:
Poll for iDMAC TX/RX interrupt before disable DMA. This to prevent disable DMA before data is transfer completed.
Signed-off-by: Ley Foon Tan ley.foon.tan@intel.com
Reviewed-by: Marek Vasut marex@denx.de
drivers/mmc/dw_mmc.c | 19 +++++++++++++++++++ include/dwmmc.h | 7 +++++++ 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 7544b84..93a836e 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -12,6 +12,7 @@ #include <memalign.h> #include <mmc.h> #include <dwmmc.h> +#include <wait_bit.h>
#define PAGE_SIZE 4096
@@ -55,6 +56,9 @@ static void dwmci_prepare_data(struct dwmci_host *host,
dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
- /* Clear IDMAC interrupt */
- dwmci_writel(host, DWMCI_IDSTS, 0xFFFFFFFF);
- data_start = (ulong)cur_idmac; dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac);
@@ -340,6 +344,18 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
/* only dma mode need it */ if (!host->fifo_mode) {
if (data->flags == MMC_DATA_READ)
mask = DWMCI_IDINTEN_RI;
else
mask = DWMCI_IDINTEN_TI;
ret = wait_for_bit_le32(host->ioaddr + DWMCI_IDSTS,
mask, true, 1000, false);
if (ret)
debug("%s: DWMCI_IDINTEN mask 0x%x timeout.\n",
__func__, mask);
/* clear interrupts */
dwmci_writel(host, DWMCI_IDSTS, DWMCI_IDINTEN_MASK);
ctrl = dwmci_readl(host, DWMCI_CTRL); ctrl &= ~(DWMCI_DMA_EN); dwmci_writel(host, DWMCI_CTRL, ctrl);
@@ -494,6 +510,9 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_CLKENA, 0); dwmci_writel(host, DWMCI_CLKSRC, 0);
- if (!host->fifo_mode)
dwmci_writel(host, DWMCI_IDINTEN, DWMCI_IDINTEN_MASK);
- return 0;
}
diff --git a/include/dwmmc.h b/include/dwmmc.h index 4ceda5e..f06720d 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -130,6 +130,13 @@ /* UHS register */ #define DWMCI_DDR_MODE (1 << 16)
+/* Internal IDMAC interrupt defines */ +#define DWMCI_IDINTEN_RI BIT(1) +#define DWMCI_IDINTEN_TI BIT(0)
+#define DWMCI_IDINTEN_MASK (DWMCI_IDINTEN_TI | \
DWMCI_IDINTEN_RI)
/* quirks */ #define DWMCI_QUIRK_DISABLE_SMU (1 << 0)

On Thu, Dec 20, 2018 at 11:57 PM Marek Vasut marex@denx.de wrote:
On 12/20/2018 10:55 AM, Ley Foon Tan wrote:
Poll for iDMAC TX/RX interrupt before disable DMA. This to prevent disable DMA before data is transfer completed.
Signed-off-by: Ley Foon Tan ley.foon.tan@intel.com
Reviewed-by: Marek Vasut marex@denx.de
Hi Marek
Will you help to merge this patch thru your git repo?
I saw this patch is delegated to your name in link below. https://patchwork.ozlabs.org/patch/1016711/
Regards Ley Foon

On 1/29/19 9:08 AM, Ley Foon Tan wrote:
On Thu, Dec 20, 2018 at 11:57 PM Marek Vasut marex@denx.de wrote:
On 12/20/2018 10:55 AM, Ley Foon Tan wrote:
Poll for iDMAC TX/RX interrupt before disable DMA. This to prevent disable DMA before data is transfer completed.
Signed-off-by: Ley Foon Tan ley.foon.tan@intel.com
Reviewed-by: Marek Vasut marex@denx.de
Hi Marek
Will you help to merge this patch thru your git repo?
I saw this patch is delegated to your name in link below. https://patchwork.ozlabs.org/patch/1016711/
Ah grmb, MMC maintainer is MIA I guess. Applied.
participants (3)
-
Ley Foon Tan
-
Ley Foon Tan
-
Marek Vasut