All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle
@ 2025-10-21 20:45 Tanmay Kathpalia
  2025-10-22  3:16 ` Peng Fan
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Tanmay Kathpalia @ 2025-10-21 20:45 UTC (permalink / raw)
  To: u-boot; +Cc: trini, peng.fan, jh80.chung, marex, tien.fong.chee,
	tanmay.kathpalia

Some boards have SD card connectors where the power rail cannot be switched
off by the driver. However there are various circumstances when a card
might be re-initialized, such as after system resume, warm re-boot, or
error handling. However, a UHS card will continue to use 1.8V signaling
unless it is power cycled.

If the card has not been power cycled, it may still be using 1.8V
signaling. According to the SD spec., the Bus Speed Mode (function group 1)
bits 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus
they can be used to determine if the card has already switched to 1.8V
signaling. Detect that situation and try to initialize a UHS-I (1.8V)
transfer mode.

Signed-off-by: Tanmay Kathpalia <tanmay.kathpalia@altera.com>
---
 drivers/mmc/mmc.c | 55 ++++++++++++++++++++++++++++++++++++++---------
 include/mmc.h     |  3 +++
 2 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index ec61ed92e86..e1f62a5d0ad 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -643,6 +643,19 @@ static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
 
 	return 0;
 }
+
+static bool mmc_sd_card_using_v18(struct mmc *mmc)
+{
+	/*
+	 * According to the SD spec., the Bus Speed Mode (function group 1) bits
+	 * 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus
+	 * they can be used to determine if the card has already switched to
+	 * 1.8V signaling.
+	 */
+	bool volt = mmc->sd3_bus_mode &
+	       (SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50);
+	return volt;
+}
 #endif
 
 static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
@@ -1369,9 +1382,6 @@ static int sd_get_capabilities(struct mmc *mmc)
 	ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
 	struct mmc_data data;
 	int timeout;
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
-	u32 sd3_bus_mode;
-#endif
 
 	mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
 
@@ -1451,16 +1461,16 @@ static int sd_get_capabilities(struct mmc *mmc)
 	if (mmc->version < SD_VERSION_3)
 		return 0;
 
-	sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
-	if (sd3_bus_mode & SD_MODE_UHS_SDR104)
+	mmc->sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
+	if (mmc->sd3_bus_mode & SD_MODE_UHS_SDR104)
 		mmc->card_caps |= MMC_CAP(UHS_SDR104);
-	if (sd3_bus_mode & SD_MODE_UHS_SDR50)
+	if (mmc->sd3_bus_mode & SD_MODE_UHS_SDR50)
 		mmc->card_caps |= MMC_CAP(UHS_SDR50);
-	if (sd3_bus_mode & SD_MODE_UHS_SDR25)
+	if (mmc->sd3_bus_mode & SD_MODE_UHS_SDR25)
 		mmc->card_caps |= MMC_CAP(UHS_SDR25);
-	if (sd3_bus_mode & SD_MODE_UHS_SDR12)
+	if (mmc->sd3_bus_mode & SD_MODE_UHS_SDR12)
 		mmc->card_caps |= MMC_CAP(UHS_SDR12);
-	if (sd3_bus_mode & SD_MODE_UHS_DDR50)
+	if (mmc->sd3_bus_mode & SD_MODE_UHS_DDR50)
 		mmc->card_caps |= MMC_CAP(UHS_DDR50);
 #endif
 
@@ -1830,7 +1840,11 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
 	uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
 	const struct mode_width_tuning *mwt;
 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
-	bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
+	/*
+	 * Enable UHS mode if the card advertises 1.8V support (S18R in OCR)
+	 * or is already operating at 1.8V signaling.
+	 */
+	bool uhs_en = (mmc->ocr & OCR_S18R) || mmc_sd_card_using_v18(mmc);
 #else
 	bool uhs_en = false;
 #endif
@@ -2701,6 +2715,27 @@ static int mmc_startup(struct mmc *mmc)
 		err = sd_get_capabilities(mmc);
 		if (err)
 			return err;
+
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
+		/*
+		 * If the card has already switched to 1.8V signaling, then
+		 * set the signal voltage to 1.8V.
+		 */
+		if (mmc_sd_card_using_v18(mmc)) {
+			/*
+			 * During a signal voltage level switch, the clock must be gated
+			 * for 5 ms according to the SD spec.
+			 */
+			mmc_set_clock(mmc, mmc->clock, MMC_CLK_DISABLE);
+			err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
+			if (err)
+				return err;
+			/* Keep clock gated for at least 10 ms, though spec only says 5 ms */
+			mdelay(10);
+			mmc_set_clock(mmc, mmc->clock, MMC_CLK_ENABLE);
+		}
+#endif
+
 		err = sd_select_mode_and_width(mmc, mmc->card_caps);
 	} else {
 		err = mmc_get_capabilities(mmc);
diff --git a/include/mmc.h b/include/mmc.h
index c6b2ab4a29f..51d3f2f8dd5 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -759,6 +759,9 @@ struct mmc {
 #endif
 	u8 *ext_csd;
 	u32 cardtype;		/* cardtype read from the MMC */
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
+	u32 sd3_bus_mode;	/* Supported UHS-I bus speed modes */
+#endif
 	enum mmc_voltage current_voltage;
 	enum bus_mode selected_mode; /* mode currently used */
 	enum bus_mode best_mode; /* best mode is the supported mode with the
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle
  2025-10-21 20:45 [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle Tanmay Kathpalia
@ 2025-10-22  3:16 ` Peng Fan
  2025-10-22 14:06   ` Tanmay Kathpalia
  2025-10-23  8:46 ` Peng Fan (OSS)
  2026-05-13 23:39 ` Judith Mendez
  2 siblings, 1 reply; 7+ messages in thread
From: Peng Fan @ 2025-10-22  3:16 UTC (permalink / raw)
  To: Tanmay Kathpalia
  Cc: u-boot, trini, peng.fan, jh80.chung, marex, tien.fong.chee

Hi Tanmay,

On Tue, Oct 21, 2025 at 01:45:26PM -0700, Tanmay Kathpalia wrote:
>Some boards have SD card connectors where the power rail cannot be switched
>off by the driver. However there are various circumstances when a card
>might be re-initialized, such as after system resume, warm re-boot, or
>error handling. However, a UHS card will continue to use 1.8V signaling
>unless it is power cycled.
>
>If the card has not been power cycled, it may still be using 1.8V
>signaling. According to the SD spec., the Bus Speed Mode (function group 1)
>bits 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus
>they can be used to determine if the card has already switched to 1.8V
>signaling. Detect that situation and try to initialize a UHS-I (1.8V)
>transfer mode.

Actually a power cycle or reset is required to make sure SD card to work
correctly. Some SD cards may work in your case, some SD cards might not work,
without a power cycle or reset.

Thanks,
Peng

>
>Signed-off-by: Tanmay Kathpalia <tanmay.kathpalia@altera.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle
  2025-10-22  3:16 ` Peng Fan
