mmc: sdhci-esdhc-imx: disable clocks before changing frequency
authorStefan Agner <stefan@agner.ch>
Thu, 12 Jul 2018 08:07:24 +0000 (10:07 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 16 Jul 2018 09:41:05 +0000 (11:41 +0200)
In the uSDHC case (e.g. i.MX 6) clocks only get disabled if frequency
is set to 0. However, it could be that the stack asks for a frequency
change while clocks are on. In that case the function clears the
divider registers (by clearing ESDHC_CLOCK_MASK) while the clock is
enabled! This causes a short period of time where the clock is
undivided (on a i.MX 6DL a clock of 196MHz has been measured).

For older IP variants the driver disables clock by clearing some bits
in ESDHC_SYSTEM_CONTROL.

Make sure to disable card clock before changing frequency for uSDHC
IP variants too.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Acked-by: Dong Aisheng <aisheng.dong@nxp.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/sdhci-esdhc-imx.c

index dc55461..9e83840 100644 (file)
@@ -705,14 +705,14 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
        int div = 1;
        u32 temp, val;
 
+       if (esdhc_is_usdhc(imx_data)) {
+               val = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
+               writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
+                       host->ioaddr + ESDHC_VENDOR_SPEC);
+       }
+
        if (clock == 0) {
                host->mmc->actual_clock = 0;
-
-               if (esdhc_is_usdhc(imx_data)) {
-                       val = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
-                       writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
-                                       host->ioaddr + ESDHC_VENDOR_SPEC);
-               }
                return;
        }