diff options
author | Wolfgang Denk <wd@denx.de> | 2012-05-20 21:20:50 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2012-05-20 21:20:50 +0200 |
commit | 6bc337fb13003a9a949dfb2713e308fb97faae8a (patch) | |
tree | 3ce9b22609e6c1d3e140fd2fb96af0c26efa948d /drivers/mmc/sdhci.c | |
parent | f50bf50d7f6f99c5ad4666d63a7eef43d3940500 (diff) | |
parent | 7d2d58b4e63a8307f713e6b17fdb9b2413548574 (diff) |
Merge branch 'master' of git://git.denx.de/u-boot-mmc
* 'master' of git://git.denx.de/u-boot-mmc:
ARM: SAMSUNG: support sdhci controller
mmc: support the sdhci instead of s5p_mmc for samsung-soc
mmc: add the quirk to use the sdhci for samsung-soc
mmc: sdhci: add the quirk for broken r1b response
i.MX28: Lower the amount of blocks transfered in one DMA cycle
mmc: fsl_esdhc: Poll until card is not busy anymore
include/mmc.h: remove struct mmc_csd
mmc: omap: handle controller errors properly
mmc: omap: improve stat wait message
mmc: omap: follow TRM procedure to power on cards
mmc:fix: Set mmc width according to MMC host capabilities
Diffstat (limited to 'drivers/mmc/sdhci.c')
-rw-r--r-- | drivers/mmc/sdhci.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index fc904b5308..1709643da8 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -128,6 +128,7 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, int trans_bytes = 0, is_aligned = 1; u32 mask, flags, mode; unsigned int timeout, start_addr = 0; + unsigned int retry = 10000; /* Wait max 10 ms */ timeout = 10; @@ -210,8 +211,19 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, stat = sdhci_readl(host, SDHCI_INT_STATUS); if (stat & SDHCI_INT_ERROR) break; + if (--retry == 0) + break; } while ((stat & mask) != mask); + if (retry == 0) { + if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) + return 0; + else { + printf("Timeout for status update!\n"); + return TIMEOUT; + } + } + if ((stat & (SDHCI_INT_ERROR | mask)) == mask) { sdhci_cmd_done(host, cmd); sdhci_writel(host, mask, SDHCI_INT_STATUS); @@ -325,6 +337,9 @@ void sdhci_set_ios(struct mmc *mmc) u32 ctrl; struct sdhci_host *host = (struct sdhci_host *)mmc->priv; + if (host->set_control_reg) + host->set_control_reg(host); + if (mmc->clock != host->clock) sdhci_set_clock(mmc, mmc->clock); @@ -348,6 +363,9 @@ void sdhci_set_ios(struct mmc *mmc) else ctrl &= ~SDHCI_CTRL_HISPD; + if (host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) + ctrl &= ~SDHCI_CTRL_HISPD; + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } @@ -431,9 +449,15 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) mmc->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; if (caps & SDHCI_CAN_VDD_180) mmc->voltages |= MMC_VDD_165_195; + + if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE) + mmc->voltages |= host->voltages; + mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; if (caps & SDHCI_CAN_DO_8BIT) mmc->host_caps |= MMC_MODE_8BIT; + if (host->host_caps) + mmc->host_caps |= host->host_caps; sdhci_reset(host, SDHCI_RESET_ALL); mmc_register(mmc); |