@ 2025-10-22 14:06   ` Tanmay Kathpalia
  0 siblings, 0 replies; 7+ messages in thread
From: Tanmay Kathpalia @ 2025-10-22 14:06 UTC (permalink / raw)
  To: Peng Fan; +Cc: u-boot, trini, peng.fan, jh80.chung, marex, tien.fong.chee

Hi Peng,

Thank you for your feedback.

On 10/22/2025 8:46 AM, Peng Fan wrote:
> Hi Tanmay,
> 
> On Tue, Oct 21, 2025 at 01:45:26PM -0700, Tanmay Kathpalia wrote:
>> Some boards have SD card connectors where the power rail cannot be switched
>> off by the driver. However there are various circumstances when a card
>> might be re-initialized, such as after system resume, warm re-boot, or
>> error handling. However, a UHS card will continue to use 1.8V signaling
>> unless it is power cycled.
>>
>> If the card has not been power cycled, it may still be using 1.8V
>> signaling. According to the SD spec., the Bus Speed Mode (function group 1)
>> bits 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus
>> they can be used to determine if the card has already switched to 1.8V
>> signaling. Detect that situation and try to initialize a UHS-I (1.8V)
>> transfer mode.
> 
> Actually a power cycle or reset is required to make sure SD card to work
> correctly. Some SD cards may work in your case, some SD cards might not work,
> without a power cycle or reset.
> 
> Thanks,
> Peng
> 


According to the SD specification for the Switch Function command (CMD6):

"If the card is initialized in 3.3V signal level, Default Speed and High 
Speed are assigned to function 0 and 1. Then support bits of function 2 
to 4 (SDR50, SDR104 and DDR50) are set to 0. If the card is initialized 
in 1.8V signal level, SDR and DDR modes are assigned from function 0 to 
function 4."

This allows the host to detect if the card is already operating at 1.8V 
signaling and proceed accordingly.

I have tested this approach with multiple SD cards from different 
vendors and capacities, including:

- Kingston Canvas Select Plus 16GB SDR104
- Samsung EVO Select 128GB SDR104
- Samsung Evo Plus 128GB SDR104

All of these cards worked reliably in my tests.

For further reference, similar discussions and solutions have been 
proposed in the Linux community:

https://lore.kernel.org/linux-mmc/a367a679-28f7-898a-c043-27df8c9c9aba@intel.com/
https://lore.kernel.org/linux-mmc/1506328144-13666-1-git-send-email-adrian.hunter@intel.com/

Thanks,
Tanmay

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle
  2025-10-21 20:45 [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle Tanmay Kathpalia
  2025-10-22  3:16 ` Peng Fan
