[PATCH v1] mmc: am654_sdhci: Add the quirk to set TESTCD bit

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com
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 --- drivers/mmc/am654_sdhci.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c index fadab7d40bb7..43f890d269e9 100644 --- a/drivers/mmc/am654_sdhci.c +++ b/drivers/mmc/am654_sdhci.c @@ -106,6 +106,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 { @@ -351,10 +353,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;
@@ -369,12 +369,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) @@ -680,6 +703,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; }
@@ -729,6 +755,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)

On Tue, 02 Jul 2024 21:54:29 +0200, Emanuele Ghidoli wrote:
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.
[...]
Applied to u-boot/master, thanks!
participants (2)
-
Emanuele Ghidoli
-
Tom Rini