]> git.sur5r.net Git - u-boot/blobdiff - drivers/mmc/sdhci.c
mtd: nand: mxs_nand: move structs into header file
[u-boot] / drivers / mmc / sdhci.c
index efc5a62e619fb5407413f97f73687e630e857111..cdeba914f95cac4037eaf9b9eb521963f9048186 100644 (file)
@@ -161,7 +161,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
        /* We shouldn't wait for data inihibit for stop commands, even
           though they might use busy signaling */
        if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ||
-           cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK)
+           ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
+             cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200) && !data))
                mask &= ~SDHCI_DATA_INHIBIT;
 
        while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
@@ -183,7 +184,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
        sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
 
        mask = SDHCI_INT_RESPONSE;
-       if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
+       if ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
+            cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200) && !data)
                mask = SDHCI_INT_DATA_AVAIL;
 
        if (!(cmd->resp_type & MMC_RSP_PRESENT))
@@ -201,7 +203,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
                flags |= SDHCI_CMD_CRC;
        if (cmd->resp_type & MMC_RSP_OPCODE)
                flags |= SDHCI_CMD_INDEX;
-       if (data || cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK)
+       if (data || cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK ||
+           cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
                flags |= SDHCI_CMD_DATA;
 
        /* Set Transfer mode regarding to data flag */
@@ -314,7 +317,7 @@ static int sdhci_execute_tuning(struct udevice *dev, uint opcode)
 
        debug("%s\n", __func__);
 
-       if (host->ops->platform_execute_tuning) {
+       if (host->ops && host->ops->platform_execute_tuning) {
                err = host->ops->platform_execute_tuning(mmc, opcode);
                if (err)
                        return err;
@@ -347,7 +350,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
        if (clock == 0)
                return 0;
 
-       if (host->ops->set_delay)
+       if (host->ops && host->ops->set_delay)
                host->ops->set_delay(host);
 
        if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
@@ -557,7 +560,7 @@ static const struct mmc_ops sdhci_ops = {
 int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
                u32 f_max, u32 f_min)
 {
-       u32 caps, caps_1;
+       u32 caps, caps_1 = 0;
 
        caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 
@@ -638,6 +641,32 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
                cfg->host_caps &= ~MMC_MODE_HS_52MHz;
        }
 
+       if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
+               caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+
+       if (!(cfg->voltages & MMC_VDD_165_195) ||
+           (host->quirks & SDHCI_QUIRK_NO_1_8_V))
+               caps_1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+                           SDHCI_SUPPORT_DDR50);
+
+       if (caps_1 & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+                     SDHCI_SUPPORT_DDR50))
+               cfg->host_caps |= MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25);
+
+       if (caps_1 & SDHCI_SUPPORT_SDR104) {
+               cfg->host_caps |= MMC_CAP(UHS_SDR104) | MMC_CAP(UHS_SDR50);
+               /*
+                * SD3.0: SDR104 is supported so (for eMMC) the caps2
+                * field can be promoted to support HS200.
+                */
+               cfg->host_caps |= MMC_CAP(MMC_HS_200);
+       } else if (caps_1 & SDHCI_SUPPORT_SDR50) {
+               cfg->host_caps |= MMC_CAP(UHS_SDR50);
+       }
+
+       if (caps_1 & SDHCI_SUPPORT_DDR50)
+               cfg->host_caps |= MMC_CAP(UHS_DDR50);
+
        if (host->host_caps)
                cfg->host_caps |= host->host_caps;