summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
authorChunyan Zhang2018-08-30 10:21:42 +0200
committerUlf Hansson2018-10-08 11:40:43 +0200
commit427b6514d0953bfc1d3fd8c404dcf839bdd8196a (patch)
treeaf8b81e31cb56b96ae7572eecca130350626e849 /drivers/mmc/host/sdhci.c
parentmmc: sdhci: Add 32-bit block count support for v4 mode (diff)
downloadkernel-qcow2-linux-427b6514d0953bfc1d3fd8c404dcf839bdd8196a.tar.gz
kernel-qcow2-linux-427b6514d0953bfc1d3fd8c404dcf839bdd8196a.tar.xz
kernel-qcow2-linux-427b6514d0953bfc1d3fd8c404dcf839bdd8196a.zip
mmc: sdhci: Add Auto CMD Auto Select support
As SD Host Controller Specification v4.10 documents: Host Controller Version 4.10 defines this "Auto CMD Auto Select" mode. Selection of Auto CMD depends on setting of CMD23 Enable in the Host Control 2 register which indicates whether card supports CMD23. If CMD23 Enable =1, Auto CMD23 is used and if CMD23 Enable =0, Auto CMD12 is used. In case of Version 4.10 or later, use of Auto CMD Auto Select is recommended rather than use of Auto CMD12 Enable or Auto CMD23 Enable. This patch add this new mode support. Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index bd6426036c89..c8951c0b8a24 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1104,6 +1104,43 @@ static inline bool sdhci_auto_cmd12(struct sdhci_host *host,
!mrq->cap_cmd_during_tfr;
}
+static inline void sdhci_auto_cmd_select(struct sdhci_host *host,
+ struct mmc_command *cmd,
+ u16 *mode)
+{
+ bool use_cmd12 = sdhci_auto_cmd12(host, cmd->mrq) &&
+ (cmd->opcode != SD_IO_RW_EXTENDED);
+ bool use_cmd23 = cmd->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23);
+ u16 ctrl2;
+
+ /*
+ * In case of Version 4.10 or later, use of 'Auto CMD Auto
+ * Select' is recommended rather than use of 'Auto CMD12
+ * Enable' or 'Auto CMD23 Enable'.
+ */
+ if (host->version >= SDHCI_SPEC_410 && (use_cmd12 || use_cmd23)) {
+ *mode |= SDHCI_TRNS_AUTO_SEL;
+
+ ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ if (use_cmd23)
+ ctrl2 |= SDHCI_CMD23_ENABLE;
+ else
+ ctrl2 &= ~SDHCI_CMD23_ENABLE;
+ sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
+
+ return;
+ }
+
+ /*
+ * If we are sending CMD23, CMD12 never gets sent
+ * on successful completion (so no Auto-CMD12).
+ */
+ if (use_cmd12)
+ *mode |= SDHCI_TRNS_AUTO_CMD12;
+ else if (use_cmd23)
+ *mode |= SDHCI_TRNS_AUTO_CMD23;
+}
+
static void sdhci_set_transfer_mode(struct sdhci_host *host,
struct mmc_command *cmd)
{
@@ -1132,17 +1169,9 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
if (mmc_op_multi(cmd->opcode) || data->blocks > 1) {
mode = SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI;
- /*
- * If we are sending CMD23, CMD12 never gets sent
- * on successful completion (so no Auto-CMD12).
- */
- if (sdhci_auto_cmd12(host, cmd->mrq) &&
- (cmd->opcode != SD_IO_RW_EXTENDED))
- mode |= SDHCI_TRNS_AUTO_CMD12;
- else if (cmd->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) {
- mode |= SDHCI_TRNS_AUTO_CMD23;
+ sdhci_auto_cmd_select(host, cmd, &mode);
+ if (cmd->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23))
sdhci_writel(host, cmd->mrq->sbc->arg, SDHCI_ARGUMENT2);
- }
}
if (data->flags & MMC_DATA_READ)