Merge tag 'mmc-v5.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 Nov 2020 18:16:26 +0000 (10:16 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 Nov 2020 18:16:26 +0000 (10:16 -0800)
Pull MMC fixes from Ulf Hansson:
 "A couple of MMC fixes:

   - sdhci-of-arasan: Stabilize communication by fixing tap value configs

   - sdhci-pci: Use SDR25 timing for HS mode for BYT-based Intel HWs"

* tag 'mmc-v5.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci-of-arasan: Issue DLL reset explicitly
  mmc: sdhci-of-arasan: Use Mask writes for Tap delays
  mmc: sdhci-of-arasan: Allow configuring zero tap values
  mmc: sdhci-pci: Prefer SDR25 timing for High Speed mode for BYT-based Intel controllers

drivers/mmc/host/sdhci-of-arasan.c
drivers/mmc/host/sdhci-pci-core.c

index 829ccef..d25a4b5 100644 (file)
 #define SDHCI_ARASAN_VENDOR_REGISTER   0x78
 
 #define SDHCI_ARASAN_ITAPDLY_REGISTER  0xF0F8
+#define SDHCI_ARASAN_ITAPDLY_SEL_MASK  0xFF
+
 #define SDHCI_ARASAN_OTAPDLY_REGISTER  0xF0FC
+#define SDHCI_ARASAN_OTAPDLY_SEL_MASK  0x3F
 
 #define SDHCI_ARASAN_CQE_BASE_ADDR     0x200
 #define VENDOR_ENHANCED_STROBE         BIT(0)
@@ -600,14 +603,8 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees)
        u8 tap_delay, tap_max = 0;
        int ret;
 
-       /*
-        * This is applicable for SDHCI_SPEC_300 and above
-        * ZynqMP does not set phase for <=25MHz clock.
-        * If degrees is zero, no need to do anything.
-        */
-       if (host->version < SDHCI_SPEC_300 ||
-           host->timing == MMC_TIMING_LEGACY ||
-           host->timing == MMC_TIMING_UHS_SDR12 || !degrees)
+       /* This is applicable for SDHCI_SPEC_300 and above */
+       if (host->version < SDHCI_SPEC_300)
                return 0;
 
        switch (host->timing) {
@@ -638,6 +635,9 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees)
        if (ret)
                pr_err("Error setting Output Tap Delay\n");
 
+       /* Release DLL Reset */
+       zynqmp_pm_sd_dll_reset(node_id, PM_DLL_RESET_RELEASE);
+
        return ret;
 }
 
@@ -668,16 +668,13 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees)
        u8 tap_delay, tap_max = 0;
        int ret;
 
-       /*
-        * This is applicable for SDHCI_SPEC_300 and above
-        * ZynqMP does not set phase for <=25MHz clock.
-        * If degrees is zero, no need to do anything.
-        */
-       if (host->version < SDHCI_SPEC_300 ||
-           host->timing == MMC_TIMING_LEGACY ||
-           host->timing == MMC_TIMING_UHS_SDR12 || !degrees)
+       /* This is applicable for SDHCI_SPEC_300 and above */
+       if (host->version < SDHCI_SPEC_300)
                return 0;
 
+       /* Assert DLL Reset */
+       zynqmp_pm_sd_dll_reset(node_id, PM_DLL_RESET_ASSERT);
+
        switch (host->timing) {
        case MMC_TIMING_MMC_HS:
        case MMC_TIMING_SD_HS:
@@ -733,14 +730,8 @@ static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees)
        struct sdhci_host *host = sdhci_arasan->host;
        u8 tap_delay, tap_max = 0;
 
-       /*
-        * This is applicable for SDHCI_SPEC_300 and above
-        * Versal does not set phase for <=25MHz clock.
-        * If degrees is zero, no need to do anything.
-        */
-       if (host->version < SDHCI_SPEC_300 ||
-           host->timing == MMC_TIMING_LEGACY ||
-           host->timing == MMC_TIMING_UHS_SDR12 || !degrees)
+       /* This is applicable for SDHCI_SPEC_300 and above */
+       if (host->version < SDHCI_SPEC_300)
                return 0;
 
        switch (host->timing) {
@@ -773,6 +764,7 @@ static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees)
                regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER);
                regval |= SDHCI_OTAPDLY_ENABLE;
                sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
+               regval &= ~SDHCI_ARASAN_OTAPDLY_SEL_MASK;
                regval |= tap_delay;
                sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
        }
@@ -804,14 +796,8 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees)
        struct sdhci_host *host = sdhci_arasan->host;
        u8 tap_delay, tap_max = 0;
 
-       /*
-        * This is applicable for SDHCI_SPEC_300 and above
-        * Versal does not set phase for <=25MHz clock.
-        * If degrees is zero, no need to do anything.
-        */
-       if (host->version < SDHCI_SPEC_300 ||
-           host->timing == MMC_TIMING_LEGACY ||
-           host->timing == MMC_TIMING_UHS_SDR12 || !degrees)
+       /* This is applicable for SDHCI_SPEC_300 and above */
+       if (host->version < SDHCI_SPEC_300)
                return 0;
 
        switch (host->timing) {
@@ -846,6 +832,7 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees)
                sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
                regval |= SDHCI_ITAPDLY_ENABLE;
                sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+               regval &= ~SDHCI_ARASAN_ITAPDLY_SEL_MASK;
                regval |= tap_delay;
                sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
                regval &= ~SDHCI_ITAPDLY_CHGWIN;
index 23da7f7..9552708 100644 (file)
@@ -665,6 +665,15 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode,
        }
 }
 
+static void sdhci_intel_set_uhs_signaling(struct sdhci_host *host,
+                                         unsigned int timing)
+{
+       /* Set UHS timing to SDR25 for High Speed mode */
+       if (timing == MMC_TIMING_MMC_HS || timing == MMC_TIMING_SD_HS)
+               timing = MMC_TIMING_UHS_SDR25;
+       sdhci_set_uhs_signaling(host, timing);
+}
+
 #define INTEL_HS400_ES_REG 0x78
 #define INTEL_HS400_ES_BIT BIT(0)
 
@@ -721,7 +730,7 @@ static const struct sdhci_ops sdhci_intel_byt_ops = {
        .enable_dma             = sdhci_pci_enable_dma,
        .set_bus_width          = sdhci_set_bus_width,
        .reset                  = sdhci_reset,
-       .set_uhs_signaling      = sdhci_set_uhs_signaling,
+       .set_uhs_signaling      = sdhci_intel_set_uhs_signaling,
        .hw_reset               = sdhci_pci_hw_reset,
 };
 
@@ -731,7 +740,7 @@ static const struct sdhci_ops sdhci_intel_glk_ops = {
        .enable_dma             = sdhci_pci_enable_dma,
        .set_bus_width          = sdhci_set_bus_width,
        .reset                  = sdhci_cqhci_reset,
-       .set_uhs_signaling      = sdhci_set_uhs_signaling,
+       .set_uhs_signaling      = sdhci_intel_set_uhs_signaling,
        .hw_reset               = sdhci_pci_hw_reset,
        .irq                    = sdhci_cqhci_irq,
 };