]> git.itanic.dy.fi Git - linux-stable/commitdiff
mmc: sdhci: Avoid unnecessary ->set_clock()
authorAdrian Hunter <adrian.hunter@intel.com>
Mon, 28 Nov 2022 13:32:58 +0000 (15:32 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Wed, 7 Dec 2022 12:29:14 +0000 (13:29 +0100)
To avoid glitches on the clock line, the card clock is disabled when making
timing changes. Do not do that separately for HISPD and UHS settings.

Tested-by: Haibo Chen <haibo.chen@nxp.com>
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20221128133259.38305-4-adrian.hunter@intel.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/sdhci.c

index af7a1d75c4580e833b0275b5e0fa9af9a36d8613..aacdd3c51cedae49510b595780adc5f01157907e 100644 (file)
@@ -2403,8 +2403,21 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        if (host->version >= SDHCI_SPEC_300) {
                u16 clk, ctrl_2;
 
+               /*
+                * According to SDHCI Spec v3.00, if the Preset Value
+                * Enable in the Host Control 2 register is set, we
+                * need to reset SD Clock Enable before changing High
+                * Speed Enable to avoid generating clock glitches.
+                */
+               clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+               if (clk & SDHCI_CLOCK_CARD_EN) {
+                       clk &= ~SDHCI_CLOCK_CARD_EN;
+                       sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+               }
+
+               sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+
                if (!host->preset_enabled) {
-                       sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
                        /*
                         * We only need to set Driver Strength if the
                         * preset value enable is not set.
@@ -2427,30 +2440,8 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
                        sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
                        host->drv_type = ios->drv_type;
-               } else {
-                       /*
-                        * According to SDHC Spec v3.00, if the Preset Value
-                        * Enable in the Host Control 2 register is set, we
-                        * need to reset SD Clock Enable before changing High
-                        * Speed Enable to avoid generating clock gliches.
-                        */
-
-                       /* Reset SD Clock Enable */
-                       clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-                       clk &= ~SDHCI_CLOCK_CARD_EN;
-                       sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-
-                       sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-
-                       /* Re-enable SD Clock */
-                       host->ops->set_clock(host, host->clock);
                }
 
-               /* Reset SD Clock Enable */
-               clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-               clk &= ~SDHCI_CLOCK_CARD_EN;
-               sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-
                host->ops->set_uhs_signaling(host, ios->timing);
                host->timing = ios->timing;