summaryrefslogtreecommitdiffstats
path: root/drivers/mci/arasan-sdhci.c
diff options
context:
space:
mode:
authorSteffen Trumtrar <s.trumtrar@pengutronix.de>2024-03-18 11:18:18 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2024-03-18 13:17:07 +0100
commit6d0980c89783391c785a7d0498ac04fd3f4a05da (patch)
tree5bc3593dc56c75fa5550ce349b09d0332d420c5e /drivers/mci/arasan-sdhci.c
parentd26f2505c399c9a512036c65dde4ecd8360c4b87 (diff)
downloadbarebox-6d0980c89783391c785a7d0498ac04fd3f4a05da.tar.gz
barebox-6d0980c89783391c785a7d0498ac04fd3f4a05da.tar.xz
mci: arasan: implement 25MHz quirk for zynqmp
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@pengutronix.de> Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Diffstat (limited to 'drivers/mci/arasan-sdhci.c')
-rw-r--r--drivers/mci/arasan-sdhci.c28
1 files changed, 27 insertions, 1 deletions
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;