Commit a3fb32da authored by Elad Nachman's avatar Elad Nachman Committed by sanglipeng1
Browse files

mmc: sdhci-xenon: fix PHY init clock stability

stable inclusion
from stable-v5.10.212
commit 36b02df0a6ce0c0fd31af2cab6607bbeeaccad58
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAGOP2

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=36b02df0a6ce0c0fd31af2cab6607bbeeaccad58



--------------------------------

commit 8e9f25a290ae0016353c9ea13314c95fb3207812 upstream.

Each time SD/mmc phy is initialized, at times, in some of
the attempts, phy fails to completes its initialization
which results into timeout error. Per the HW spec, it is
a pre-requisite to ensure a stable SD clock before a phy
initialization is attempted.

Fixes: 06c8b667 ("mmc: sdhci-xenon: Add support to PHYs of Marvell Xenon SDHC")
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarElad Nachman <enachman@marvell.com>
Link: https://lore.kernel.org/r/20240222200930.1277665-1-enachman@marvell.com


Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarsanglipeng1 <sanglipeng1@jd.com>
parent 522b6759
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/ktime.h>
#include <linux/iopoll.h>
#include <linux/of_address.h>

#include "sdhci-pltfm.h"
@@ -218,6 +219,19 @@ static int xenon_alloc_emmc_phy(struct sdhci_host *host)
	return 0;
}

static int xenon_check_stability_internal_clk(struct sdhci_host *host)
{
	u32 reg;
	int err;

	err = read_poll_timeout(sdhci_readw, reg, reg & SDHCI_CLOCK_INT_STABLE,
				1100, 20000, false, host, SDHCI_CLOCK_CONTROL);
	if (err)
		dev_err(mmc_dev(host->mmc), "phy_init: Internal clock never stabilized.\n");

	return err;
}

/*
 * eMMC 5.0/5.1 PHY init/re-init.
 * eMMC PHY init should be executed after:
@@ -234,6 +248,11 @@ static int xenon_emmc_phy_init(struct sdhci_host *host)
	struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
	struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs;

	int ret = xenon_check_stability_internal_clk(host);

	if (ret)
		return ret;

	reg = sdhci_readl(host, phy_regs->timing_adj);
	reg |= XENON_PHY_INITIALIZAION;
	sdhci_writel(host, reg, phy_regs->timing_adj);