]> git.sur5r.net Git - u-boot/blobdiff - drivers/mmc/sdhci.c
mmc: sdhci: Handle execute tuning command in sdhci_send_command
[u-boot] / drivers / mmc / sdhci.c
index d31793a7b793df083bfc5491fecb40e71608798f..d92f6db37414a70f498344f6049d875312997b3b 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2011, Marvell Semiconductor Inc.
  * Lei Wen <leiwen@marvell.com>
  *
- * SPDX-License-Identifier:    GPL-2.0+
- *
  * Back ported to the 8xx platform (from the 8260 platform) by
  * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
  */
@@ -152,7 +151,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
        u32 mask, flags, mode;
        unsigned int time = 0, start_addr = 0;
        int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
-       unsigned start = get_timer(0);
+       ulong start = get_timer(0);
 
        /* Timeout unit - ms */
        static unsigned int cmd_timeout = SDHCI_CMD_DEFAULT_TIMEOUT;
@@ -161,7 +160,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)
+       if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ||
+           cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK)
                mask &= ~SDHCI_DATA_INHIBIT;
 
        while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
@@ -183,6 +183,9 @@ 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)
+               mask = SDHCI_INT_DATA_AVAIL;
+
        if (!(cmd->resp_type & MMC_RSP_PRESENT))
                flags = SDHCI_CMD_RESP_NONE;
        else if (cmd->resp_type & MMC_RSP_136)
@@ -198,7 +201,7 @@ 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)
+       if (data || cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK)
                flags |= SDHCI_CMD_DATA;
 
        /* Set Transfer mode regarding to data flag */
@@ -440,6 +443,9 @@ static int sdhci_set_ios(struct mmc *mmc)
        if (mmc->clock != host->clock)
                sdhci_set_clock(mmc, mmc->clock);
 
+       if (mmc->clk_disable)
+               sdhci_set_clock(mmc, 0);
+
        /* Set bus width */
        ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
        if (mmc->bus_width == 8) {
@@ -462,7 +468,8 @@ static int sdhci_set_ios(struct mmc *mmc)
        else
                ctrl &= ~SDHCI_CTRL_HISPD;
 
-       if (host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)
+       if ((host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) ||
+           (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE))
                ctrl &= ~SDHCI_CTRL_HISPD;
 
        sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
@@ -602,6 +609,11 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
                        cfg->host_caps &= ~MMC_MODE_8BIT;
        }
 
+       if (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE) {
+               cfg->host_caps &= ~MMC_MODE_HS;
+               cfg->host_caps &= ~MMC_MODE_HS_52MHz;
+       }
+
        if (host->host_caps)
                cfg->host_caps |= host->host_caps;