@ 2025-10-23  8:46 ` Peng Fan (OSS)
  2026-05-13 23:39 ` Judith Mendez
  2 siblings, 0 replies; 7+ messages in thread
From: Peng Fan (OSS) @ 2025-10-23  8:46 UTC (permalink / raw)
  To: u-boot, Tanmay Kathpalia
  Cc: Peng Fan, trini, jh80.chung, marex, tien.fong.chee

From: Peng Fan <peng.fan@nxp.com>


On Tue, 21 Oct 2025 13:45:26 -0700, Tanmay Kathpalia wrote:
> Some boards have SD card connectors where the power rail cannot be switched
> off by the driver. However there are various circumstances when a card
> might be re-initialized, such as after system resume, warm re-boot, or
> error handling. However, a UHS card will continue to use 1.8V signaling
> unless it is power cycled.
> 
> If the card has not been power cycled, it may still be using 1.8V
> signaling. According to the SD spec., the Bus Speed Mode (function group 1)
> bits 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus
> they can be used to determine if the card has already switched to 1.8V
> signaling. Detect that situation and try to initialize a UHS-I (1.8V)
> transfer mode.
> 
> [...]

Applied to mmc/next, thanks!

[1/1] mmc: sd: Handle UHS-I voltage signaling without power cycle
      commit: a9797a8a057b408e9c26f69d5e1d651285bf81c0

