The Arasan on the zynqmp in version 8.9a doesn't meet the timing requirements at 25MHz. It works at 19MHz instead. Add the quirk from linux kernel v6.8-rc4. Signed-off-by: Steffen Trumtrar <s.trumtrar@xxxxxxxxxxxxxx> Reviewed-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- drivers/mci/arasan-sdhci.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/mci/arasan-sdhci.c b/drivers/mci/arasan-sdhci.c index 98f990b5c1..77e6086165 100644 --- a/drivers/mci/arasan-sdhci.c +++ b/drivers/mci/arasan-sdhci.c @@ -37,6 +37,12 @@ struct arasan_sdhci_host { /* Controller does not have CD wired and will not function normally without */ #define SDHCI_ARASAN_QUIRK_FORCE_CDTEST BIT(0) #define SDHCI_ARASAN_QUIRK_NO_1_8_V BIT(1) +/* + * Some of the Arasan variations might not have timing requirements + * met at 25MHz for Default Speed mode, those controllers work at + * 19MHz instead + */ +#define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2) }; static inline @@ -110,13 +116,30 @@ static int arasan_sdhci_init(struct mci_host *mci, struct device *dev) return 0; } +static void arasan_sdhci_set_clock(struct mci_host *mci, unsigned int clock) +{ + struct arasan_sdhci_host *host = to_arasan_sdhci_host(mci); + + if (host->quirks & SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN) { + /* + * Some of the Arasan variations might not have timing + * requirements met at 25MHz for Default Speed mode, + * those controllers work at 19MHz instead. + */ + if (clock == 25000000) + clock = (25000000 * 19) / 25; + } + + sdhci_set_clock(&host->sdhci, clock, host->sdhci.max_clk); +} + static void arasan_sdhci_set_ios(struct mci_host *mci, struct mci_ios *ios) { struct arasan_sdhci_host *host = to_arasan_sdhci_host(mci); u16 val; if (ios->clock) - sdhci_set_clock(&host->sdhci, ios->clock, host->sdhci.max_clk); + arasan_sdhci_set_clock(mci, ios->clock); sdhci_set_bus_width(&host->sdhci, ios->bus_width); @@ -245,6 +268,9 @@ static int arasan_sdhci_probe(struct device *dev) if (of_property_read_bool(np, "no-1-8-v")) arasan_sdhci->quirks |= SDHCI_ARASAN_QUIRK_NO_1_8_V; + if (of_device_is_compatible(np, "xlnx,zynqmp-8.9a")) + arasan_sdhci->quirks |= SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN; + arasan_sdhci->sdhci.base = IOMEM(iores->start); arasan_sdhci->sdhci.mci = mci; mci->send_cmd = arasan_sdhci_send_cmd; -- 2.43.2