Page MenuHomeFreeBSD

D56072.id.diff
No OneTemporary

D56072.id.diff

diff --git a/sys/arm/broadcom/bcm2835/bcm_gpclk.c b/sys/arm/broadcom/bcm2835/bcm_gpclk.c
new file mode 100644
--- /dev/null
+++ b/sys/arm/broadcom/bcm2835/bcm_gpclk.c
@@ -0,0 +1,182 @@
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+
+#include <dev/clk/clk.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+struct bcm_gpclk_softc {
+ device_t dev;
+ clk_t clk;
+ uint64_t freq;
+ bool enabled;
+};
+
+static struct ofw_compat_data compat_data[] = {
+ { "freebsd,bcm-gpclk", 1 },
+ { NULL, 0 }
+};
+
+static int
+bcm_gpclk_freq_proc(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm_gpclk_softc *sc;
+ uint64_t freq;
+ int rv;
+
+ sc = arg1;
+ freq = sc->freq;
+
+ rv = sysctl_handle_64(oidp, &freq, 0, req);
+ if (rv != 0 || req->newptr == NULL)
+ return (rv);
+
+ if (!sc->enabled)
+ return (EINVAL);
+
+ if (freq == 0)
+ return (EINVAL);
+
+ rv = clk_set_freq(sc->clk, freq, CLK_SET_ROUND_ANY);
+ if (rv != 0)
+ return (rv);
+
+ clk_get_freq(sc->clk, &sc->freq);
+
+ if (bootverbose)
+ device_printf(sc->dev, "GP clock frequency set to %ju Hz\n",
+ (uintmax_t)sc->freq);
+ return (0);
+}
+
+static int
+bcm_gpclk_enable_proc(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm_gpclk_softc *sc;
+ bool enable;
+ int rv;
+
+ sc = arg1;
+ enable = sc->enabled;
+
+ rv = sysctl_handle_bool(oidp, &enable, 0, req);
+ if (rv != 0 || req->newptr == NULL)
+ return (rv);
+
+ if (enable && !sc->enabled) {
+ if (sc->clk == NULL)
+ return (EINVAL);
+
+ rv = clk_enable(sc->clk);
+ if (rv != 0)
+ return (rv);
+
+ sc->enabled = true;
+ } else if (!enable && sc->enabled) {
+ if (sc->clk == NULL)
+ return (EINVAL);
+
+ rv = clk_disable(sc->clk);
+ if (rv != 0)
+ return (rv);
+
+ sc->enabled = false;
+ }
+ if (bootverbose)
+ device_printf(sc->dev, "GP clock %s\n",
+ enable ? "enabled" : "disabled");
+ return (0);
+}
+
+static int
+bcm_gpclk_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);
+
+ device_set_desc(dev, "BCM GP Clock");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_gpclk_attach(device_t dev)
+{
+ struct bcm_gpclk_softc *sc;
+ phandle_t node;
+ int rv;
+ struct sysctl_ctx_list *ctxs;
+ struct sysctl_oid_list *tree;
+ struct sysctl_oid *oid;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+
+ rv = clk_get_by_ofw_index(dev, node, 0, &sc->clk);
+ if (rv != 0) {
+ device_printf(dev, "cannot get clock: %d\n", rv);
+ return (rv);
+ }
+
+ sc->dev = dev;
+ sc->enabled = false; /* Set false as default. */
+
+ /* Get actual frequency after setting. */
+ clk_get_freq(sc->clk, &sc->freq);
+
+ if (bootverbose)
+ device_printf(dev, "GP clock attached");
+
+ /* sysctl interface */
+ ctxs = device_get_sysctl_ctx(dev);
+ tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+
+ oid = SYSCTL_ADD_PROC(ctxs, tree, OID_AUTO, "freq", CTLFLAG_RW | CTLTYPE_U64,
+ sc, 0, bcm_gpclk_freq_proc, "QU", "GP clock frequency (Hz)");
+ if (oid == NULL) {
+ device_printf(dev, "failed to add sysctl for frequency\n");
+ return (ENOMEM);
+ }
+
+ oid = SYSCTL_ADD_PROC(ctxs, tree, OID_AUTO, "enable", CTLFLAG_RW | CTLTYPE_U8,
+ sc, 0, bcm_gpclk_enable_proc, "CU", "GP clock enable");
+ if (oid == NULL) {
+ device_printf(dev, "failed to add sysctl for enable\n");
+ return (ENOMEM);
+ }
+
+ return (0);
+}
+
+static int
+bcm_gpclk_detach(device_t dev)
+{
+ struct bcm_gpclk_softc *sc = device_get_softc(dev);
+ if (sc->clk != NULL) {
+ clk_release(sc->clk);
+ }
+ return (0);
+}
+
+static device_method_t bcm_gpclk_methods[] = {
+ DEVMETHOD(device_probe, bcm_gpclk_probe),
+ DEVMETHOD(device_attach, bcm_gpclk_attach),
+ DEVMETHOD(device_detach, bcm_gpclk_detach),
+ DEVMETHOD_END
+};
+
+static driver_t bcm_gpclk_driver = {
+ "bcm_gpclk",
+ bcm_gpclk_methods,
+ sizeof(struct bcm_gpclk_softc),
+};
+
+DRIVER_MODULE(bcm_gpclk, simplebus, bcm_gpclk_driver, NULL, NULL);
+MODULE_DEPEND(bcm_gpclk, clk, 1, 1, 1);
diff --git a/sys/arm/broadcom/bcm2835/files.bcm283x b/sys/arm/broadcom/bcm2835/files.bcm283x
--- a/sys/arm/broadcom/bcm2835/files.bcm283x
+++ b/sys/arm/broadcom/bcm2835/files.bcm283x
@@ -22,6 +22,7 @@
arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt
# CPRMAN clock controller (clkdev framework)
+arm/broadcom/bcm2835/bcm_gpclk.c standard
dev/clk/broadcom/bcm_clk_periph.c standard
dev/clk/broadcom/bcm_clk_pll.c standard
dev/clk/broadcom/bcm_clk_pll_channel.c standard
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -629,6 +629,7 @@
arm/broadcom/bcm2835/bcm2838_pci.c optional soc_brcm_bcm2838 fdt pci
arm/broadcom/bcm2835/bcm2838_xhci.c optional soc_brcm_bcm2838 fdt pci xhci
arm/broadcom/bcm2835/raspberrypi_gpio.c optional soc_brcm_bcm2837 gpio fdt | soc_brcm_bcm2838 gpio fdt
+arm/broadcom/bcm2835/bcm_gpclk.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
dev/clk/broadcom/bcm_clk_periph.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
dev/clk/broadcom/bcm_clk_pll.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
dev/clk/broadcom/bcm_clk_pll_channel.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
diff --git a/sys/dts/arm64/overlays/dpclk-rpi.dtso b/sys/dts/arm64/overlays/dpclk-rpi.dtso
new file mode 100644
--- /dev/null
+++ b/sys/dts/arm64/overlays/dpclk-rpi.dtso
@@ -0,0 +1,26 @@
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/bcm2835.h>
+#include <dt-bindings/pinctrl/bcm2835.h>
+
+/ {
+ compatible = "brcm,bcm2711";
+};
+
+&{/soc/gpio@7e200000} {
+ gpclk0_gpio4: gpclk0-gpio4 {
+ brcm,pins = <4>;
+ brcm,function = <BCM2835_FSEL_ALT0>; /* = 4,GPCLK0 */
+ };
+};
+
+&{/soc} {
+ gpclk0: gpclk@0 {
+ compatible = "freebsd,bcm-gpclk";
+ status = "okay";
+ clocks = <&clocks BCM2835_CLOCK_GP0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpclk0_gpio4>;
+ };
+};
diff --git a/sys/modules/dtb/rpi/Makefile b/sys/modules/dtb/rpi/Makefile
--- a/sys/modules/dtb/rpi/Makefile
+++ b/sys/modules/dtb/rpi/Makefile
@@ -5,7 +5,8 @@
.elif ${MACHINE_CPUARCH} == "aarch64"
DTSO= \
spigen-rpi3.dtso \
- spigen-rpi4.dtso
+ spigen-rpi4.dtso \
+ dpclk-rpi.dtso
.endif
.include <bsd.dtb.mk>

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 29, 11:18 AM (6 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32345264
Default Alt Text
D56072.id.diff (6 KB)

Event Timeline