mmc: Add vendor hacks to core mmc files 41/316541/1
authorMichal Wilczynski <m.wilczynski@samsung.com>
Thu, 22 Aug 2024 08:08:09 +0000 (10:08 +0200)
committerMichal Wilczynski <m.wilczynski@samsung.com>
Thu, 22 Aug 2024 11:53:51 +0000 (13:53 +0200)
It seems that the mmc devices don't work correctly without some changes
to mmc core code. Port the hacks from the vendor kernel [1].

[1] - https://github.com/BPI-SINOVOIP/pi-linux.git

Change-Id: Id4ef2af64f2706d0f195e825be19574c40b23cf4
Signed-off-by: Michal Wilczynski <m.wilczynski@samsung.com>
drivers/mmc/core/core.c
drivers/mmc/core/mmc.c
drivers/mmc/core/sd.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h

index a8c17b4cd737927bba95eea34ded3e28587b8084..c4e12377074b8141f9cb894e7a7653fb31c0bc75 100644 (file)
@@ -1421,6 +1421,13 @@ void _mmc_detect_change(struct mmc_host *host, unsigned long delay, bool cd_irq)
                __pm_wakeup_event(host->ws, 5000);
 
        host->detect_change = 1;
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       if (!(host->caps2 & MMC_CAP2_NO_MMC)) {
+               mmc_rescan(&host->detect.work);
+               return;
+       }
+#endif
+
        mmc_schedule_delayed_work(&host->detect, delay);
 }
 
@@ -2084,6 +2091,12 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
                        return 0;
        }
 
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       if (host->ops->encrypt_config)
+               host->ops->encrypt_config(host, 0);
+#endif
+
+
        /* Order's important: probe SDIO, then SD, then MMC */
        if (!(host->caps2 & MMC_CAP2_NO_SDIO))
                if (!mmc_attach_sdio(host))
@@ -2097,6 +2110,12 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
                if (!mmc_attach_mmc(host))
                        return 0;
 
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       if (host->ops->encrypt_config)
+               host->ops->encrypt_config(host, 1);
+#endif
+
+
 out:
        mmc_power_off(host);
        return -EIO;
@@ -2291,6 +2310,10 @@ void mmc_start_host(struct mmc_host *host)
        }
 
        mmc_gpiod_request_cd_irq(host);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       if (host->caps2 & MMC_CAP2_DISABLE_PROBE_SCAN)
+               return;
+#endif
        _mmc_detect_change(host, 0, false);
 }
 
