git: 550db3d6f502 - main - sdhci: Initial support for the SpacemiT K1 sdhci controller
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 16 Aug 2026 17:17:15 UTC
The branch main has been updated by bnovkov:
URL: https://cgit.FreeBSD.org/src/commit/?id=550db3d6f502946f6cf01eeb34f53e70395ddc6f
commit 550db3d6f502946f6cf01eeb34f53e70395ddc6f
Author: Bojan Novković <bnovkov@FreeBSD.org>
AuthorDate: 2026-05-19 21:07:12 +0000
Commit: Bojan Novković <bnovkov@FreeBSD.org>
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ć <bnovkov@FreeBSD.org>
+ *
+ * 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