diff mbox series

[01/10] mmc: sd: SDUC Support Recognition

Message ID 20240728081154.1782120-2-avri.altman@wdc.com
State Superseded
Headers show
Series Add SDUC Support | expand

Commit Message

Avri Altman July 28, 2024, 8:11 a.m. UTC
ACMD21 was extended to support the host-card handshake during
initialization.  The card expects that the HCS & HO2T bits to be set in
the command argument, and sets the applicable bits in the R3 returned
response.  On the contrary, if a SDUC card is inserted to a
non-supporting host, it will never respond to this ACMD21 until
eventually, the host will timed out and give up.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/sd_ops.c | 19 +++++++++++++++----
 include/linux/mmc/host.h  |  6 ++++++
 include/linux/mmc/sd.h    |  1 +
 3 files changed, 22 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 8b9b34286ef3..7f6963dac873 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -168,12 +168,16 @@  int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 		.cmd = &cmd
 	};
 	int err;
+	u32 sduc_arg = SD_OCR_CCS | SD_OCR_2T;
 
 	cmd.opcode = SD_APP_OP_COND;
+	cmd.arg = ocr;
+
 	if (mmc_host_is_spi(host))
-		cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
+		cmd.arg &= (1 << 30); /* SPI only defines one bit */
 	else
-		cmd.arg = ocr;
+		cmd.arg |= sduc_arg;
+
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
 	err = __mmc_poll_for_busy(host, SD_APP_OP_COND_PERIOD_US,
@@ -182,8 +186,15 @@  int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 	if (err)
 		return err;
 
-	if (rocr && !mmc_host_is_spi(host))
-		*rocr = cmd.resp[0];
+	if (!mmc_host_is_spi(host)) {
+		if (rocr)
+			*rocr = cmd.resp[0];
+
+		if ((cmd.resp[0] & sduc_arg) == sduc_arg)
+			host->caps2 |= MMC_CAP2_SD_SDUC;
+		else
+			host->caps2 &= ~MMC_CAP2_SD_SDUC;
+	}
 
 	return 0;
 }
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 88c6a76042ee..a9c36a3e1a10 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -427,6 +427,7 @@  struct mmc_host {
 #define MMC_CAP2_CRYPTO		0
 #endif
 #define MMC_CAP2_ALT_GPT_TEGRA	(1 << 28)	/* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_SD_SDUC	(1 << 29)	/* SD over 2TB */
 
 	int			fixed_drv_type;	/* fixed driver type for non-removable media */
 
@@ -638,6 +639,11 @@  static inline int mmc_card_uhs(struct mmc_card *card)
 		card->host->ios.timing <= MMC_TIMING_UHS_DDR50;
 }
 
+static inline int mmc_card_is_sduc(struct mmc_host *host)
+{
+	return host->caps2 & MMC_CAP2_SD_SDUC;
+}
+
 void mmc_retune_timer_stop(struct mmc_host *host);
 
 static inline void mmc_retune_needed(struct mmc_host *host)
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
index 6727576a8755..865cc0ca8543 100644
--- a/include/linux/mmc/sd.h
+++ b/include/linux/mmc/sd.h
@@ -36,6 +36,7 @@ 
 /* OCR bit definitions */
 #define SD_OCR_S18R		(1 << 24)    /* 1.8V switching request */
 #define SD_ROCR_S18A		SD_OCR_S18R  /* 1.8V switching accepted by card */
+#define SD_OCR_2T		(1 << 27)    /* HO2T/CO2T - SDUC support */
 #define SD_OCR_XPC		(1 << 28)    /* SDXC power control */
 #define SD_OCR_CCS		(1 << 30)    /* Card Capacity Status */