mmc: am654_sdhci: Add the quirk to set TESTCD bit
The ARASAN MMC controller on Keystone 3 class of devices need the SDCD
line to be connected for proper functioning.
In cases where this can't be connected, add a quirk to force the
controller into test mode and set the TESTCD bit. Use the flag
"ti,fails-without-test-cd", to implement this above quirk when required.
Additionally, this quirk also avoids waiting for the controller debounce
time.
This commit is similar to linux kernel commit c7666240ec76
("drivers: mmc: sdhci_am654: Add the quirk to set TESTCD bit").
Signed-off-by: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
This commit is contained in:
committed by
Tom Rini
parent
9945a30e2e
commit
afdce76863
@@ -105,6 +105,8 @@ struct am654_sdhci_plat {
|
||||
#define FREQSEL_2_BIT BIT(2)
|
||||
#define STRBSEL_4_BIT BIT(3)
|
||||
#define DLL_CALIB BIT(4)
|
||||
u32 quirks;
|
||||
#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
|
||||
};
|
||||
|
||||
struct timing_data {
|
||||
@@ -350,10 +352,8 @@ int am654_sdhci_init(struct am654_sdhci_plat *plat)
|
||||
}
|
||||
|
||||
#define MAX_SDCD_DEBOUNCE_TIME 2000
|
||||
static int am654_sdhci_deferred_probe(struct sdhci_host *host)
|
||||
static int am654_sdhci_cd_poll(struct mmc *mmc)
|
||||
{
|
||||
struct udevice *dev = host->mmc->dev;
|
||||
struct am654_sdhci_plat *plat = dev_get_plat(dev);
|
||||
unsigned long start;
|
||||
int val;
|
||||
|
||||
@@ -368,12 +368,35 @@ static int am654_sdhci_deferred_probe(struct sdhci_host *host)
|
||||
if (get_timer(start) > MAX_SDCD_DEBOUNCE_TIME)
|
||||
return -ENOMEDIUM;
|
||||
|
||||
val = mmc_getcd(host->mmc);
|
||||
val = mmc_getcd(mmc);
|
||||
} while (!val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int am654_sdhci_deferred_probe(struct sdhci_host *host)
|
||||
{
|
||||
struct udevice *dev = host->mmc->dev;
|
||||
struct am654_sdhci_plat *plat = dev_get_plat(dev);
|
||||
int ret;
|
||||
|
||||
if (!(plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST)) {
|
||||
if (am654_sdhci_cd_poll(host->mmc))
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
am654_sdhci_init(plat);
|
||||
|
||||
return sdhci_probe(dev);
|
||||
ret = sdhci_probe(dev);
|
||||
|
||||
if (plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) {
|
||||
u8 hostctrlreg = sdhci_readb(host, SDHCI_HOST_CONTROL);
|
||||
|
||||
hostctrlreg |= SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST;
|
||||
sdhci_writeb(host, hostctrlreg, SDHCI_HOST_CONTROL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void am654_sdhci_write_b(struct sdhci_host *host, u8 val, int reg)
|
||||
@@ -679,6 +702,9 @@ static int am654_sdhci_probe(struct udevice *dev)
|
||||
|
||||
regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
|
||||
|
||||
if (plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST)
|
||||
am654_sdhci_deferred_probe(host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -728,6 +754,8 @@ static int am654_sdhci_of_to_plat(struct udevice *dev)
|
||||
|
||||
dev_read_u32(dev, "ti,strobe-sel", &plat->strb_sel);
|
||||
dev_read_u32(dev, "ti,clkbuf-sel", &plat->clkbuf_sel);
|
||||
if (dev_read_bool(dev, "ti,fails-without-test-cd"))
|
||||
plat->quirks |= SDHCI_AM654_QUIRK_FORCE_CDTEST;
|
||||
|
||||
ret = mmc_of_parse(dev, cfg);
|
||||
if (ret)
|
||||
|
||||
Reference in New Issue
Block a user