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 7544b84ab61..93a836eac36 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 76225b7939b..a9c8f335c14 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 b04345a1e15..1c1527cc747 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 a556acd5cb5..923f846370f 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 2421915a079..6e656e5a9b8 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); | 
