diff mbox series

[v2,08/11] mmc: fsl_esdhc_imx: use dma-mapping API

Message ID 20211112191523.1943825-9-sean.anderson@seco.com
State Superseded
Delegated to: Peng Fan
Headers show
Series fsl_esdhc_imx: port several patches from fsl_esdhc | expand

Commit Message

Sean Anderson Nov. 12, 2021, 7:15 p.m. UTC
[ fsl_esdhc commit b1ba1460a445bcc67972a617625d0349e4f22b31 ]

Use the dma_{map,unmap}_single() calls. These will take care of the
flushing and invalidation of caches.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---

(no changes since v1)

 drivers/mmc/fsl_esdhc_imx.c | 50 +++++++++++--------------------------
 1 file changed, 15 insertions(+), 35 deletions(-)

Comments

Jaehoon Chung Nov. 15, 2021, 8:40 a.m. UTC | #1
On 11/13/21 4:15 AM, Sean Anderson wrote:
> [ fsl_esdhc commit b1ba1460a445bcc67972a617625d0349e4f22b31 ]
> 
> Use the dma_{map,unmap}_single() calls. These will take care of the
> flushing and invalidation of caches.
> 
> Signed-off-by: Michael Walle <michael@walle.cc>
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
> 
> (no changes since v1)
> 
>  drivers/mmc/fsl_esdhc_imx.c | 50 +++++++++++--------------------------
>  1 file changed, 15 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
> index 3588056759..afc8259323 100644
> --- a/drivers/mmc/fsl_esdhc_imx.c
> +++ b/drivers/mmc/fsl_esdhc_imx.c
> @@ -38,6 +38,7 @@
>  #include <mapmem.h>
>  #include <dm/ofnode.h>
>  #include <linux/iopoll.h>
> +#include <linux/dma-mapping.h>
>  
>  #ifndef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE
>  #ifdef CONFIG_FSL_USDHC
> @@ -171,6 +172,7 @@ struct fsl_esdhc_priv {
>  	struct gpio_desc cd_gpio;
>  	struct gpio_desc wp_gpio;
>  #endif
> +	dma_addr_t dma_addr;
>  };
>  
>  /* Return the XFERTYP flags for a given command and data packet */
> @@ -281,8 +283,8 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
>  			    struct mmc_data *data)
>  {
>  	int timeout;
> +	uint trans_bytes = data->blocksize * data->blocks;
>  	struct fsl_esdhc *regs = priv->esdhc_regs;
> -	dma_addr_t addr;
>  	uint wml_value;
>  
>  	wml_value = data->blocksize/4;
> @@ -293,17 +295,13 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
>  
>  		esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
>  #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
> -		addr = virt_to_phys((void *)(data->dest));
> -		if (upper_32_bits(addr))
> +		priv->dma_addr = dma_map_single(data->dest, trans_bytes,
> +						mmc_get_dma_dir(data));
> +		if (upper_32_bits(priv->dma_addr))
>  			printf("Cannot use 64 bit addresses with SDMA\n");
> -		esdhc_write32(&regs->dsaddr, lower_32_bits(addr));
> +		esdhc_write32(&regs->dsaddr, lower_32_bits(priv->dma_addr));
>  #endif
>  	} else {
> -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
> -		flush_dcache_range((ulong)data->src,
> -				   (ulong)data->src+data->blocks
> -					 *data->blocksize);
> -#endif
>  		if (wml_value > WML_WR_WML_MAX)
>  			wml_value = WML_WR_WML_MAX_VAL;
>  		if (priv->wp_enable) {
> @@ -325,10 +323,11 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
>  		esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
>  					wml_value << 16);
>  #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
> -		addr = virt_to_phys((void *)(data->src));
> -		if (upper_32_bits(addr))
> +		priv->dma_addr = dma_map_single((void *)data->src, trans_bytes,
> +						mmc_get_dma_dir(data));
> +		if (upper_32_bits(priv->dma_addr))
>  			printf("Cannot use 64 bit addresses with SDMA\n");
> -		esdhc_write32(&regs->dsaddr, lower_32_bits(addr));
> +		esdhc_write32(&regs->dsaddr, lower_32_bits(priv->dma_addr));
>  #endif
>  	}
>  
> @@ -378,23 +377,6 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
>  	return 0;
>  }
>  
> -static void check_and_invalidate_dcache_range
> -	(struct mmc_cmd *cmd,
> -	 struct mmc_data *data) {
> -	unsigned start = 0;
> -	unsigned end = 0;
> -	unsigned size = roundup(ARCH_DMA_MINALIGN,
> -				data->blocks*data->blocksize);
> -	dma_addr_t addr;
> -
> -	addr = virt_to_phys((void *)(data->dest));
> -	if (upper_32_bits(addr))
> -		printf("Cannot use 64 bit addresses with SDMA\n");
> -	start = lower_32_bits(addr);
> -	end = start + size;
> -	invalidate_dcache_range(start, end);
> -}
> -
>  #ifdef CONFIG_MCF5441x
>  /*
>   * Swaps 32-bit words to little-endian byte order.
> @@ -450,9 +432,6 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
>  		err = esdhc_setup_data(priv, mmc, data);
>  		if(err)
>  			return err;
> -
> -		if (data->flags & MMC_DATA_READ)
> -			check_and_invalidate_dcache_range(cmd, data);
>  	}
>  
>  	/* Figure out the transfer arguments */
> @@ -560,12 +539,13 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
>  		 * cache-fill during the DMA operations such as the
>  		 * speculative pre-fetching etc.
>  		 */
> -		if (data->flags & MMC_DATA_READ) {
> -			check_and_invalidate_dcache_range(cmd, data);
> +		dma_unmap_single(priv->dma_addr,
> +				 data->blocks * data->blocksize,
> +				 mmc_get_dma_dir(data));
>  #ifdef CONFIG_MCF5441x
> +		if (data->flags & MMC_DATA_READ)
>  			sd_swap_dma_buff(data);
>  #endif
> -		}
>  #endif
>  	}
>  
>
diff mbox series

