summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorSean Anderson <sean.anderson@seco.com>2021-11-23 15:03:44 -0500
committerJaehoon Chung <jh80.chung@samsung.com>2022-01-12 09:56:40 +0900
commit41c6a22fc2963bfc76fc2aa21f572ceb0c5a4e22 (patch)
tree81466fff343310b0f94c4a01819c7bab3b2482e0 /drivers/mmc
parent01672677690149ea91c6cd88f055961b6f9fc046 (diff)
mmc: fsl_esdhc_imx: simplify esdhc_setup_data()
[ fsl_esdhc commit 7e48a028a42c111ba38a90b86e5f57dace980fa0 ] First, we need the waterlevel setting for PIO mode only. Secondy, both DMA setup code is identical for both directions, except for the data pointer. Thus, unify them. 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.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 283af35a81..6c25a77c79 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -279,59 +279,74 @@ static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv,
}
#endif
-static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
- struct mmc_data *data)
+#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
+static void esdhc_setup_watermark_level(struct fsl_esdhc_priv *priv,
+ struct mmc_data *data)
{
- int timeout;
- uint trans_bytes = data->blocksize * data->blocks;
struct fsl_esdhc *regs = priv->esdhc_regs;
- uint wml_value;
-
- wml_value = data->blocksize/4;
+ uint wml_value = data->blocksize / 4;
if (data->flags & MMC_DATA_READ) {
if (wml_value > WML_RD_WML_MAX)
wml_value = WML_RD_WML_MAX_VAL;
esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
-#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
- 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(priv->dma_addr));
-#endif
} else {
if (wml_value > WML_WR_WML_MAX)
wml_value = WML_WR_WML_MAX_VAL;
- if (priv->wp_enable) {
- if ((esdhc_read32(&regs->prsstat) &
- PRSSTAT_WPSPL) == 0) {
- printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
- return -ETIMEDOUT;
- }
+
+ esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
+ wml_value << 16);
+ }
+}
+#endif
+
+static void esdhc_setup_dma(struct fsl_esdhc_priv *priv, struct mmc_data *data)
+{
+ uint trans_bytes = data->blocksize * data->blocks;
+ struct fsl_esdhc *regs = priv->esdhc_regs;
+ void *buf;
+
+ if (data->flags & MMC_DATA_WRITE)
+ buf = (void *)data->src;
+ else
+ buf = data->dest;
+
+ priv->dma_addr = dma_map_single(buf, 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(priv->dma_addr));
+ esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
+}
+
+static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
+ struct mmc_data *data)
+{
+ int timeout;
+ bool is_write = data->flags & MMC_DATA_WRITE;
+ struct fsl_esdhc *regs = priv->esdhc_regs;
+
+ if (is_write) {
+ if (priv->wp_enable && !(esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL)) {
+ printf("Cannot write to locked SD card.\n");
+ return -EINVAL;
} else {
#if CONFIG_IS_ENABLED(DM_GPIO)
if (dm_gpio_is_valid(&priv->wp_gpio) &&
dm_gpio_get_value(&priv->wp_gpio)) {
- printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
- return -ETIMEDOUT;
+ printf("Cannot write to locked SD card.\n");
+ return -EINVAL;
}
#endif
}
-
- esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
- wml_value << 16);
-#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
- 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(priv->dma_addr));
-#endif
}
- esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
+#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
+ esdhc_setup_watermark_level(priv, data);
+#else
+ esdhc_setup_dma(priv, data);
+#endif
/* Calculate the timeout period for data transactions */
/*