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); }