diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2022-11-28 15:32:58 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2022-12-07 13:29:14 +0100 |
commit | beaba9e46cffca7fcf00bec7cf52fe52a9dcf918 (patch) | |
tree | 2f171a11ae5c019b0c6fd93ab4b58482a736d801 | |
parent | e026a3f9172f5c9aacff270b929a166c3ea1b6f7 (diff) | |
download | linux-beaba9e46cffca7fcf00bec7cf52fe52a9dcf918.tar.gz linux-beaba9e46cffca7fcf00bec7cf52fe52a9dcf918.tar.bz2 linux-beaba9e46cffca7fcf00bec7cf52fe52a9dcf918.zip |
mmc: sdhci: Avoid unnecessary ->set_clock()
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>
-rw-r--r-- | drivers/mmc/host/sdhci.c | 37 |
1 files changed, 14 insertions, 23 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index af7a1d75c458..aacdd3c51ced 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -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; |