index 7e39017e440fb2275ed95e6b9aaff197884122d3..0a892267b680867349eee29b3be0867e232fcda0 100644 (file)
@@ -2160,14 +2160,28 @@ static int mmc_suspend(struct mmc_host *host)
 static int _mmc_resume(struct mmc_host *host)
 {
        int err = 0;
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       int retry = 3;
+#endif
 
        mmc_claim_host(host);
 
        if (!mmc_card_suspended(host->card))
                goto out;
 
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+retry_resume:
+#endif
        mmc_power_up(host, host->card->ocr);
        err = mmc_init_card(host, host->card->ocr, host->card);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       if (err && retry--) {
+               pr_err("%s: try to retry resume, err:%d\n",
+                       mmc_hostname(host), err);
+               mmc_power_off(host);
+               goto retry_resume;
+       }
+#endif
        mmc_card_clr_suspended(host->card);
 
 out:
index c3e554344c99f9d7abe38e3ba20f312321246b4b..e25ed03513c13f101174a86d7d3d465a0f2b777c 100644 (file)
@@ -1409,6 +1409,11 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        u32 rocr = 0;
        bool v18_fixup_failed = false;
 
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       u8 tuning_fail = 0;
+#endif
+
+
        WARN_ON(!host->claimed);
 retry:
        err = mmc_sd_get_cid(host, ocr, cid, &rocr);
@@ -1498,9 +1503,23 @@ retry:
                goto cont;
        }
 
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       if (tuning_fail)
+               card->sw_caps.sd3_bus_mode &= ~SD_MODE_UHS_SDR104;
+#endif
+
        /* Initialization sequence for UHS-I cards */
        if (rocr & SD_ROCR_S18A && mmc_host_uhs(host)) {
                err = mmc_sd_init_uhs_card(card);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+               if (err && err == -EIO) {
+                       mmc_power_off(host);
+                       mmc_power_up(host, host->ocr_avail);
+                       tuning_fail = 1;
+                       goto retry;
+               }
+#endif
+
                if (err)
                        goto free_card;
        } else {
@@ -1803,8 +1822,24 @@ static int mmc_sd_runtime_resume(struct mmc_host *host)
 
 static int mmc_sd_hw_reset(struct mmc_host *host)
 {
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       int ret;
+       int sdr104;
+#endif
+
        mmc_power_cycle(host, host->card->ocr);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       /* if all selected delaycode have crc, reset to DDR50 */
+       sdr104 = host->caps & MMC_CAP_UHS_SDR104;
+       if (sdr104)
+               host->caps &= ~MMC_CAP_UHS_SDR104;
+       ret = mmc_sd_init_card(host, host->card->ocr, host->card);
+       if (sdr104)
+               host->caps |= MMC_CAP_UHS_SDR104;
+       return ret;
+#else
        return mmc_sd_init_card(host, host->card->ocr, host->card);
+#endif
 }
 
 static const struct mmc_bus_ops mmc_sd_ops = {
index ff41aa56564eaac0bada1efdb687731d7bf69474..cc6602c17e2dced7a2b068937a94d2df03f38574 100644 (file)
@@ -2712,6 +2712,16 @@ static int sdhci_card_busy(struct mmc_host *mmc)
        return !(present_state & SDHCI_DATA_0_LVL_MASK);
 }
 
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+static void sdhci_encrypt_config(struct mmc_host *mmc, unsigned int enc_flag)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+
+       if (host->ops->set_encrypt_feature)
+               host->ops->set_encrypt_feature(host, enc_flag);
+}
+#endif
+
 static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
 {
        struct sdhci_host *host = mmc_priv(mmc);
@@ -3062,6 +3072,9 @@ static const struct mmc_host_ops sdhci_ops = {
        .execute_tuning                 = sdhci_execute_tuning,
        .card_event                     = sdhci_card_event,
        .card_busy      = sdhci_card_busy,
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       .encrypt_config = sdhci_encrypt_config,
+#endif
 };
 
 /*****************************************************************************\
index f219bdea8f280d6ffb647ff4ac8523a13c6214c3..ec648fc1fe0457c948752e0e13ccbf28d6155ab7 100644 (file)
@@ -486,6 +486,20 @@ struct sdhci_host {
 /* Issue CMD and DATA reset together */
 #define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER      (1<<19)
 
+
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+/* Support SDH controller on FPGA */
+#define SDHCI_QUIRK2_SUPPORT_PHY_BYPASS                        (1<<25)
+/* Disable scan card at probe phase */
+#define SDHCI_QUIRK2_DISABLE_PROBE_CDSCAN              (1<<26)
+/* Need to set IO capability by SOC part register */
+#define SDHCI_QUIRK2_SET_AIB_MMC                       (1<<27)
+/* Controller not support phy module */
+#define SDHCI_QUIRK2_BROKEN_PHY_MODULE                 (1<<28)
+/* Controller support encrypt module */
+#define SDHCI_QUIRK2_SUPPORT_ENCRYPT                   (1<<29)
+#endif
+
        int irq;                /* Device IRQ */
        void __iomem *ioaddr;   /* Mapped address */
        phys_addr_t mapbase;    /* physical address base */
@@ -668,6 +682,9 @@ struct sdhci_ops {
        void    (*request_done)(struct sdhci_host *host,
                                struct mmc_request *mrq);
        void    (*dump_vendor_regs)(struct sdhci_host *host);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+       void    (*set_encrypt_feature)(struct sdhci_host *host, unsigned int enc_flag);
+#endif
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS