git: 550db3d6f502 - main - sdhci: Initial support for the SpacemiT K1 sdhci controller

Bojan Novković <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a81f09b.316c2.5a6e8b31__20301.8647081748$1786900678$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by bnovkov:

URL: https://cgit.FreeBSD.org/src/commit/?id=550db3d6f502946f6cf01eeb34f53e70395ddc6f

commit 550db3d6f502946f6cf01eeb34f53e70395ddc6f
Author:     Bojan Novković <[email protected]>
AuthorDate: 2026-05-19 21:07:12 +0000
Commit:     Bojan Novković <[email protected]>
CommitDate: 2026-08-16 17:15:52 +0000

    sdhci: Initial support for the SpacemiT K1 sdhci controller
    
    Reviewed by:    mhorne
    Differential Revision:  https://reviews.freebsd.org/D57178
---
 sys/dev/sdhci/sdhci_fdt_spacemit.c | 134 +++++++++++++++++++++++++++++++++++++
 sys/riscv/spacemit/files.spacemit  |   2 +
 2 files changed, 136 insertions(+)

diff --git a/sys/dev/sdhci/sdhci_fdt_spacemit.c b/sys/dev/sdhci/sdhci_fdt_spacemit.c
new file mode 100644
index 000000000000..d516ce60f889
--- /dev/null
+++ b/sys/dev/sdhci/sdhci_fdt_spacemit.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2026 Bojan Novković <[email protected]>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/taskqueue.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/ofw_subr.h>
+#include <dev/clk/clk.h>
+#include <dev/ofw/openfirm.h>
+
+#include <dev/hwreset/hwreset.h>
+#include <dev/phy/phy.h>
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmcbrvar.h>
+#include <dev/mmc/mmcreg.h>
+
+#include <dev/sdhci/sdhci.h>
+#include <dev/sdhci/sdhci_fdt.h>
+
+#include "mmcbr_if.h"
+#include "sdhci_if.h"
+
+#include "opt_mmccam.h"
+#include "opt_soc.h"
+
+static struct ofw_compat_data compat_data[] = {
+	{ "spacemit,k1-sdhci", 1 },
+	{ NULL, 0 }
+};
+
+static int
+sdhci_fdt_spacemit_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	if (ofw_bus_has_prop(dev, "no-sd")) {
+		/* XXX: only attach to the SD card for now. */
+		device_printf(dev, "MMC and SDIO aren't supported yet\n");
+		return (ENXIO);
+	}
+
+	device_set_desc(dev, "SpacemiT K1 SDHCI controller");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+sdhci_fdt_spacemit_attach(device_t dev)
+{
+	struct sdhci_fdt_softc *sc;
+	clk_t clk_core;
+	hwreset_t rst;
+
+	sc = device_get_softc(dev);
+	sc->quirks = SDHCI_QUIRK_PRESET_VALUE_BROKEN |
+		SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+
+	if (clk_get_by_ofw_name(dev, 0, "core", &clk_core)) {
+		device_printf(dev, "cannot get core clock\n");
+		return (ENXIO);
+	}
+	if (clk_get_by_ofw_name(dev, 0, "io", &sc->clk_core)) {
+		device_printf(dev, "cannot get io clock\n");
+		return (ENXIO);
+	}
+	if (hwreset_get_by_ofw_name(dev, 0, "sdh", &rst) != 0) {
+		device_printf(dev, "cannot get device reset\n");
+		return (ENXIO);
+	}
+
+	if (hwreset_deassert(rst) != 0) {
+		device_printf(dev, "cannot reset device\n");
+		return (ENXIO);
+	}
+	if (clk_enable(clk_core) != 0) {
+		device_printf(dev, "cannot enable core clock\n");
+		return (ENXIO);
+	}
+	if (clk_enable(sc->clk_core) != 0) {
+		device_printf(dev, "cannot enable io clock\n");
+		return (ENXIO);
+	}
+
+	return (sdhci_fdt_attach(dev));
+}
+
+static int
+sdhci_fdt_spacemit_set_clock(device_t dev, struct sdhci_slot *slot, int clock)
+{
+	struct sdhci_fdt_softc *sc = device_get_softc(dev);
+	uint64_t freq;
+
+	sc = device_get_softc(dev);
+
+	clk_set_freq(sc->clk_core, clock, CLK_SET_ROUND_ANY);
+	clk_get_freq(sc->clk_core, &freq);
+
+	return ((int)freq);
+}
+
+static device_method_t sdhci_fdt_spacemit_methods[] = {
+	/* device_if */
+	DEVMETHOD(device_probe,		sdhci_fdt_spacemit_probe),
+	DEVMETHOD(device_attach,	sdhci_fdt_spacemit_attach),
+
+	DEVMETHOD(sdhci_set_clock,	sdhci_fdt_spacemit_set_clock),
+	DEVMETHOD_END
+};
+extern driver_t sdhci_fdt_driver;
+
+DEFINE_CLASS_1(sdhci_spacemit, sdhci_fdt_spacemit_driver, sdhci_fdt_spacemit_methods,
+    sizeof(struct sdhci_fdt_softc), sdhci_fdt_driver);
+DRIVER_MODULE(sdhci_spacemit, simplebus, sdhci_fdt_spacemit_driver, NULL, NULL);
+
+#ifndef MMCCAM
+MMC_DECLARE_BRIDGE(sdhci_fdt_spacemit);
+#endif
diff --git a/sys/riscv/spacemit/files.spacemit b/sys/riscv/spacemit/files.spacemit
index b4ab14e9240b..2b0d5cfdb343 100644
--- a/sys/riscv/spacemit/files.spacemit
+++ b/sys/riscv/spacemit/files.spacemit
@@ -1,3 +1,5 @@
 dev/clk/spacemit/k1_clk.c	optional k1_ccu fdt
 dev/clk/spacemit/k1_pll.c	optional k1_ccu fdt
 dev/clk/spacemit/k1_apmu.c	optional k1_ccu fdt
+
+dev/sdhci/sdhci_fdt_spacemit.c	optional fdt sdhci sdhci_spacemit
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.