Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9db8fc6 authored by Prathamesh Shete's avatar Prathamesh Shete Committed by Greg Kroah-Hartman
Browse files

mmc: sdhci-tegra: Fix switch to HS400ES mode



commit 4fc7261dbab139d3c64c3b618262504e16cfe7ee upstream.

When CMD13 is sent after switching to HS400ES mode, the bus
is operating at either MMC_HIGH_26_MAX_DTR or MMC_HIGH_52_MAX_DTR.
To meet Tegra SDHCI requirement at HS400ES mode, force SDHCI
interface clock to MMC_HS200_MAX_DTR (200 MHz) so that host
controller CAR clock and the interface clock are rate matched.

Signed-off-by: default avatarPrathamesh Shete <pshete@nvidia.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Fixes: dfc9700c ("mmc: tegra: Implement HS400 enhanced strobe")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20211214113653.4631-1-pshete@nvidia.com


Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d9031ce0
Loading
Loading
Loading
Loading
+26 −17
Original line number Diff line number Diff line
@@ -340,23 +340,6 @@ static void tegra_sdhci_set_tap(struct sdhci_host *host, unsigned int tap)
	}
}

static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc,
					      struct mmc_ios *ios)
{
	struct sdhci_host *host = mmc_priv(mmc);
	u32 val;

	val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);

	if (ios->enhanced_strobe)
		val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
	else
		val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;

	sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);

}

static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -768,6 +751,32 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
	}
}

static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc,
					      struct mmc_ios *ios)
{
	struct sdhci_host *host = mmc_priv(mmc);
	u32 val;

	val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);

	if (ios->enhanced_strobe) {
		val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
		/*
		 * When CMD13 is sent from mmc_select_hs400es() after
		 * switching to HS400ES mode, the bus is operating at
		 * either MMC_HIGH_26_MAX_DTR or MMC_HIGH_52_MAX_DTR.
		 * To meet Tegra SDHCI requirement at HS400ES mode, force SDHCI
		 * interface clock to MMC_HS200_MAX_DTR (200 MHz) so that host
		 * controller CAR clock and the interface clock are rate matched.
		 */
		tegra_sdhci_set_clock(host, MMC_HS200_MAX_DTR);
	} else {
		val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
	}

	sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);
}

static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);