mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-16 09:54:35 +00:00
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:
parent
9945a30e2e
commit
afdce76863
1 changed files with 33 additions and 5 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue