@@ -76,6 +76,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
@@ -34,6 +34,7 @@ struct sdhci_esdhc {
u8 spec_ver;
bool quirk_incorrect_hostver;
bool quirk_limited_clk_division;
+ bool quirk_unreliable_pulse_detection;
unsigned int peripheral_clock;
};
@@ -640,6 +641,8 @@ static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
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);
@@ -651,6 +654,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);
+ }
}
}
@@ -891,6 +900,11 @@ static SIMPLE_DEV_PM_OPS(esdhc_of_dev_pm_ops,
{ },
};
+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)
{
struct sdhci_pltfm_host *pltfm_host;
@@ -917,6 +931,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;
+
np = pdev->dev.of_node;
clk = of_clk_get(np, 0);
if (!IS_ERR(clk)) {