|
@@ -18,6 +18,7 @@
|
|
|
#include <linux/of.h>
|
|
|
#include <linux/delay.h>
|
|
|
#include <linux/module.h>
|
|
|
+#include <linux/sys_soc.h>
|
|
|
#include <linux/mmc/host.h>
|
|
|
#include "sdhci-pltfm.h"
|
|
|
#include "sdhci-esdhc.h"
|
|
@@ -28,6 +29,7 @@
|
|
|
struct sdhci_esdhc {
|
|
|
u8 vendor_ver;
|
|
|
u8 spec_ver;
|
|
|
+ bool quirk_incorrect_hostver;
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -87,6 +89,8 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
|
|
|
static u16 esdhc_readw_fixup(struct sdhci_host *host,
|
|
|
int spec_reg, u32 value)
|
|
|
{
|
|
|
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
|
|
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
|
|
|
u16 ret;
|
|
|
int shift = (spec_reg & 0x2) * 8;
|
|
|
|
|
@@ -94,6 +98,12 @@ static u16 esdhc_readw_fixup(struct sdhci_host *host,
|
|
|
ret = value & 0xffff;
|
|
|
else
|
|
|
ret = (value >> shift) & 0xffff;
|
|
|
+ /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect
|
|
|
+ * vendor version and spec version information.
|
|
|
+ */
|
|
|
+ if ((spec_reg == SDHCI_HOST_VERSION) &&
|
|
|
+ (esdhc->quirk_incorrect_hostver))
|
|
|
+ ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200;
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -572,6 +582,12 @@ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = {
|
|
|
.ops = &sdhci_esdhc_le_ops,
|
|
|
};
|
|
|
|
|
|
+static struct soc_device_attribute soc_incorrect_hostver[] = {
|
|
|
+ { .family = "QorIQ T4240", .revision = "1.0", },
|
|
|
+ { .family = "QorIQ T4240", .revision = "2.0", },
|
|
|
+ { },
|
|
|
+};
|
|
|
+
|
|
|
static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
|
|
|
{
|
|
|
struct sdhci_pltfm_host *pltfm_host;
|
|
@@ -585,6 +601,10 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
|
|
|
esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >>
|
|
|
SDHCI_VENDOR_VER_SHIFT;
|
|
|
esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK;
|
|
|
+ if (soc_device_match(soc_incorrect_hostver))
|
|
|
+ esdhc->quirk_incorrect_hostver = true;
|
|
|
+ else
|
|
|
+ esdhc->quirk_incorrect_hostver = false;
|
|
|
}
|
|
|
|
|
|
static int sdhci_esdhc_probe(struct platform_device *pdev)
|