Patch

diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 3588056759..afc8259323 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -38,6 +38,7 @@ 
 #include <mapmem.h>
 #include <dm/ofnode.h>
 #include <linux/iopoll.h>
+#include <linux/dma-mapping.h>
 
 #ifndef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE
 #ifdef CONFIG_FSL_USDHC
@@ -171,6 +172,7 @@  struct fsl_esdhc_priv {
 	struct gpio_desc cd_gpio;
 	struct gpio_desc wp_gpio;
 #endif
+	dma_addr_t dma_addr;
 };
 
 /* Return the XFERTYP flags for a given command and data packet */
@@ -281,8 +283,8 @@  static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
 			    struct mmc_data *data)
 {
 	int timeout;
+	uint trans_bytes = data->blocksize * data->blocks;
 	struct fsl_esdhc *regs = priv->esdhc_regs;
-	dma_addr_t addr;
 	uint wml_value;
 
 	wml_value = data->blocksize/4;
@@ -293,17 +295,13 @@  static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
 
 		esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
 #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
-		addr = virt_to_phys((void *)(data->dest));
-		if (upper_32_bits(addr))
+		priv->dma_addr = dma_map_single(data->dest, trans_bytes,
+						mmc_get_dma_dir(data));
+		if (upper_32_bits(priv->dma_addr))
 			printf("Cannot use 64 bit addresses with SDMA\n");
-		esdhc_write32(&regs->dsaddr, lower_32_bits(addr));
+		esdhc_write32(&regs->dsaddr, lower_32_bits(priv->dma_addr));
 #endif
 	} else {
-#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
-		flush_dcache_range((ulong)data->src,
-				   (ulong)data->src+data->blocks
-					 *data->blocksize);
-#endif
 		if (wml_value > WML_WR_WML_MAX)
 			wml_value = WML_WR_WML_MAX_VAL;
 		if (priv->wp_enable) {
@@ -325,10 +323,11 @@  static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
 		esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
 					wml_value << 16);
 #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
-		addr = virt_to_phys((void *)(data->src));
-		if (upper_32_bits(addr))
+		priv->dma_addr = dma_map_single((void *)data->src, trans_bytes,
+						mmc_get_dma_dir(data));
+		if (upper_32_bits(priv->dma_addr))
 			printf("Cannot use 64 bit addresses with SDMA\n");
-		esdhc_write32(&regs->dsaddr, lower_32_bits(addr));
+		esdhc_write32(&regs->dsaddr, lower_32_bits(priv->dma_addr));
 #endif
 	}
 
@@ -378,23 +377,6 @@  static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
 	return 0;
 }
 
-static void check_and_invalidate_dcache_range
-	(struct mmc_cmd *cmd,
-	 struct mmc_data *data) {
-	unsigned start = 0;
-	unsigned end = 0;
-	unsigned size = roundup(ARCH_DMA_MINALIGN,
-				data->blocks*data->blocksize);
-	dma_addr_t addr;
-
-	addr = virt_to_phys((void *)(data->dest));
-	if (upper_32_bits(addr))
-		printf("Cannot use 64 bit addresses with SDMA\n");
-	start = lower_32_bits(addr);
-	end = start + size;
-	invalidate_dcache_range(start, end);
-}
-
 #ifdef CONFIG_MCF5441x
 /*
  * Swaps 32-bit words to little-endian byte order.
@@ -450,9 +432,6 @@  static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
 		err = esdhc_setup_data(priv, mmc, data);
 		if(err)
 			return err;
-
-		if (data->flags & MMC_DATA_READ)
-			check_and_invalidate_dcache_range(cmd, data);
 	}
 
 	/* Figure out the transfer arguments */
@@ -560,12 +539,13 @@  static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
 		 * cache-fill during the DMA operations such as the
 		 * speculative pre-fetching etc.
 		 */
-		if (data->flags & MMC_DATA_READ) {
-			check_and_invalidate_dcache_range(cmd, data);
+		dma_unmap_single(priv->dma_addr,
+				 data->blocks * data->blocksize,
+				 mmc_get_dma_dir(data));
 #ifdef CONFIG_MCF5441x
+		if (data->flags & MMC_DATA_READ)
 			sd_swap_dma_buff(data);
 #endif
-		}
 #endif
 	}