diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/dw_mmc.c | 19 | ||||
-rw-r--r-- | drivers/mmc/mmc-uclass.c | 19 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 26 | ||||
-rw-r--r-- | drivers/mmc/renesas-sdhi.c | 3 | ||||
-rw-r--r-- | drivers/mmc/tmio-common.c | 10 |
5 files changed, 74 insertions, 3 deletions
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 7544b84ab6..93a836eac3 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -12,6 +12,7 @@ #include <memalign.h> #include <mmc.h> #include <dwmmc.h> +#include <wait_bit.h> #define PAGE_SIZE 4096 @@ -55,6 +56,9 @@ static void dwmci_prepare_data(struct dwmci_host *host, dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET); + /* Clear IDMAC interrupt */ + dwmci_writel(host, DWMCI_IDSTS, 0xFFFFFFFF); + data_start = (ulong)cur_idmac; dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac); @@ -340,6 +344,18 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, /* only dma mode need it */ if (!host->fifo_mode) { + if (data->flags == MMC_DATA_READ) + mask = DWMCI_IDINTEN_RI; + else + mask = DWMCI_IDINTEN_TI; + ret = wait_for_bit_le32(host->ioaddr + DWMCI_IDSTS, + mask, true, 1000, false); + if (ret) + debug("%s: DWMCI_IDINTEN mask 0x%x timeout.\n", + __func__, mask); + /* clear interrupts */ + dwmci_writel(host, DWMCI_IDSTS, DWMCI_IDINTEN_MASK); + ctrl = dwmci_readl(host, DWMCI_CTRL); ctrl &= ~(DWMCI_DMA_EN); dwmci_writel(host, DWMCI_CTRL, ctrl); @@ -494,6 +510,9 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_CLKENA, 0); dwmci_writel(host, DWMCI_CLKSRC, 0); + if (!host->fifo_mode) + dwmci_writel(host, DWMCI_IDINTEN, DWMCI_IDINTEN_MASK); + return 0; } diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 76225b7939..a9c8f335c1 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -368,6 +368,19 @@ static int mmc_blk_probe(struct udevice *dev) return 0; } +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) +static int mmc_blk_remove(struct udevice *dev) +{ + struct udevice *mmc_dev = dev_get_parent(dev); + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev); + struct mmc *mmc = upriv->mmc; + + return mmc_deinit(mmc); +} +#endif + static const struct blk_ops mmc_blk_ops = { .read = mmc_bread, #if CONFIG_IS_ENABLED(MMC_WRITE) @@ -382,6 +395,12 @@ U_BOOT_DRIVER(mmc_blk) = { .id = UCLASS_BLK, .ops = &mmc_blk_ops, .probe = mmc_blk_probe, +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) + .remove = mmc_blk_remove, + .flags = DM_FLAG_OS_PREPARE, +#endif }; #endif /* CONFIG_BLK */ diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index b04345a1e1..1c1527cc74 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -2781,6 +2781,32 @@ int mmc_init(struct mmc *mmc) return err; } +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) +int mmc_deinit(struct mmc *mmc) +{ + u32 caps_filtered; + + if (!mmc->has_init) + return 0; + + if (IS_SD(mmc)) { + caps_filtered = mmc->card_caps & + ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) | + MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) | + MMC_CAP(UHS_SDR104)); + + return sd_select_mode_and_width(mmc, caps_filtered); + } else { + caps_filtered = mmc->card_caps & + ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400)); + + return mmc_select_mode_and_width(mmc, caps_filtered); + } +} +#endif + int mmc_set_dsr(struct mmc *mmc, u16 val) { mmc->dsr = val; diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index a556acd5cb..923f846370 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -148,6 +148,9 @@ static int renesas_sdhi_hs400(struct udevice *dev) tmio_sd_writel(priv, priv->tap_set, RENESAS_SDHI_SCC_TAPSET); } + tmio_sd_writel(priv, hs400 ? 0x704 : 0x300, + RENESAS_SDHI_SCC_DT2FF); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL; tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c index 2421915a07..6e656e5a9b 100644 --- a/drivers/mmc/tmio-common.c +++ b/drivers/mmc/tmio-common.c @@ -705,10 +705,14 @@ static void tmio_sd_host_init(struct tmio_sd_priv *priv) * This register dropped backward compatibility at version 0x10. * Write an appropriate value depending on the IP version. */ - if (priv->version >= 0x10) - tmio_sd_writel(priv, 0x101, TMIO_SD_HOST_MODE); - else + if (priv->version >= 0x10) { + if (priv->caps & TMIO_SD_CAP_64BIT) + tmio_sd_writel(priv, 0x100, TMIO_SD_HOST_MODE); + else + tmio_sd_writel(priv, 0x101, TMIO_SD_HOST_MODE); + } else { tmio_sd_writel(priv, 0x0, TMIO_SD_HOST_MODE); + } if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL) { tmp = tmio_sd_readl(priv, TMIO_SD_DMA_MODE); |