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

Commit dd3f6983 authored by yangbo lu's avatar yangbo lu Committed by Ulf Hansson
Browse files

mmc: sdhci-of-esdhc: disable SD clock for clock value 0



SD clock should be disabled for clock value 0. It's not
right to just return. This may cause failure of signal
voltage switching.

Signed-off-by: default avatarYangbo Lu <yangbo.lu@nxp.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent cdaba732
Loading
Loading
Loading
Loading
+30 −28
Original line number Diff line number Diff line
@@ -458,6 +458,33 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
	return clock / 256 / 16;
}

static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
{
	u32 val;
	ktime_t timeout;

	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);

	if (enable)
		val |= ESDHC_CLOCK_SDCLKEN;
	else
		val &= ~ESDHC_CLOCK_SDCLKEN;

	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);

	/* Wait max 20 ms */
	timeout = ktime_add_ms(ktime_get(), 20);
	val = ESDHC_CLOCK_STABLE;
	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
		if (ktime_after(ktime_get(), timeout)) {
			pr_err("%s: Internal clock never stabilised.\n",
				mmc_hostname(host->mmc));
			break;
		}
		udelay(10);
	}
}

static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -469,8 +496,10 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)

	host->mmc->actual_clock = 0;

	if (clock == 0)
	if (clock == 0) {
		esdhc_clock_enable(host, false);
		return;
	}

	/* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
	if (esdhc->vendor_ver < VENDOR_V_23)
@@ -558,33 +587,6 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
	sdhci_writel(host, ctrl, ESDHC_PROCTL);
}

static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
{
	u32 val;
	ktime_t timeout;

	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);

	if (enable)
		val |= ESDHC_CLOCK_SDCLKEN;
	else
		val &= ~ESDHC_CLOCK_SDCLKEN;

	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);

	/* Wait max 20 ms */
	timeout = ktime_add_ms(ktime_get(), 20);
	val = ESDHC_CLOCK_STABLE;
	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
		if (ktime_after(ktime_get(), timeout)) {
			pr_err("%s: Internal clock never stabilised.\n",
				mmc_hostname(host->mmc));
			break;
		}
		udelay(10);
	}
}

static void esdhc_reset(struct sdhci_host *host, u8 mask)
{
	sdhci_reset(host, mask);