Best regards,
-- 
Peng Fan <peng.fan@nxp.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle
  2025-10-21 20:45 [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle Tanmay Kathpalia
  2025-10-22  3:16 ` Peng Fan
  2025-10-23  8:46 ` Peng Fan (OSS)
@ 2026-05-13 23:39 ` Judith Mendez
  2026-05-14 18:50   ` Kathpalia, Tanmay
  2 siblings, 1 reply; 7+ messages in thread
From: Judith Mendez @ 2026-05-13 23:39 UTC (permalink / raw)
  To: Tanmay Kathpalia, u-boot
  Cc: trini, peng.fan, jh80.chung, marex, tien.fong.chee

Hi Tanmay, all,

On 10/21/25 3:45 PM, Tanmay Kathpalia wrote:
> Some boards have SD card connectors where the power rail cannot be switched
> off by the driver. However there are various circumstances when a card
> might be re-initialized, such as after system resume, warm re-boot, or
> error handling. However, a UHS card will continue to use 1.8V signaling
> unless it is power cycled.
> 
> If the card has not been power cycled, it may still be using 1.8V
> signaling. According to the SD spec., the Bus Speed Mode (function group 1)
> bits 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus
> they can be used to determine if the card has already switched to 1.8V
> signaling. Detect that situation and try to initialize a UHS-I (1.8V)
> transfer mode.

This implementation broke am65 IDK board SD card boot, I have still
to check why this breaks only one board, potentially there might
be a quirk only for this board... But for now sending the question
in case anyone might have an idea what is going on & save me some
time.

~ Judith

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle
  2026-05-13 23:39 ` Judith Mendez
@ 2026-05-14 18:50   ` Kathpalia, Tanmay
  2026-05-14 22:21     ` Judith Mendez
  0 siblings, 1 reply; 7+ messages in thread
From: Kathpalia, Tanmay @ 2026-05-14 18:50 UTC (permalink / raw)
  To: Judith Mendez, u-boot; +Cc: trini, peng.fan, jh80.chung, marex, tien.fong.chee


On 5/14/2026 5:09 AM, Judith Mendez wrote:
> Hi Tanmay, all,
>
> On 10/21/25 3:45 PM, Tanmay Kathpalia wrote:
>> Some boards have SD card connectors where the power rail cannot be 
>> switched
>> off by the driver. However there are various circumstances when a card
>> might be re-initialized, such as after system resume, warm re-boot, or
>> error handling. However, a UHS card will continue to use 1.8V signaling
>> unless it is power cycled.
>>
>> If the card has not been power cycled, it may still be using 1.8V
>> signaling. According to the SD spec., the Bus Speed Mode (function 
>> group 1)
>> bits 2 to 4 are zero if the card is initialized at 3.3V signal level. 
>> Thus
>> they can be used to determine if the card has already switched to 1.8V
>> signaling. Detect that situation and try to initialize a UHS-I (1.8V)
>> transfer mode.
>
> This implementation broke am65 IDK board SD card boot, I have still
> to check why this breaks only one board, potentially there might
> be a quirk only for this board... But for now sending the question
> in case anyone might have an idea what is going on & save me some
> time.
>
>

Thanks for reporting this. I had a deeper look at the code and found
an issue that is likely the root cause of the failure on am65 IDK.

During a normal cold boot with a UHS-capable host and UHS card, the
voltage switch to 1.8V is already performed inside sd_send_op_cond()
as part of the ACMD41 handshake, and this is recorded in mmc->ocr via
the S18R bit. By the time mmc_startup() calls sd_get_capabilities(),
the card is already operating at 1.8V and reports UHS bus speed modes,
causing mmc_sd_card_using_v18() to return true. The warm-reboot
recovery path then fires unconditionally and switches the host voltage
a second time, which on boards like am65 IDK can leave the controller
in a bad state.

The fix is to guard the recovery path so it only activates when the
voltage switch was not already performed during the current session:

-        if (mmc_sd_card_using_v18(mmc)) {
+        if (!(mmc->ocr & OCR_S18R) && mmc_sd_card_using_v18(mmc)) {

Could you please try this change and let me know if it resolves the
failure on am65 IDK?

I will send the patch for review on the mailing list.

Regards,
Tanmay

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle
  2026-05-14 18:50   ` Kathpalia, Tanmay
@ 2026-05-14 22:21     ` Judith Mendez
  0 siblings, 0 replies; 7+ messages in thread
From: Judith Mendez @ 2026-05-14 22:21 UTC (permalink / raw)
  To: Kathpalia, Tanmay, u-boot
  Cc: trini, peng.fan, jh80.chung, marex, tien.fong.chee

Hi,

On 5/14/26 1:50 PM, Kathpalia, Tanmay wrote:
> 
> On 5/14/2026 5:09 AM, Judith Mendez wrote:
>> Hi Tanmay, all,
>>
>> On 10/21/25 3:45 PM, Tanmay Kathpalia wrote:
>>> Some boards have SD card connectors where the power rail cannot be 
>>> switched
>>> off by the driver. However there are various circumstances when a card
>>> might be re-initialized, such as after system resume, warm re-boot, or
>>> error handling. However, a UHS card will continue to use 1.8V signaling
>>> unless it is power cycled.
>>>
>>> If the card has not been power cycled, it may still be using 1.8V
>>> signaling. According to the SD spec., the Bus Speed Mode (function 
>>> group 1)
>>> bits 2 to 4 are zero if the card is initialized at 3.3V signal level. 
>>> Thus
>>> they can be used to determine if the card has already switched to 1.8V
>>> signaling. Detect that situation and try to initialize a UHS-I (1.8V)
>>> transfer mode.
>>
>> This implementation broke am65 IDK board SD card boot, I have still
>> to check why this breaks only one board, potentially there might
>> be a quirk only for this board... But for now sending the question
>> in case anyone might have an idea what is going on & save me some
>> time.
>>
>>
> 
> Thanks for reporting this. I had a deeper look at the code and found
> an issue that is likely the root cause of the failure on am65 IDK.
> 
> During a normal cold boot with a UHS-capable host and UHS card, the
> voltage switch to 1.8V is already performed inside sd_send_op_cond()
> as part of the ACMD41 handshake, and this is recorded in mmc->ocr via
> the S18R bit. By the time mmc_startup() calls sd_get_capabilities(),
> the card is already operating at 1.8V and reports UHS bus speed modes,
> causing mmc_sd_card_using_v18() to return true. The warm-reboot
> recovery path then fires unconditionally and switches the host voltage
> a second time, which on boards like am65 IDK can leave the controller
> in a bad state.
> 
> The fix is to guard the recovery path so it only activates when the
> voltage switch was not already performed during the current session:
> 
> -        if (mmc_sd_card_using_v18(mmc)) {
> +        if (!(mmc->ocr & OCR_S18R) && mmc_sd_card_using_v18(mmc)) {
> 
> Could you please try this change and let me know if it resolves the
> failure on am65 IDK?
> 
> I will send the patch for review on the mailing list.
> 

Seems like that did not work for me [0] :(

[0] https://gist.github.com/jmenti/bb2dfc93630219a4d137edf2e20ce66c

I might not have a chance to debug/respond here soon since ill be out
until may 25, so until then, happy hacking :D

~ Judith



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-05-14 22:21 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-21 20:45 [PATCH] mmc: sd: Handle UHS-I voltage signaling without power cycle Tanmay Kathpalia
2025-10-22  3:16 ` Peng Fan
2025-10-22 14:06   ` Tanmay Kathpalia
2025-10-23  8:46 ` Peng Fan (OSS)
2026-05-13 23:39 ` Judith Mendez
2026-05-14 18:50   ` Kathpalia, Tanmay
2026-05-14 22:21     ` Judith Mendez

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.