Skip to content

Commit

Permalink
mmc: sdhci-of-esdhc: workaround for unreliable pulse width detection
Browse files Browse the repository at this point in the history
This was a SoC issue on LX2160A Rev1.0.
eSDHC_DLLCFG1[DLL_PD_PULSE_STRETCH_SEL] must be set to 0 to
get 4 delay cells in the pulse width detection logic for eMMC
HS400 mode. Otherwise it would cause unexpected HS400 issue.
This patch is to clear this bit always for affected SoC when
reset for all, since this bit doesn't affect other speed modes.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
  • Loading branch information
Yangbo Lu authored and Ulf Hansson committed Dec 17, 2018
1 parent 58d0bf8 commit 48e304c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
4 changes: 4 additions & 0 deletions drivers/mmc/host/sdhci-esdhc.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
#define ESDHC_DLL_ENABLE 0x80000000
#define ESDHC_DLL_FREQ_SEL 0x08000000

/* DLL Config 1 Register */
#define ESDHC_DLLCFG1 0x164
#define ESDHC_DLL_PD_PULSE_STRETCH_SEL 0x80000000

/* DLL Status 0 Register */
#define ESDHC_DLLSTAT0 0x170
#define ESDHC_DLL_STS_SLV_LOCK 0x08000000
Expand Down
19 changes: 19 additions & 0 deletions drivers/mmc/host/sdhci-of-esdhc.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct sdhci_esdhc {
u8 spec_ver;
bool quirk_incorrect_hostver;
bool quirk_limited_clk_division;
bool quirk_unreliable_pulse_detection;
bool quirk_fixup_tuning;
unsigned int peripheral_clock;
const struct esdhc_clk_fixup *clk_fixup;
Expand Down Expand Up @@ -676,6 +677,8 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)

static void esdhc_reset(struct sdhci_host *host, u8 mask)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
u32 val;

sdhci_reset(host, mask);
Expand All @@ -687,6 +690,12 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask)
val = sdhci_readl(host, ESDHC_TBCTL);
val &= ~ESDHC_TB_EN;
sdhci_writel(host, val, ESDHC_TBCTL);

if (esdhc->quirk_unreliable_pulse_detection) {
val = sdhci_readl(host, ESDHC_DLLCFG1);
val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL;
sdhci_writel(host, val, ESDHC_DLLCFG1);
}
}
}

Expand Down Expand Up @@ -941,6 +950,11 @@ static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = {
{ },
};

static struct soc_device_attribute soc_unreliable_pulse_detection[] = {
{ .family = "QorIQ LX2160A", .revision = "1.0", },
{ },
};

static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
{
const struct of_device_id *match;
Expand Down Expand Up @@ -968,6 +982,11 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
else
esdhc->quirk_limited_clk_division = false;

if (soc_device_match(soc_unreliable_pulse_detection))
esdhc->quirk_unreliable_pulse_detection = true;
else
esdhc->quirk_unreliable_pulse_detection = false;

match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node);
if (match)
esdhc->clk_fixup = match->data;
Expand Down

0 comments on commit 48e304c

Please sign in to comment.