aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorSean Anderson2021-11-23 15:03:43 -0500
committerJaehoon Chung2022-01-12 09:56:40 +0900
commit01672677690149ea91c6cd88f055961b6f9fc046 (patch)
tree5ffe8fea791cadb19e07baa1407d9ca159d7b629 /drivers/mmc
parented9e9b2213b6fe09005349057afa33a044bdd4d3 (diff)
mmc: fsl_esdhc_imx: use dma-mapping API
[ 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>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/fsl_esdhc_imx.c50
1 files changed, 15 insertions, 35 deletions
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 84df131c9fb..283af35a81f 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
}