summaryrefslogtreecommitdiff
path: root/drivers/mmc/jz_mmc.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-01-17 19:12:55 -0500
committerTom Rini <trini@konsulko.com>2019-01-17 19:12:55 -0500
commitf83ef0dac83110d20389eb71f09285f009f3d198 (patch)
treee653de97fa1b8873704bd3d8afa557464c67e73c /drivers/mmc/jz_mmc.c
parente964df1e2ae7b2c041a9d767f03ad2b72a3f2ac7 (diff)
parent49f0b6bab919e6a9a509af841b43bbb49728dc45 (diff)
Merge tag 'mips-pull-2019-11-16' of git://git.denx.de/u-boot-mips
- MIPS: mscc: various enhancements for Luton and Ocelot platforms - MIPS: mscc: added support for Jaguar2 platform - MIPS: optimised SPL linker script - MIPS: bcm6368: fix restart flow issues - MIPS: fixed CONFIG_OF_EMBED warnings for all MIPS boards - MIPS: mt7688: small fixes and enhancements - mmc: compile-out write support if disabled
Diffstat (limited to 'drivers/mmc/jz_mmc.c')
-rw-r--r--drivers/mmc/jz_mmc.c105
1 files changed, 61 insertions, 44 deletions
diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
index 3132c3e191..cb2a7c3eb5 100644
--- a/drivers/mmc/jz_mmc.c
+++ b/drivers/mmc/jz_mmc.c
@@ -134,6 +134,60 @@ static int jz_mmc_clock_rate(void)
return 24000000;
}
+#if CONFIG_IS_ENABLED(MMC_WRITE)
+static inline void jz_mmc_write_data(struct jz_mmc_priv *priv, struct mmc_data *data)
+{
+ int sz = DIV_ROUND_UP(data->blocks * data->blocksize, 4);
+ const void *buf = data->src;
+
+ while (sz--) {
+ u32 val = get_unaligned_le32(buf);
+
+ wait_for_bit_le32(priv->regs + MSC_IREG,
+ MSC_IREG_TXFIFO_WR_REQ,
+ true, 10000, false);
+ writel(val, priv->regs + MSC_TXFIFO);
+ buf += 4;
+ }
+}
+#else
+static void jz_mmc_write_data(struct jz_mmc_priv *priv, struct mmc_data *data)
+{}
+#endif
+
+static inline int jz_mmc_read_data(struct jz_mmc_priv *priv, struct mmc_data *data)
+{
+ int sz = data->blocks * data->blocksize;
+ void *buf = data->dest;
+ u32 stat, val;
+
+ do {
+ stat = readl(priv->regs + MSC_STAT);
+
+ if (stat & MSC_STAT_TIME_OUT_READ)
+ return -ETIMEDOUT;
+ if (stat & MSC_STAT_CRC_READ_ERROR)
+ return -EINVAL;
+ if (stat & MSC_STAT_DATA_FIFO_EMPTY) {
+ udelay(10);
+ continue;
+ }
+ do {
+ val = readl(priv->regs + MSC_RXFIFO);
+ if (sz == 1)
+ *(u8 *)buf = (u8)val;
+ else if (sz == 2)
+ put_unaligned_le16(val, buf);
+ else if (sz >= 4)
+ put_unaligned_le32(val, buf);
+ buf += 4;
+ sz -= 4;
+ stat = readl(priv->regs + MSC_STAT);
+ } while (!(stat & MSC_STAT_DATA_FIFO_EMPTY));
+ } while (!(stat & MSC_STAT_DATA_TRAN_DONE));
+ return 0;
+}
+
static int jz_mmc_send_cmd(struct mmc *mmc, struct jz_mmc_priv *priv,
struct mmc_cmd *cmd, struct mmc_data *data)
{
@@ -249,51 +303,14 @@ static int jz_mmc_send_cmd(struct mmc *mmc, struct jz_mmc_priv *priv,
cmd->response[0] |= readw(priv->regs + MSC_RES) & 0xff;
}
}
-
- if (data && (data->flags & MMC_DATA_WRITE)) {
- /* write the data */
- int sz = DIV_ROUND_UP(data->blocks * data->blocksize, 4);
- const void *buf = data->src;
-
- while (sz--) {
- u32 val = get_unaligned_le32(buf);
-
- wait_for_bit_le32(priv->regs + MSC_IREG,
- MSC_IREG_TXFIFO_WR_REQ,
- true, 10000, false);
- writel(val, priv->regs + MSC_TXFIFO);
- buf += 4;
+ if (data) {
+ if (data->flags & MMC_DATA_WRITE)
+ jz_mmc_write_data(priv, data);
+ else if (data->flags & MMC_DATA_READ) {
+ ret = jz_mmc_read_data(priv, data);
+ if (ret)
+ return ret;
}
- } else if (data && (data->flags & MMC_DATA_READ)) {
- /* read the data */
- int sz = data->blocks * data->blocksize;
- void *buf = data->dest;
-
- do {
- stat = readl(priv->regs + MSC_STAT);
-
- if (stat & MSC_STAT_TIME_OUT_READ)
- return -ETIMEDOUT;
- if (stat & MSC_STAT_CRC_READ_ERROR)
- return -EINVAL;
- if (stat & MSC_STAT_DATA_FIFO_EMPTY) {
- udelay(10);
- continue;
- }
- do {
- u32 val = readl(priv->regs + MSC_RXFIFO);
-
- if (sz == 1)
- *(u8 *)buf = (u8)val;
- else if (sz == 2)
- put_unaligned_le16(val, buf);
- else if (sz >= 4)
- put_unaligned_le32(val, buf);
- buf += 4;
- sz -= 4;
- stat = readl(priv->regs + MSC_STAT);
- } while (!(stat & MSC_STAT_DATA_FIFO_EMPTY));
- } while (!(stat & MSC_STAT_DATA_TRAN_DONE));
}
return 0;