diff --git a/sys/dev/mmc/host/dwmmc_starfive.c b/sys/dev/mmc/host/dwmmc_starfive.c new file mode 100644 --- /dev/null +++ b/sys/dev/mmc/host/dwmmc_starfive.c @@ -0,0 +1,115 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2017 Emmanuel Vadot + * Copyright (c) 2021 Mitchell Horne + * Copyright (c) 2024 The FreeBSD Foundation + * + * Portions of this software were developed by Mitchell Horne + * under sponsorship from the FreeBSD Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +#include "opt_mmccam.h" + +enum dwmmc_type { + DWMMC_GENERIC = 1, + DWMMC_JH7110 +}; + +static struct ofw_compat_data compat_data[] = { + {"snps,dw-mshc", DWMMC_GENERIC}, + {"starfive,jh7110-mmc", DWMMC_JH7110}, + {NULL, 0} +}; + +static int dwmmc_starfive_update_ios(struct dwmmc_softc *sc, + struct mmc_ios *ios) +{ + int err; + + if (ios->clock != 0 && ios->clock != sc->bus_hz) { + err = clk_set_freq(sc->ciu, ios->clock, CLK_SET_ROUND_DOWN); + if (err != 0) { + printf("%s, Failed to set freq for ciu clock\n", + __func__); + return (err); + } + sc->bus_hz = ios->clock; + } + + return (0); +} + +static int +starfive_dwmmc_probe(device_t dev) +{ + phandle_t node; + int type; + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + if (type == 0) + return (ENXIO); + + /* + * If we matched the generic compat string, check the top-level board + * compatible, to ensure we should actually use the starfive driver. + */ + if (type == DWMMC_GENERIC) { + node = OF_finddevice("/"); + if (!ofw_bus_node_is_compatible(node, "starfive,jh7110")) + return (ENXIO); + } + + device_set_desc(dev, "Synopsys DesignWare Mobile Storage " + "Host Controller (StarFive)"); + + return (BUS_PROBE_VENDOR); +} + +static int +starfive_dwmmc_attach(device_t dev) +{ + struct dwmmc_softc *sc; + + sc = device_get_softc(dev); + sc->update_ios = &dwmmc_starfive_update_ios; + + return (dwmmc_attach(dev)); +} + +static device_method_t starfive_dwmmc_methods[] = { + /* bus interface */ + DEVMETHOD(device_probe, starfive_dwmmc_probe), + DEVMETHOD(device_attach, starfive_dwmmc_attach), + DEVMETHOD(device_detach, dwmmc_detach), + + DEVMETHOD_END +}; + +DEFINE_CLASS_1(starfive_dwmmc, starfive_dwmmc_driver, starfive_dwmmc_methods, + sizeof(struct dwmmc_softc), dwmmc_driver); + +DRIVER_MODULE(starfive_dwmmc, simplebus, starfive_dwmmc_driver, 0, 0); + +#ifndef MMCCAM +MMC_DECLARE_BRIDGE(starfive_dwmmc); +#endif diff --git a/sys/riscv/conf/std.starfive b/sys/riscv/conf/std.starfive --- a/sys/riscv/conf/std.starfive +++ b/sys/riscv/conf/std.starfive @@ -9,4 +9,8 @@ device dwc device dwc_starfive +# MMC/SD/SDIO Card slot support +device dwmmc +device dwmmc_starfive + files "../starfive/files.starfive" diff --git a/sys/riscv/starfive/files.starfive b/sys/riscv/starfive/files.starfive --- a/sys/riscv/starfive/files.starfive +++ b/sys/riscv/starfive/files.starfive @@ -3,5 +3,6 @@ dev/clk/starfive/jh7110_clk_pll.c standard dev/clk/starfive/jh7110_clk_sys.c standard dev/dwc/if_dwc_starfive.c optional dwc_starfive fdt +dev/mmc/host/dwmmc_starfive.c optional dwmmc_starfive fdt riscv/starfive/starfive_syscon.c standard