]> 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 11d1f0c24cd84f25ae08e2e406150d7a966d9edc..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.
  */
@@ -86,8 +85,8 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
        do {
                stat = sdhci_readl(host, SDHCI_INT_STATUS);
                if (stat & SDHCI_INT_ERROR) {
-                       printf("%s: Error detected in status(0x%X)!\n",
-                              __func__, stat);
+                       pr_debug("%s: Error detected in status(0x%X)!\n",
+                                __func__, stat);
                        return -EIO;
                }
                if (!transfer_done && (stat & rdy)) {
@@ -152,17 +151,17 @@ 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;
 
-       sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
        mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
 
        /* 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) {
@@ -181,7 +180,12 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
                udelay(1000);
        }
 
+       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)
@@ -197,11 +201,11 @@ 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 */
-       if (data != 0) {
+       if (data) {
                sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
                mode = SDHCI_TRNS_BLK_CNT_EN;
                trans_bytes = data->blocks * data->blocksize;
@@ -249,7 +253,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 
        sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
 #ifdef CONFIG_MMC_SDHCI_SDMA
-       if (data != 0) {
+       if (data) {
                trans_bytes = ALIGN(trans_bytes, CONFIG_SYS_CACHELINE_SIZE);
                flush_cache(start_addr, trans_bytes);
        }
@@ -439,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) {
@@ -461,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);
@@ -593,7 +601,7 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
        if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
                cfg->voltages |= host->voltages;
 
-       cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
+       cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
 
        /* Since Host Controller Version3.0 */
        if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
@@ -601,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;