Page MenuHomeFreeBSD

D55942.diff
No OneTemporary

D55942.diff

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
@@ -21,6 +21,15 @@
arm/broadcom/bcm2835/bcm2838_xhci.c optional xhci
arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt
+# CPRMAN clock controller (clkdev framework)
+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
+dev/clk/broadcom/bcm_clk_stub.c standard
+dev/clk/broadcom/bcm_cprman.c standard
+dev/clk/broadcom/bcm2835_cprman_clocks.c standard
+dev/clk/broadcom/bcm2835_cprman_drv.c standard
+
dev/mbox/mbox_if.m standard
arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq \
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,13 @@
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
+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
+dev/clk/broadcom/bcm_clk_stub.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
+dev/clk/broadcom/bcm_cprman.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
+dev/clk/broadcom/bcm2835_cprman_clocks.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
+dev/clk/broadcom/bcm2835_cprman_drv.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 fdt \
compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq soc_brcm_bcm2837 fdt \
diff --git a/sys/dev/clk/broadcom/bcm2835_cprman_clocks.c b/sys/dev/clk/broadcom/bcm2835_cprman_clocks.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/clk/broadcom/bcm2835_cprman_clocks.c
@@ -0,0 +1,279 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 Perdixky <3293789706@qq.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+
+#include <dev/clk/broadcom/bcm_cprman.h>
+
+#include <contrib/device-tree/include/dt-bindings/clock/bcm2835.h>
+
+#define BCM2835_CM_LOCK 0x114
+#define BCM2835_A2W_XOSC_CTRL 0x1190
+
+#define BCM2835_PLL_CTRL_PRST_DISABLE_SHIFT 17
+#define BCM2835_PLL_CTRL_PWRDN_SHIFT 16
+#define BCM2835_PLL_CTRL_PDIV_SHIFT 12
+#define BCM2835_PLL_CTRL_PDIV_WIDTH 3
+#define BCM2835_PLL_CTRL_NDIV_SHIFT 0
+#define BCM2835_PLL_CTRL_NDIV_WIDTH 10
+
+#define BCM2835_PLL_FRAC_SHIFT 0
+#define BCM2835_PLL_FRAC_WIDTH 20
+
+#define BCM2835_CM_PLL_ANARST_SHIFT 8
+
+#define BCM2835_A2W_XOSC_PLLC_ENABLE_SHIFT 0
+#define BCM2835_A2W_XOSC_PLLD_ENABLE_SHIFT 4
+#define BCM2835_A2W_XOSC_PLLA_ENABLE_SHIFT 6
+
+#define BCM2835_CM_LOCK_FLOCKA_SHIFT 8
+#define BCM2835_CM_LOCK_FLOCKC_SHIFT 10
+#define BCM2835_CM_LOCK_FLOCKD_SHIFT 11
+
+#define BCM2835_PLL_MIN_RATE 600000000ULL
+#define BCM2835_PLLA_MAX_RATE 2400000000ULL
+#define BCM2835_PLLC_MAX_RATE 3000000000ULL
+#define BCM2835_PLLD_MAX_RATE 2400000000ULL
+
+#define BCM2835_PLL_CHANNEL_DISABLE_SHIFT 8
+#define BCM2835_PLL_CHANNEL_DIV_SHIFT 0
+#define BCM2835_PLL_CHANNEL_DIV_WIDTH 8
+
+static const char *bcm2835_osc_parent[] = {
+ "osc",
+};
+
+static const char *bcm2835_plla_parent[] = {
+ "plla",
+};
+
+static const char *bcm2835_pllc_parent[] = {
+ "pllc",
+};
+
+static const char *bcm2835_plld_parent[] = {
+ "plld",
+};
+
+#define BCM2835_STUB_CLK(_name) \
+ { \
+ .clkdef = { \
+ .name = (_name), \
+ .flags = 0, \
+ }, \
+ .freq = 0, \
+ }
+
+/*
+ * TODO: Replace these temporary 0Hz placeholders with real providers for
+ * test/debug clocks and PLLH once the corresponding clknodes are added.
+ */
+static const struct bcm_clk_stub_def bcm2835_stub_clks[] = {
+ BCM2835_STUB_CLK("gnd"),
+ BCM2835_STUB_CLK("testdebug0"),
+ BCM2835_STUB_CLK("testdebug1"),
+ BCM2835_STUB_CLK("pllh_aux"),
+};
+
+/*
+ * BCM2835 peripheral clock SRC field (CTL[3:0]) maps to these parents
+ * in order. Only "osc" is guaranteed to be registered as a fixed clock
+ * from the DTB; the PLL names are resolved when those nodes are added.
+ */
+static const char *bcm2835_peri_parents[] = {
+ "gnd", /* 0 */
+ "osc", /* 1: 19.2 MHz crystal */
+ "testdebug0", /* 2 */
+ "testdebug1", /* 3 */
+ "plla_per", /* 4 */
+ "pllc_per", /* 5 */
+ "plld_per", /* 6 */
+ "pllh_aux", /* 7 */
+};
+
+/*
+ * BCM2835 peripheral clock register layout (both CTL and DIV):
+ * CTL: [31:24] PASSWD [10:9] MASH [7] BUSY [4] ENAB [3:0] SRC
+ * DIV: [31:24] PASSWD [23:12] DIVI [11:0] DIVF
+ */
+#define BCM2835_PERIPH_CLK(_name, _id, _ctl, _div) \
+ { \
+ .clkdef = { \
+ .name = (_name), \
+ .id = (_id), \
+ .parent_names = bcm2835_peri_parents, \
+ .parent_cnt = nitems(bcm2835_peri_parents), \
+ .flags = 0, \
+ }, \
+ .ctl_offset = (_ctl), \
+ .div_offset = (_div), \
+ .mash_shift = 9, \
+ .mash_width = 2, \
+ .busy_shift = 7, \
+ .enable_shift = 4, \
+ .src_shift = 0, \
+ .src_width = 4, \
+ .div_int_shift = 12, \
+ .div_int_width = 12, \
+ .div_frac_shift = 0, \
+ .div_frac_width = 12, \
+ }
+
+#define BCM2835_PLL_CLK(_name, _id, _cm, _ctrl, _frac, _ana0, _xosc, _flock, _max) \
+ { \
+ .clkdef = { \
+ .name = (_name), \
+ .id = (_id), \
+ .parent_names = bcm2835_osc_parent, \
+ .parent_cnt = nitems(bcm2835_osc_parent), \
+ .flags = 0, \
+ }, \
+ .min_freq = BCM2835_PLL_MIN_RATE, \
+ .max_freq = (_max), \
+ .a2w_xosc_ctrl_offset = BCM2835_A2W_XOSC_CTRL, \
+ .a2w_xosc_ctrl = { \
+ .enable_shift = (_xosc), \
+ }, \
+ .cm_offset = (_cm), \
+ .cm = { \
+ .anarst_shift = BCM2835_CM_PLL_ANARST_SHIFT, \
+ }, \
+ .cm_lock_offset = BCM2835_CM_LOCK, \
+ .cm_lock = { \
+ .flock_shift = (_flock), \
+ }, \
+ .a2w_ctrl_offset = (_ctrl), \
+ .a2w_ctrl = { \
+ .prst_disable_shift = BCM2835_PLL_CTRL_PRST_DISABLE_SHIFT, \
+ .pwrdn_shift = BCM2835_PLL_CTRL_PWRDN_SHIFT, \
+ .pdiv_shift = BCM2835_PLL_CTRL_PDIV_SHIFT, \
+ .pdiv_width = BCM2835_PLL_CTRL_PDIV_WIDTH, \
+ .ndiv_shift = BCM2835_PLL_CTRL_NDIV_SHIFT, \
+ .ndiv_width = BCM2835_PLL_CTRL_NDIV_WIDTH, \
+ }, \
+ .a2w_frac_offset = (_frac), \
+ .a2w_frac = { \
+ .frac_shift = BCM2835_PLL_FRAC_SHIFT, \
+ .frac_width = BCM2835_PLL_FRAC_WIDTH, \
+ }, \
+ .a2w_nan1_offset = (_ana0) + 0x4, \
+ .a2w_nan1 = { \
+ .ki_shift = 19, \
+ .ki_width = 3, \
+ .kp_shift = 15, \
+ .kp_width = 4, \
+ .fb_prediv_shift = 14, \
+ }, \
+ .a2w_nan3_offset = (_ana0) + 0xc, \
+ .a2w_nan3 = { \
+ .ka_shift = 7, \
+ .ka_width = 3, \
+ }, \
+ }
+
+#define BCM2835_PLL_CHANNEL(_name, _id, _parents, _cm, _a2w, _load, _hold) \
+ { \
+ .clkdef = { \
+ .name = (_name), \
+ .id = (_id), \
+ .parent_names = (_parents), \
+ .parent_cnt = 1, \
+ .flags = 0, \
+ }, \
+ .cm_offset = (_cm), \
+ .hold_shift = (_hold), \
+ .load_shift = (_load), \
+ .offset = (_a2w), \
+ .disable_shift = BCM2835_PLL_CHANNEL_DISABLE_SHIFT, \
+ .div_shift = BCM2835_PLL_CHANNEL_DIV_SHIFT, \
+ .div_width = BCM2835_PLL_CHANNEL_DIV_WIDTH, \
+ }
+
+static const struct bcm_clk_periph_def bcm2835_periph_clks[] = {
+ BCM2835_PERIPH_CLK("gp0", BCM2835_CLOCK_GP0, 0x070, 0x074),
+ BCM2835_PERIPH_CLK("gp1", BCM2835_CLOCK_GP1, 0x078, 0x07c),
+ BCM2835_PERIPH_CLK("gp2", BCM2835_CLOCK_GP2, 0x080, 0x084),
+ BCM2835_PERIPH_CLK("pwm", BCM2835_CLOCK_PWM, 0x0a0, 0x0a4),
+ BCM2835_PERIPH_CLK("pcm", BCM2835_CLOCK_PCM, 0x098, 0x09c),
+};
+
+static const struct bcm_clk_pll_def bcm2835_plls[] = {
+ BCM2835_PLL_CLK("plla", BCM2835_PLLA, 0x104, 0x1100, 0x1200, 0x1010,
+ BCM2835_A2W_XOSC_PLLA_ENABLE_SHIFT, BCM2835_CM_LOCK_FLOCKA_SHIFT,
+ BCM2835_PLLA_MAX_RATE),
+ BCM2835_PLL_CLK("pllc", BCM2835_PLLC, 0x108, 0x1120, 0x1220, 0x1030,
+ BCM2835_A2W_XOSC_PLLC_ENABLE_SHIFT, BCM2835_CM_LOCK_FLOCKC_SHIFT,
+ BCM2835_PLLC_MAX_RATE),
+ BCM2835_PLL_CLK("plld", BCM2835_PLLD, 0x10c, 0x1140, 0x1240, 0x1050,
+ BCM2835_A2W_XOSC_PLLD_ENABLE_SHIFT, BCM2835_CM_LOCK_FLOCKD_SHIFT,
+ BCM2835_PLLD_MAX_RATE),
+};
+
+static const struct bcm_clk_pll_channel_def bcm2835_pll_channels[] = {
+ BCM2835_PLL_CHANNEL("plla_dsi0", BCM2835_PLLA_DSI0, bcm2835_plla_parent,
+ 0x104, 0x1300, 0, 1),
+ BCM2835_PLL_CHANNEL("plla_ccp2", BCM2835_PLLA_CCP2, bcm2835_plla_parent,
+ 0x104, 0x1600, 2, 3),
+ BCM2835_PLL_CHANNEL("plla_core", BCM2835_PLLA_CORE, bcm2835_plla_parent,
+ 0x104, 0x1400, 4, 5),
+ BCM2835_PLL_CHANNEL("plla_per", BCM2835_PLLA_PER, bcm2835_plla_parent,
+ 0x104, 0x1500, 6, 7),
+
+ BCM2835_PLL_CHANNEL("pllc_core0", BCM2835_PLLC_CORE0,
+ bcm2835_pllc_parent, 0x108, 0x1620, 0, 1),
+ BCM2835_PLL_CHANNEL("pllc_core1", BCM2835_PLLC_CORE1,
+ bcm2835_pllc_parent, 0x108, 0x1420, 2, 3),
+ BCM2835_PLL_CHANNEL("pllc_core2", BCM2835_PLLC_CORE2,
+ bcm2835_pllc_parent, 0x108, 0x1320, 4, 5),
+ BCM2835_PLL_CHANNEL("pllc_per", BCM2835_PLLC_PER, bcm2835_pllc_parent,
+ 0x108, 0x1520, 6, 7),
+
+ BCM2835_PLL_CHANNEL("plld_dsi0", BCM2835_PLLD_DSI0, bcm2835_plld_parent,
+ 0x10c, 0x1340, 0, 1),
+ BCM2835_PLL_CHANNEL("plld_dsi1", BCM2835_PLLD_DSI1, bcm2835_plld_parent,
+ 0x10c, 0x1640, 2, 3),
+ BCM2835_PLL_CHANNEL("plld_core", BCM2835_PLLD_CORE, bcm2835_plld_parent,
+ 0x10c, 0x1440, 4, 5),
+ BCM2835_PLL_CHANNEL("plld_per", BCM2835_PLLD_PER, bcm2835_plld_parent,
+ 0x10c, 0x1540, 6, 7),
+};
+
+const struct bcm_cprman_clk_data bcm2835_cprman_clk_data = {
+ .stub_clks = bcm2835_stub_clks,
+ .stub_clk_cnt = nitems(bcm2835_stub_clks),
+
+ .periph_clks = bcm2835_periph_clks,
+ .periph_clk_cnt = nitems(bcm2835_periph_clks),
+
+ .pll_clks = bcm2835_plls,
+ .pll_clk_cnt = nitems(bcm2835_plls),
+
+ .pll_chan_clks = bcm2835_pll_channels,
+ .pll_chan_clk_cnt = nitems(bcm2835_pll_channels),
+};
diff --git a/sys/dev/clk/broadcom/bcm2835_cprman_drv.c b/sys/dev/clk/broadcom/bcm2835_cprman_drv.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/clk/broadcom/bcm2835_cprman_drv.c
@@ -0,0 +1,95 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 Perdixky <3293789706@qq.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#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 <machine/bus.h>
+
+#include <dev/clk/broadcom/bcm_cprman.h>
+#include <dev/fdt/simplebus.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+extern const struct bcm_cprman_clk_data bcm2835_cprman_clk_data;
+
+static struct ofw_compat_data compat_data[] = {
+ { "brcm,bcm2835-cprman", 1 },
+ { "brcm,bcm2711-cprman", 1 },
+ { NULL, 0 }
+};
+
+static int
+bcm2835_cprman_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, "BCM2835 CPRMAN Clock Controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm2835_cprman_attach(device_t dev)
+{
+ struct bcm_cprman_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->clk_data = &bcm2835_cprman_clk_data;
+
+ return (bcm_cprman_attach(dev));
+}
+
+static device_method_t bcm2835_cprman_methods[] = {
+ DEVMETHOD(device_probe, bcm2835_cprman_probe),
+ DEVMETHOD(device_attach, bcm2835_cprman_attach),
+ DEVMETHOD_END
+};
+
+/*
+ * DEFINE_CLASS_1: inherit bcm_cprman_driver's clkdev methods
+ * (clkdev_write_4 / read_4 / modify_4 / device_lock / device_unlock).
+ * This driver only adds probe + attach on top.
+ */
+DEFINE_CLASS_1(bcm2835_cprman, bcm2835_cprman_driver, bcm2835_cprman_methods,
+ sizeof(struct bcm_cprman_softc), bcm_cprman_driver);
+
+/*
+ * Clock drivers must be initialized early (BUS_PASS_BUS) so that
+ * peripheral drivers can find their clocks during their own attach.
+ */
+EARLY_DRIVER_MODULE(bcm2835_cprman, simplebus, bcm2835_cprman_driver, 0, 0,
+ BUS_PASS_BUS + BUS_PASS_ORDER_LATE);
+MODULE_VERSION(bcm2835_cprman, 1);

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 12, 12:41 PM (13 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31348752
Default Alt Text
D55942.diff (14 KB)

Event Timeline