diff options
-rw-r--r-- | drivers/mmc/mmc.c | 28 | ||||
-rw-r--r-- | drivers/mmc/renesas-sdhi.c | 10 | ||||
-rw-r--r-- | drivers/mmc/tmio-common.c | 11 | ||||
-rw-r--r-- | drivers/mmc/tmio-common.h | 1 | ||||
-rw-r--r-- | drivers/mmc/uniphier-sd.c | 1 | ||||
-rw-r--r-- | fs/fs.c | 2 |
6 files changed, 40 insertions, 13 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 84d157ff40..b04345a1e1 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -724,7 +724,8 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) return err; } -int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) +static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value, + bool send_status) { struct mmc_cmd cmd; int timeout = 1000; @@ -740,19 +741,29 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) while (retries > 0) { ret = mmc_send_cmd(mmc, &cmd, NULL); - /* Waiting for the ready status */ - if (!ret) { - ret = mmc_send_status(mmc, timeout); - return ret; + if (ret) { + retries--; + continue; + } + + if (!send_status) { + mdelay(50); + return 0; } - retries--; + /* Waiting for the ready status */ + return mmc_send_status(mmc, timeout); } return ret; } +int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) +{ + return __mmc_switch(mmc, set, index, value, true); +} + #if !CONFIG_IS_ENABLED(MMC_TINY) static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode, bool hsdowngrade) @@ -784,8 +795,9 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode, default: return -EINVAL; } - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, - speed_bits); + + err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, + speed_bits, !hsdowngrade); if (err) return err; diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 733b6d62f5..a556acd5cb 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -462,6 +462,16 @@ static void renesas_sdhi_filter_caps(struct udevice *dev) priv->nrtaps = 4; else priv->nrtaps = 8; + + /* H3 ES1.x and M3W ES1.0 uses bit 17 for DTRAEND */ + if (((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) && + (rmobile_get_cpu_rev_integer() <= 1)) || + ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && + (rmobile_get_cpu_rev_integer() == 1) && + (rmobile_get_cpu_rev_fraction() == 0))) + priv->read_poll_flag = TMIO_SD_DMA_INFO1_END_RD; + else + priv->read_poll_flag = TMIO_SD_DMA_INFO1_END_RD2; } static int renesas_sdhi_probe(struct udevice *dev) diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c index 201492001f..2421915a07 100644 --- a/drivers/mmc/tmio-common.c +++ b/drivers/mmc/tmio-common.c @@ -347,12 +347,10 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data) /* * The DMA READ completion flag position differs on Socionext * and Renesas SoCs. It is bit 20 on Socionext SoCs and using - * bit 17 is a hardware bug and forbidden. It is bit 17 on - * Renesas SoCs and bit 20 does not work on them. + * bit 17 is a hardware bug and forbidden. It is either bit 17 + * or bit 20 on Renesas SoCs, depending on SoC. */ - poll_flag = (priv->caps & TMIO_SD_CAP_RCAR) ? - TMIO_SD_DMA_INFO1_END_RD : - TMIO_SD_DMA_INFO1_END_RD2; + poll_flag = priv->read_poll_flag; tmp |= TMIO_SD_DMA_MODE_DIR_RD; } else { buf = (void *)data->src; @@ -369,6 +367,9 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data) ret = tmio_sd_dma_wait_for_irq(dev, poll_flag, data->blocks); + if (poll_flag == TMIO_SD_DMA_INFO1_END_RD) + udelay(1); + __dma_unmap_single(dma_addr, len, dir); return ret; diff --git a/drivers/mmc/tmio-common.h b/drivers/mmc/tmio-common.h index 192026ce3e..58ce3d65b0 100644 --- a/drivers/mmc/tmio-common.h +++ b/drivers/mmc/tmio-common.h @@ -119,6 +119,7 @@ struct tmio_sd_priv { void __iomem *regbase; unsigned int version; u32 caps; + u32 read_poll_flag; #define TMIO_SD_CAP_NONREMOVABLE BIT(0) /* Nonremovable e.g. eMMC */ #define TMIO_SD_CAP_DMA_INTERNAL BIT(1) /* have internal DMA engine */ #define TMIO_SD_CAP_DIV1024 BIT(2) /* divisor 1024 is available */ diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c index 6539880ab5..8f89bda233 100644 --- a/drivers/mmc/uniphier-sd.c +++ b/drivers/mmc/uniphier-sd.c @@ -47,6 +47,7 @@ static int uniphier_sd_probe(struct udevice *dev) struct tmio_sd_priv *priv = dev_get_priv(dev); priv->clk_get_rate = uniphier_sd_clk_get_rate; + priv->read_poll_flag = TMIO_SD_DMA_INFO1_END_RD2; #ifndef CONFIG_SPL_BUILD int ret; @@ -801,6 +801,8 @@ int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) else printf("%s\n", info->name); + fs_close(); + return CMD_RET_SUCCESS; } |