sdhci: Add SD Express hook
authorPhil Elwell <phil@raspberrypi.com>
Tue, 6 Jul 2021 08:45:36 +0000 (09:45 +0100)
committerDom Cobley <popcornmix@gmail.com>
Mon, 19 Feb 2024 11:33:42 +0000 (11:33 +0000)
sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR speeds at 1.8v.

drivers/mmc/host/sdhci-of-dwcmshc.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h

index 3a3bae6..6129591 100644 (file)
@@ -376,7 +376,10 @@ static const struct sdhci_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {
        .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
                  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
        .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
-                  SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
+                  SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
+                   SDHCI_QUIRK2_NO_SDR50 |
+                   SDHCI_QUIRK2_NO_SDR104 |
+                   SDHCI_QUIRK2_NO_SDR25,
 };
 
 static int dwcmshc_rk35xx_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv)
index 4e28320..db3c97b 100644 (file)
@@ -3047,6 +3047,15 @@ static void sdhci_card_event(struct mmc_host *mmc)
        spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static int sdhci_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+
+       if (!host->ops->init_sd_express)
+               return -EOPNOTSUPP;
+       return host->ops->init_sd_express(host, ios);
+}
+
 static const struct mmc_host_ops sdhci_ops = {
        .request        = sdhci_request,
        .post_req       = sdhci_post_req,
@@ -3062,6 +3071,7 @@ static const struct mmc_host_ops sdhci_ops = {
        .execute_tuning                 = sdhci_execute_tuning,
        .card_event                     = sdhci_card_event,
        .card_busy      = sdhci_card_busy,
+       .init_sd_express = sdhci_init_sd_express,
 };
 
 /*****************************************************************************\
@@ -4574,6 +4584,15 @@ int sdhci_setup_host(struct sdhci_host *host)
            !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50))
                mmc->caps |= MMC_CAP_UHS_DDR50;
 
+       if (host->quirks2 & SDHCI_QUIRK2_NO_SDR25)
+               mmc->caps &= ~MMC_CAP_UHS_SDR25;
+
+       if (host->quirks2 & SDHCI_QUIRK2_NO_SDR50)
+               mmc->caps &= ~MMC_CAP_UHS_SDR50;
+
+       if (host->quirks2 & SDHCI_QUIRK2_NO_SDR104)
+               mmc->caps &= ~MMC_CAP_UHS_SDR104;
+
        /* Does the host need tuning for SDR50? */
        if (host->caps1 & SDHCI_USE_SDR50_TUNING)
                host->flags |= SDHCI_SDR50_NEEDS_TUNING;
index f219bde..b5f1bc7 100644 (file)
@@ -486,6 +486,11 @@ struct sdhci_host {
 /* Issue CMD and DATA reset together */
 #define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER      (1<<19)
 
+/* Quirks to ignore a speed if a that speed is unreliable */
+#define SDHCI_QUIRK2_NO_SDR25  (1<<19)
+#define SDHCI_QUIRK2_NO_SDR50  (1<<20)
+#define SDHCI_QUIRK2_NO_SDR104 (1<<21)
+
        int irq;                /* Device IRQ */
        void __iomem *ioaddr;   /* Mapped address */
        phys_addr_t mapbase;    /* physical address base */
@@ -668,6 +673,7 @@ struct sdhci_ops {
        void    (*request_done)(struct sdhci_host *host,
                                struct mmc_request *mrq);
        void    (*dump_vendor_regs)(struct sdhci_host *host);
+       int     (*init_sd_express)(struct sdhci_host *host, struct mmc_ios *ios);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS