|
@@ -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)
|