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