Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151916655
D55942.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D55942.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D55942: clk/broadcom: Add BCM2835 CPRMAN clock tables and wire up build
Attached
Detach File
Event Timeline
Log In to Comment