summaryrefslogtreecommitdiff
path: root/drivers/mmc/sdhci.c
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2012-05-20 19:20:50 (GMT)
committerWolfgang Denk <wd@denx.de>2012-05-20 19:20:50 (GMT)
commit6bc337fb13003a9a949dfb2713e308fb97faae8a (patch)
tree3ce9b22609e6c1d3e140fd2fb96af0c26efa948d /drivers/mmc/sdhci.c
parentf50bf50d7f6f99c5ad4666d63a7eef43d3940500 (diff)
parent7d2d58b4e63a8307f713e6b17fdb9b2413548574 (diff)
downloadu-boot-6bc337fb13003a9a949dfb2713e308fb97faae8a.tar.xz
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.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index fc904b5..1709643 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);