Commit beaba9e4 authored by Adrian Hunter's avatar Adrian Hunter Committed by Ulf Hansson
Browse files

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: default avatarHaibo Chen <haibo.chen@nxp.com>
Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20221128133259.38305-4-adrian.hunter@intel.com


Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent e026a3f9
Loading
Loading
Loading
Loading
+14 −23
Original line number Diff line number Diff line
@@ -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;

		if (!host->preset_enabled) {
		/*
		 * 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) {
			/*
			 * 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;