]> www.infradead.org Git - users/willy/xarray.git/commitdiff
mmc: Add quirk to disable DDR50 tuning
authorErick Shepherd <erick.shepherd@ni.com>
Mon, 31 Mar 2025 22:13:37 +0000 (17:13 -0500)
committerUlf Hansson <ulf.hansson@linaro.org>
Wed, 14 May 2025 14:59:16 +0000 (16:59 +0200)
Adds the MMC_QUIRK_NO_UHS_DDR50_TUNING quirk and updates
mmc_execute_tuning() to return 0 if that quirk is set. This fixes an
issue on certain Swissbit SD cards that do not support DDR50 tuning
where tuning requests caused I/O errors to be thrown.

Signed-off-by: Erick Shepherd <erick.shepherd@ni.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20250331221337.1414534-1-erick.shepherd@ni.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/core/card.h
drivers/mmc/core/quirks.h
drivers/mmc/core/sd.c
include/linux/mmc/card.h

index 3205feb1e8ff6ac7296e81075c105798a5bbac68..9cbdd240c3a7d42ecbb45cbc52c5562e4664ee35 100644 (file)
@@ -89,6 +89,7 @@ struct mmc_fixup {
 #define CID_MANFID_MICRON       0x13
 #define CID_MANFID_SAMSUNG      0x15
 #define CID_MANFID_APACER       0x27
+#define CID_MANFID_SWISSBIT     0x5D
 #define CID_MANFID_KINGSTON     0x70
 #define CID_MANFID_HYNIX       0x90
 #define CID_MANFID_KINGSTON_SD 0x9F
@@ -294,4 +295,9 @@ static inline int mmc_card_broken_sd_poweroff_notify(const struct mmc_card *c)
        return c->quirks & MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY;
 }
 
+static inline int mmc_card_no_uhs_ddr50_tuning(const struct mmc_card *c)
+{
+       return c->quirks & MMC_QUIRK_NO_UHS_DDR50_TUNING;
+}
+
 #endif
index 89b512905be1400334322484805c3cca01dc69c6..7f893bafaa607d1e853e060b96bed88e57194de2 100644 (file)
@@ -34,6 +34,16 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
                   MMC_QUIRK_BROKEN_SD_CACHE | MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY,
                   EXT_CSD_REV_ANY),
 
+       /*
+        * Swissbit series S46-u cards throw I/O errors during tuning requests
+        * after the initial tuning request expectedly times out. This has
+        * only been observed on cards manufactured on 01/2019 that are using
+        * Bay Trail host controllers.
+        */
+       _FIXUP_EXT("0016G", CID_MANFID_SWISSBIT, 0x5342, 2019, 1,
+                  0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
+                  MMC_QUIRK_NO_UHS_DDR50_TUNING, EXT_CSD_REV_ANY),
+
        END_FIXUP
 };
 
index 8eba697d3d8671c62ab3cff78c11552027fea365..6847b3fe8887aaa2a6f4f4bf85041708301e7ee5 100644 (file)
@@ -617,6 +617,29 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status)
        return 0;
 }
 
+/*
+ * Determine if the card should tune or not.
+ */
+static bool mmc_sd_use_tuning(struct mmc_card *card)
+{
+       /*
+        * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
+        * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
+        */
+       if (mmc_host_is_spi(card->host))
+               return false;
+
+       switch (card->host->ios.timing) {
+       case MMC_TIMING_UHS_SDR50:
+       case MMC_TIMING_UHS_SDR104:
+               return true;
+       case MMC_TIMING_UHS_DDR50:
+               return !mmc_card_no_uhs_ddr50_tuning(card);
+       }
+
+       return false;
+}
+
 /*
  * UHS-I specific initialization procedure
  */
@@ -660,14 +683,7 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
        if (err)
                goto out;
 
-       /*
-        * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
-        * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
-        */
-       if (!mmc_host_is_spi(card->host) &&
-               (card->host->ios.timing == MMC_TIMING_UHS_SDR50 ||
-                card->host->ios.timing == MMC_TIMING_UHS_DDR50 ||
-                card->host->ios.timing == MMC_TIMING_UHS_SDR104)) {
+       if (mmc_sd_use_tuning(card)) {
                err = mmc_execute_tuning(card);
 
                /*
index 526fce581657542303ff9d11f64659ffd2650a49..ddcdf23d731c4732402920b82fe48cc019158ac3 100644 (file)
@@ -329,6 +329,7 @@ struct mmc_card {
 #define MMC_QUIRK_BROKEN_SD_CACHE      (1<<15) /* Disable broken SD cache support */
 #define MMC_QUIRK_BROKEN_CACHE_FLUSH   (1<<16) /* Don't flush cache until the write has occurred */
 #define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY    (1<<17) /* Disable broken SD poweroff notify support */
+#define MMC_QUIRK_NO_UHS_DDR50_TUNING  (1<<18) /* Disable DDR50 tuning */
 
        bool                    written_flag;   /* Indicates eMMC has been written since power on */
        bool                    reenable_cmdq;  /* Re-enable Command Queue */