summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/tmio-common.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index f1ce019db5..785b654671 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -95,7 +95,7 @@ static void __dma_unmap_single(dma_addr_t addr, size_t size,
invalidate_dcache_range(addr, addr + size);
}
-static int tmio_sd_check_error(struct udevice *dev)
+static int tmio_sd_check_error(struct udevice *dev, struct mmc_cmd *cmd)
{
struct tmio_sd_priv *priv = dev_get_priv(dev);
u32 info2 = tmio_sd_readl(priv, TMIO_SD_INFO2);
@@ -116,7 +116,9 @@ static int tmio_sd_check_error(struct udevice *dev)
if (info2 & (TMIO_SD_INFO2_ERR_END | TMIO_SD_INFO2_ERR_CRC |
TMIO_SD_INFO2_ERR_IDX)) {
- dev_err(dev, "communication out of sync\n");
+ if ((cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK) &&
+ (cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200))
+ dev_err(dev, "communication out of sync\n");
return -EILSEQ;
}
@@ -129,8 +131,8 @@ static int tmio_sd_check_error(struct udevice *dev)
return 0;
}
-static int tmio_sd_wait_for_irq(struct udevice *dev, unsigned int reg,
- u32 flag)
+static int tmio_sd_wait_for_irq(struct udevice *dev, struct mmc_cmd *cmd,
+ unsigned int reg, u32 flag)
{
struct tmio_sd_priv *priv = dev_get_priv(dev);
long wait = 1000000;
@@ -142,7 +144,7 @@ static int tmio_sd_wait_for_irq(struct udevice *dev, unsigned int reg,
return -ETIMEDOUT;
}
- ret = tmio_sd_check_error(dev);
+ ret = tmio_sd_check_error(dev, cmd);
if (ret)
return ret;
@@ -178,15 +180,15 @@ tmio_pio_read_fifo(64, q)
tmio_pio_read_fifo(32, l)
tmio_pio_read_fifo(16, w)
-static int tmio_sd_pio_read_one_block(struct udevice *dev, char *pbuf,
- uint blocksize)
+static int tmio_sd_pio_read_one_block(struct udevice *dev, struct mmc_cmd *cmd,
+ char *pbuf, uint blocksize)
{
struct tmio_sd_priv *priv = dev_get_priv(dev);
int ret;
/* wait until the buffer is filled with data */
- ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO2,
- TMIO_SD_INFO2_BRE);
+ ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
+ TMIO_SD_INFO2_BRE);
if (ret)
return ret;
@@ -231,15 +233,15 @@ tmio_pio_write_fifo(64, q)
tmio_pio_write_fifo(32, l)
tmio_pio_write_fifo(16, w)
-static int tmio_sd_pio_write_one_block(struct udevice *dev,
+static int tmio_sd_pio_write_one_block(struct udevice *dev, struct mmc_cmd *cmd,
const char *pbuf, uint blocksize)
{
struct tmio_sd_priv *priv = dev_get_priv(dev);
int ret;
/* wait until the buffer becomes empty */
- ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO2,
- TMIO_SD_INFO2_BWE);
+ ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
+ TMIO_SD_INFO2_BWE);
if (ret)
return ret;
@@ -255,7 +257,8 @@ static int tmio_sd_pio_write_one_block(struct udevice *dev,
return 0;
}
-static int tmio_sd_pio_xfer(struct udevice *dev, struct mmc_data *data)
+static int tmio_sd_pio_xfer(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
{
const char *src = data->src;
char *dest = data->dest;
@@ -263,10 +266,10 @@ static int tmio_sd_pio_xfer(struct udevice *dev, struct mmc_data *data)
for (i = 0; i < data->blocks; i++) {
if (data->flags & MMC_DATA_READ)
- ret = tmio_sd_pio_read_one_block(dev, dest,
+ ret = tmio_sd_pio_read_one_block(dev, cmd, dest,
data->blocksize);
else
- ret = tmio_sd_pio_write_one_block(dev, src,
+ ret = tmio_sd_pio_write_one_block(dev, cmd, src,
data->blocksize);
if (ret)
return ret;
@@ -468,8 +471,8 @@ int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
cmd->cmdidx, tmp, cmd->cmdarg);
tmio_sd_writel(priv, tmp, TMIO_SD_CMD);
- ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO1,
- TMIO_SD_INFO1_RSP);
+ ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO1,
+ TMIO_SD_INFO1_RSP);
if (ret)
return ret;
@@ -497,17 +500,17 @@ int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
tmio_sd_addr_is_dmaable(data->src))
ret = tmio_sd_dma_xfer(dev, data);
else
- ret = tmio_sd_pio_xfer(dev, data);
+ ret = tmio_sd_pio_xfer(dev, cmd, data);
if (ret)
return ret;
- ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO1,
- TMIO_SD_INFO1_CMP);
+ ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO1,
+ TMIO_SD_INFO1_CMP);
if (ret)
return ret;
}
- return tmio_sd_wait_for_irq(dev, TMIO_SD_INFO2,
+ return tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
TMIO_SD_INFO2_SCLKDIVEN);
}