mmc: Merge branch fixes into next
Merge the mmc fixes for v6.8-rc[n] into the next branch, to allow them to get tested together with the new mmc changes that are targeted for v6.9. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
commit
6e860b05a0
@ -11,6 +11,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/ktime.h>
|
#include <linux/ktime.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
#include "sdhci-pltfm.h"
|
#include "sdhci-pltfm.h"
|
||||||
@ -109,6 +110,8 @@
|
|||||||
#define XENON_EMMC_PHY_LOGIC_TIMING_ADJUST (XENON_EMMC_PHY_REG_BASE + 0x18)
|
#define XENON_EMMC_PHY_LOGIC_TIMING_ADJUST (XENON_EMMC_PHY_REG_BASE + 0x18)
|
||||||
#define XENON_LOGIC_TIMING_VALUE 0x00AA8977
|
#define XENON_LOGIC_TIMING_VALUE 0x00AA8977
|
||||||
|
|
||||||
|
#define XENON_MAX_PHY_TIMEOUT_LOOPS 100
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List offset of PHY registers and some special register values
|
* List offset of PHY registers and some special register values
|
||||||
* in eMMC PHY 5.0 or eMMC PHY 5.1
|
* in eMMC PHY 5.0 or eMMC PHY 5.1
|
||||||
@ -216,6 +219,19 @@ static int xenon_alloc_emmc_phy(struct sdhci_host *host)
|
|||||||
return 0;
|
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 5.0/5.1 PHY init/re-init.
|
||||||
* eMMC PHY init should be executed after:
|
* eMMC PHY init should be executed after:
|
||||||
@ -232,6 +248,11 @@ static int xenon_emmc_phy_init(struct sdhci_host *host)
|
|||||||
struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
|
struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
|
||||||
struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs;
|
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 = sdhci_readl(host, phy_regs->timing_adj);
|
||||||
reg |= XENON_PHY_INITIALIZAION;
|
reg |= XENON_PHY_INITIALIZAION;
|
||||||
sdhci_writel(host, reg, phy_regs->timing_adj);
|
sdhci_writel(host, reg, phy_regs->timing_adj);
|
||||||
@ -259,18 +280,27 @@ static int xenon_emmc_phy_init(struct sdhci_host *host)
|
|||||||
/* get the wait time */
|
/* get the wait time */
|
||||||
wait /= clock;
|
wait /= clock;
|
||||||
wait++;
|
wait++;
|
||||||
/* wait for host eMMC PHY init completes */
|
|
||||||
udelay(wait);
|
|
||||||
|
|
||||||
reg = sdhci_readl(host, phy_regs->timing_adj);
|
/*
|
||||||
reg &= XENON_PHY_INITIALIZAION;
|
* AC5X spec says bit must be polled until zero.
|
||||||
if (reg) {
|
* We see cases in which timeout can take longer
|
||||||
|
* than the standard calculation on AC5X, which is
|
||||||
|
* expected following the spec comment above.
|
||||||
|
* According to the spec, we must wait as long as
|
||||||
|
* it takes for that bit to toggle on AC5X.
|
||||||
|
* Cap that with 100 delay loops so we won't get
|
||||||
|
* stuck here forever:
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = read_poll_timeout(sdhci_readl, reg,
|
||||||
|
!(reg & XENON_PHY_INITIALIZAION),
|
||||||
|
wait, XENON_MAX_PHY_TIMEOUT_LOOPS * wait,
|
||||||
|
false, host, phy_regs->timing_adj);
|
||||||
|
if (ret)
|
||||||
dev_err(mmc_dev(host->mmc), "eMMC PHY init cannot complete after %d us\n",
|
dev_err(mmc_dev(host->mmc), "eMMC PHY init cannot complete after %d us\n",
|
||||||
wait);
|
wait * XENON_MAX_PHY_TIMEOUT_LOOPS);
|
||||||
return -ETIMEDOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ARMADA_3700_SOC_PAD_1_8V 0x1
|
#define ARMADA_3700_SOC_PAD_1_8V 0x1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user