Module Name:    src
Committed By:   skrll
Date:           Sat Jul 27 07:09:50 UTC 2024

Modified Files:
        src/sys/arch/riscv/starfive: files.starfive jh7100_clkc.c
Added Files:
        src/sys/arch/riscv/starfive: jh71x0_clkc.c jh71x0_clkc.h
Removed Files:
        src/sys/arch/riscv/starfive: jh7100_clkc.h

Log Message:
risc-v: split the jh7100 clock controller driver

In preparation for the JH7110 clock driver split the clock definition
and attachment code from the clock handling macros / methods.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/riscv/starfive/files.starfive
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/riscv/starfive/jh7100_clkc.c
cvs rdiff -u -r1.2 -r0 src/sys/arch/riscv/starfive/jh7100_clkc.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/riscv/starfive/jh71x0_clkc.c \
    src/sys/arch/riscv/starfive/jh71x0_clkc.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/riscv/starfive/files.starfive
diff -u src/sys/arch/riscv/starfive/files.starfive:1.3 src/sys/arch/riscv/starfive/files.starfive:1.4
--- src/sys/arch/riscv/starfive/files.starfive:1.3	Wed Feb  7 17:17:59 2024
+++ src/sys/arch/riscv/starfive/files.starfive	Sat Jul 27 07:09:50 2024
@@ -1,13 +1,19 @@
-#	$NetBSD: files.starfive,v 1.3 2024/02/07 17:17:59 skrll Exp $
+#	$NetBSD: files.starfive,v 1.4 2024/07/27 07:09:50 skrll Exp $
 #
 # Configuration info for StarFive SoCs
 #
 
-# JH7100 Clock controller
+# JH71x0 Clock controllers
 device	jh7100clkc
 attach	jh7100clkc at fdt with jh7100_clkc
 file	arch/riscv/starfive/jh7100_clkc.c		jh7100_clkc
 
+device	jh7110clkc
+attach	jh7110clkc at fdt with jh7110_clkc
+file	arch/riscv/starfive/jh7110_clkc.c		jh7110_clkc
+
+file	arch/riscv/starfive/jh71x0_clkc.c		jh7100_clkc | jh7110_clkc
+
 # JH71x0 USB
 device	jh71x0usb
 attach	jh71x0usb at fdt with jh71x0_usb

Index: src/sys/arch/riscv/starfive/jh7100_clkc.c
diff -u src/sys/arch/riscv/starfive/jh7100_clkc.c:1.2 src/sys/arch/riscv/starfive/jh7100_clkc.c:1.3
--- src/sys/arch/riscv/starfive/jh7100_clkc.c:1.2	Wed Jan 17 06:56:50 2024
+++ src/sys/arch/riscv/starfive/jh7100_clkc.c	Sat Jul 27 07:09:50 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: jh7100_clkc.c,v 1.2 2024/01/17 06:56:50 skrll Exp $ */
+/* $NetBSD: jh7100_clkc.c,v 1.3 2024/07/27 07:09:50 skrll Exp $ */
 
 /*-
  * Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.c,v 1.2 2024/01/17 06:56:50 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.c,v 1.3 2024/07/27 07:09:50 skrll Exp $");
 
 #include <sys/param.h>
 
@@ -41,7 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.
 
 #include <dev/fdt/fdtvar.h>
 
-#include <riscv/starfive/jh7100_clkc.h>
+#include <riscv/starfive/jh71x0_clkc.h>
 
 
 #define	JH7100_CLK_CPUNDBUS_ROOT	0
@@ -133,355 +133,6 @@ __KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.
 
 #define	JH7100_NCLKS			189
 
-struct jh7100_clkc_softc {
-	device_t		sc_dev;
-	bus_space_tag_t		sc_bst;
-	bus_space_handle_t	sc_bsh;
-	int			sc_phandle;
-	struct clk_domain	sc_clkdom;
-	struct jh7100_clkc_clk *sc_clk;
-	size_t			sc_nclks;
-
-	u_int			sc_osclk;
-	u_int			sc_oaclk;
-};
-
-#define	RD4(sc, reg)							\
-	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
-#define	WR4(sc, reg, val)						\
-	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
-
-static void
-jh7100_clkc_update(struct jh7100_clkc_softc * const sc,
-    struct jh7100_clkc_clk *jcc, uint32_t set, uint32_t clr)
-{
-	uint32_t val = RD4(sc, jcc->jcc_reg);
-	val &= ~clr;
-	val |=  set;
-	WR4(sc, jcc->jcc_reg, val);
-}
-
-
-/*
- * FIXED_FACTOR operations
- */
-
-static u_int
-jh7100_clkc_fixed_factor_get_parent_rate(struct clk *clk)
-{
-	struct clk *clk_parent = clk_get_parent(clk);
-	if (clk_parent == NULL)
-		return 0;
-
-	return clk_get_rate(clk_parent);
-}
-
-u_int
-jh7100_clkc_fixed_factor_get_rate(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_FIXED_FACTOR);
-
-	struct jh7100_clkc_fixed_factor * const jcff = &jcc->jcc_ffactor;
-	struct clk *clk = &jcc->jcc_clk;
-
-	uint64_t rate = jh7100_clkc_fixed_factor_get_parent_rate(clk);
-	if (rate == 0)
-		return 0;
-
-	rate *= jcff->jcff_mult;
-	rate /= jcff->jcff_div;
-
-	return rate;
-}
-
-static int
-jh7100_clkc_fixed_factor_set_parent_rate(struct clk *clk, u_int rate)
-{
-	struct clk *clk_parent = clk_get_parent(clk);
-	if (clk_parent == NULL)
-		return ENXIO;
-
-	return clk_set_rate(clk_parent, rate);
-}
-
-int
-jh7100_clkc_fixed_factor_set_rate(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc, u_int rate)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_FIXED_FACTOR);
-
-	struct jh7100_clkc_fixed_factor * const jcff = &jcc->jcc_ffactor;
-	struct clk *clk = &jcc->jcc_clk;
-
-	uint64_t tmp = rate;
-	tmp *= jcff->jcff_div;
-	tmp /= jcff->jcff_mult;
-
-	return jh7100_clkc_fixed_factor_set_parent_rate(clk, tmp);
-}
-
-const char *
-jh7100_clkc_fixed_factor_get_parent(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_FIXED_FACTOR);
-
-	struct jh7100_clkc_fixed_factor * const jcff = &jcc->jcc_ffactor;
-
-	return jcff->jcff_parent;
-}
-
-
-/*
- * MUX operations
- */
-
-int
-jh7100_clkc_mux_set_parent(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc, const char *name)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_MUX);
-
-	struct jh7100_clkc_mux * const jcm = &jcc->jcc_mux;
-
-	size_t i;
-	for (i = 0; i < jcm->jcm_nparents; i++) {
-		if (jcm->jcm_parents[i] != NULL &&
-		    strcmp(jcm->jcm_parents[i], name) == 0)
-			break;
-	}
-	if (i >= jcm->jcm_nparents)
-		return EINVAL;
-
-	uint32_t val = RD4(sc, jcc->jcc_reg);
-	val &= ~JH7100_CLK_MUX_MASK;
-	val |= __SHIFTIN(i, JH7100_CLK_MUX_MASK);
-	WR4(sc, jcc->jcc_reg, val);
-
-	return 0;
-}
-
-
-const char *
-jh7100_clkc_mux_get_parent(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_MUX);
-
-	uint32_t val = RD4(sc, jcc->jcc_reg);
-	size_t pindex = __SHIFTOUT(val, JH7100_CLK_MUX_MASK);
-
-	if (pindex >= jcc->jcc_mux.jcm_nparents)
-		return NULL;
-
-	return jcc->jcc_mux.jcm_parents[pindex];
-}
-
-
-/*
- * GATE operations
- */
-
-int
-jh7100_clkc_gate_enable(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc, int enable)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_GATE);
-
-	jh7100_clkc_update(sc, jcc,
-	    (enable ? JH7100_CLK_ENABLE : 0), JH7100_CLK_ENABLE);
-
-	return 0;
-}
-
-const char *
-jh7100_clkc_gate_get_parent(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_GATE);
-
-	struct jh7100_clkc_gate *jcc_gate = &jcc->jcc_gate;
-
-	return jcc_gate->jcg_parent;
-}
-
-
-/*
- * DIVIDER operations
- */
-
-u_int
-jh7100_clkc_div_get_rate(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_DIV);
-
-	struct clk * const clk = &jcc->jcc_clk;
-	struct clk * const clk_parent = clk_get_parent(clk);
-
-	if (clk_parent == NULL)
-		return 0;
-
-	u_int rate = clk_get_rate(clk_parent);
-	if (rate == 0)
-		return 0;
-
-	uint32_t val = RD4(sc, jcc->jcc_reg);
-	uint32_t div = __SHIFTOUT(val, JH7100_CLK_DIV_MASK);
-
-	return rate / div;
-}
-
-int
-jh7100_clkc_div_set_rate(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc, u_int new_rate)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_DIV);
-
-	struct jh7100_clkc_div * const jcc_div = &jcc->jcc_div;
-	struct clk * const clk = &jcc->jcc_clk;
-	struct clk * const clk_parent = clk_get_parent(clk);
-
-	if (clk_parent == NULL)
-		return ENXIO;
-
-	if (jcc_div->jcd_maxdiv == 0)
-		return ENXIO;
-
-	u_int parent_rate = clk_get_rate(clk_parent);
-
-	if (parent_rate == 0) {
-		return (new_rate == 0) ? 0 : ERANGE;
-	}
-	u_int ratio = howmany(parent_rate, new_rate);
-	u_int div = uimin(ratio, jcc_div->jcd_maxdiv);
-
-	jh7100_clkc_update(sc, jcc,
-	    __SHIFTIN(div, JH7100_CLK_DIV_MASK), JH7100_CLK_DIV_MASK);
-
-	return 0;
-}
-
-const char *
-jh7100_clkc_div_get_parent(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_DIV);
-
-	struct jh7100_clkc_div *jcc_div = &jcc->jcc_div;
-
-	return jcc_div->jcd_parent;
-}
-
-
-/*
- * FRACTIONAL DIVIDER operations
- */
-
-u_int
-jh7100_clkc_fracdiv_get_rate(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_FRACDIV);
-
-	struct clk * const clk = &jcc->jcc_clk;
-	struct clk * const clk_parent = clk_get_parent(clk);
-
-	if (clk_parent == NULL)
-		return 0;
-
-	u_int rate = clk_get_rate(clk_parent);
-	if (rate == 0)
-		return 0;
-
-	uint32_t val = RD4(sc, jcc->jcc_reg);
-	unsigned long div100 =
-	    100UL * __SHIFTOUT(val, JH7100_CLK_INT_MASK) +
-	            __SHIFTOUT(val, JH7100_CLK_FRAC_MASK);
-
-	return (div100 >= JH7100_CLK_FRAC_MIN) ? 100UL * rate / div100 : 0;
-}
-
-int
-jh7100_clkc_fracdiv_set_rate(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc, u_int new_rate)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_FRACDIV);
-
-	struct clk * const clk = &jcc->jcc_clk;
-	struct clk * const clk_parent = clk_get_parent(clk);
-
-	if (clk_parent == NULL)
-		return ENXIO;
-
-	panic("Implement me");
-
-	return 0;
-}
-
-const char *
-jh7100_clkc_fracdiv_get_parent(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_FRACDIV);
-
-	struct jh7100_clkc_fracdiv *jcc_fracdiv = &jcc->jcc_fracdiv;
-
-	return jcc_fracdiv->jcd_parent;
-}
-
-
-/*
- * INV operations
- */
-
-const char *
-jh7100_clkc_inv_get_parent(struct jh7100_clkc_softc *sc,
-    struct jh7100_clkc_clk *jcc)
-{
-	KASSERT(jcc->jcc_type == JH7100CLK_INV);
-
-	struct jh7100_clkc_inv * const jci = &jcc->jcc_inv;
-
-	return jci->jci_parent;
-}
-
-
-static struct jh7100_clkc_clkops jh7100_clkc_gate_ops = {
-	.jcco_enable = jh7100_clkc_gate_enable,
-	.jcco_getparent = jh7100_clkc_gate_get_parent,
-};
-
-static struct jh7100_clkc_clkops jh7100_clkc_div_ops = {
-	.jcco_setrate = jh7100_clkc_div_set_rate,
-	.jcco_getrate = jh7100_clkc_div_get_rate,
-	.jcco_getparent = jh7100_clkc_div_get_parent,
-};
-
-static struct jh7100_clkc_clkops jh7100_clkc_fracdiv_ops = {
-	.jcco_setrate = jh7100_clkc_fracdiv_set_rate,
-	.jcco_getrate = jh7100_clkc_fracdiv_get_rate,
-	.jcco_getparent = jh7100_clkc_fracdiv_get_parent,
-};
-
-struct jh7100_clkc_clkops jh7100_clkc_ffactor_ops = {
-	.jcco_setrate = jh7100_clkc_fixed_factor_set_rate,
-	.jcco_getrate = jh7100_clkc_fixed_factor_get_rate,
-	.jcco_getparent = jh7100_clkc_fixed_factor_get_parent,
-};
-
-
-struct jh7100_clkc_clkops jh7100_clkc_mux_ops = {
-	.jcco_setparent = jh7100_clkc_mux_set_parent,
-	.jcco_getparent = jh7100_clkc_mux_get_parent,
-};
-
-
-struct jh7100_clkc_clkops jh7100_clkc_inv_ops = {
-	.jcco_getparent = jh7100_clkc_inv_get_parent,
-};
-
 
 static const char *cpundbus_root_parents[] = {
 	"osc_sys", "pll0_out", "pll1_out", "pll2_out",
@@ -520,312 +171,125 @@ static const char *gmac_tx_parents[] = {
 };
 
 
-static struct jh7100_clkc_clk jh7100_clocks[] = {
-	JH7100CLKC_FIXED_FACTOR(JH7100_CLK_PLL0_OUT,	"pll0_out",	"osc_sys",	1, 40),
-	JH7100CLKC_FIXED_FACTOR(JH7100_CLK_PLL1_OUT,	"pll1_out",	"osc_sys",	1, 64),
-	JH7100CLKC_FIXED_FACTOR(JH7100_CLK_PLL2_OUT,	"pll2_out",	"pll2_refclk",	1, 55),
-
-	JH7100CLKC_MUX(JH7100_CLK_CPUNDBUS_ROOT,	"cpundbus_root", cpundbus_root_parents),
-	JH7100CLKC_MUX(JH7100_CLK_DSP_ROOT, 		"dsp_root",	 dsp_root_parents),
-	JH7100CLKC_MUX(JH7100_CLK_GMACUSB_ROOT,		"gmacusb_root",	 gmacusb_root_parents),
-	JH7100CLKC_MUX(JH7100_CLK_PERH0_ROOT,		"perh0_root",	 perh0_root_parents),
-	JH7100CLKC_MUX(JH7100_CLK_PERH1_ROOT,   	"perh1_root",	 perh1_root_parents),
-	JH7100CLKC_MUX(JH7100_CLK_PLL2_REF,		"pll2_refclk",	 pll2_refclk_parents),
+static struct jh71x0_clkc_clk jh7100_clocks[] = {
+	JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL0_OUT,	"pll0_out",	"osc_sys",	1, 40),
+	JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL1_OUT,	"pll1_out",	"osc_sys",	1, 64),
+	JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL2_OUT,	"pll2_out",	"pll2_refclk",	1, 55),
+
+	JH71X0CLKC_MUX(JH7100_CLK_CPUNDBUS_ROOT,	"cpundbus_root", cpundbus_root_parents),
+	JH71X0CLKC_MUX(JH7100_CLK_DSP_ROOT, 		"dsp_root",	 dsp_root_parents),
+	JH71X0CLKC_MUX(JH7100_CLK_GMACUSB_ROOT,		"gmacusb_root",  gmacusb_root_parents),
+	JH71X0CLKC_MUX(JH7100_CLK_PERH0_ROOT,   	"perh0_root",    perh0_root_parents),
+	JH71X0CLKC_MUX(JH7100_CLK_PERH1_ROOT,   	"perh1_root",    perh1_root_parents),
+	JH71X0CLKC_MUX(JH7100_CLK_PLL2_REF,		"pll2_refclk",   pll2_refclk_parents),
 
-	JH7100CLKC_MUX(JH7100_CLK_VOUT_ROOT,		"vout_root",	 vout_root_parents),
-	JH7100CLKC_MUX(JH7100_CLK_VOUTBUS_ROOT,		"voutbus_root",	 vout_root_parents),
+	JH71X0CLKC_MUX(JH7100_CLK_VOUT_ROOT,		"vout_root",	 vout_root_parents),
+	JH71X0CLKC_MUX(JH7100_CLK_VOUTBUS_ROOT,		"voutbus_root",	 vout_root_parents),
 
-	JH7100CLKC_MUX_FLAGS(JH7100_CLK_GMAC_TX,	"gmac_tx",	gmac_tx_parents, CLK_SET_RATE_PARENT),
+	JH71X0CLKC_MUX_FLAGS(JH7100_CLK_GMAC_TX,	"gmac_tx",	gmac_tx_parents, CLK_SET_RATE_PARENT),
 
-	JH7100CLKC_MUX(JH7100_CLK_GMAC_RX_PRE,		"gmac_rx_pre",  gmac_rx_pre_parents),
+	JH71X0CLKC_MUX(JH7100_CLK_GMAC_RX_PRE,		"gmac_rx_pre",  gmac_rx_pre_parents),
 
-	JH7100CLKC_DIV(JH7100_CLK_CPUNBUS_ROOT_DIV,	"cpunbus_root_div",
+	JH71X0CLKC_DIV(JH7100_CLK_CPUNBUS_ROOT_DIV,	"cpunbus_root_div",
 									 2, "cpundbus_root"),
-	JH7100CLKC_DIV(JH7100_CLK_PERH0_SRC,		"perh0_src",	 4, "perh0_root"),
-	JH7100CLKC_DIV(JH7100_CLK_PERH1_SRC,		"perh1_src",	 4, "perh1_root"),
+	JH71X0CLKC_DIV(JH7100_CLK_PERH0_SRC,		"perh0_src",	 4, "perh0_root"),
+	JH71X0CLKC_DIV(JH7100_CLK_PERH1_SRC,		"perh1_src",	 4, "perh1_root"),
 
-	JH7100CLKC_DIV(JH7100_CLK_AHB_BUS,		"ahb_bus",	 8, "cpunbus_root_div"),
-	JH7100CLKC_DIV(JH7100_CLK_APB1_BUS,		"apb1_bus",	 8, "ahb_bus"),
-	JH7100CLKC_DIV(JH7100_CLK_APB2_BUS,		"apb2_bus",	 8, "ahb_bus"),
-	JH7100CLKC_DIV(JH7100_CLK_CPU_CORE,		"cpu_core",	 8, "cpunbus_root_div"),
-	JH7100CLKC_DIV(JH7100_CLK_CPU_AXI,		"cpu_axi",	 8, "cpu_core"),
-	JH7100CLKC_DIV(JH7100_CLK_GMAC_ROOT_DIV,	"gmac_root_div", 8, "gmacusb_root"),
-	JH7100CLKC_DIV(JH7100_CLK_DSP_ROOT_DIV,		"dsp_root_div",	 4, "dsp_root"),
-	JH7100CLKC_DIV(JH7100_CLK_SGDMA1P_BUS,		"sgdma1p_bus",	 8, "cpunbus_root_div"),
-
-	JH7100CLKC_DIV(JH7100_CLK_DISPBUS_SRC,		"dispbus_src",	 4, "voutbus_root"),
-
-	JH7100CLKC_DIV(JH7100_CLK_DISP_BUS,		"disp_bus",	 4, "dispbus_src"),
-
-	JH7100CLKC_GATE(JH7100_CLK_UART0_APB,		"uart0_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_UART1_APB,		"uart1_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_UART2_APB,		"uart2_apb",	"apb2_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_UART3_APB,		"uart3_apb",	"apb2_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SGDMA2P_AXI,		"sgdma2p_axi",	"cpu_axi"),
-	JH7100CLKC_GATE(JH7100_CLK_SGDMA2P_AHB,		"sgdma2p_ahb",	"ahb_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SGDMA1P_AXI,		"sgdma1p_axi",	"sgdma1p_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_GPIO_APB,		"gpio_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_I2C0_APB,		"i2c0_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_I2C1_APB,		"i2c1_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_I2C2_APB,		"i2c2_apb",	"apb2_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_I2C3_APB,		"i2c3_apb",	"apb2_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_TRNG_APB,		"trng_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SEC_AHB,		"sec_ahb",	"ahb_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_GMAC_AHB,		"gmac_ahb",	"ahb_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_GMAC_AHB,		"gmac_ahb",	"ahb_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_JPEG_APB,		"jpeg_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_PWM_APB,		"pwm_apb",	"apb2_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_QSPI_AHB,		"qspi_ahb",	"ahb_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SPI0_APB,		"spi0_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SPI1_APB,		"spi1_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SPI2_APB,		"spi2_apb",	"apb2_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SPI3_APB,		"spi3_apb",	"apb2_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SDIO0_AHB,		"sdio0_ahb",	"ahb_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_SDIO1_AHB,		"sdio1_ahb",	"ahb_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_OTP_APB,		"otp_apb",	"apb1_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_DOM7AHB_BUS,		"dom7ahb_bus",  "ahb_bus"),
-	JH7100CLKC_GATE(JH7100_CLK_AUDIO_SRC,		"audio_src",	"audio_div"),
-	JH7100CLKC_GATE(JH7100_CLK_AUDIO_12288,		"audio_12288",	"osc_aud"),
-
-	JH7100CLKC_GATE(JH7100_CLK_DISP_AXI,		"disp_axi",	"disp_bus"),
-
-	JH7100CLKC_GATE(JH7100_CLK_GMAC_RMII,		"gmac_rmii",	"gmac_rmii_ref"),
-
-	JH7100CLKC_GATE(JH7100_CLK_WDTIMER_APB,		"wdtimer_apb",	"apb2_bus"),
-
-	JH7100CLKC_GATEDIV(JH7100_CLK_UART0_CORE,	"uart0_core",		63, "perh1_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_UART1_CORE,	"uart1_core",		63, "perh1_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_UART2_CORE,	"uart2_core",		63, "perh0_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_UART3_CORE,	"uart3_core",		63, "perh0_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_I2C0_CORE,	"i2c0_core",		63, "perh1_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_I2C1_CORE,	"i2c1_core",		63, "perh1_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_I2C2_CORE,	"i2c2_core",		63, "perh0_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_I2C3_CORE,	"i2c3_core",		63, "perh0_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_GMAC_PTP_REF,	"gmac_ptp_refclk",	31, "gmac_root_div"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_VP6_CORE,		"vp6_core",		 4, "dsp_root_div"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_VP6_CORE,		"vp6_core",		 4, "dsp_root_div"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_SPI0_CORE,	"spi0_core",		63, "perh1_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_SPI1_CORE,	"spi1_core",		63, "perh1_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_SPI2_CORE,	"spi2_core",		63, "perh0_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_SPI3_CORE,	"spi3_core",		63, "perh0_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_VP6_CORE,		"vp6_core",		 4, "dsp_root_div"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_SDIO0_CCLKINT,	"sdio0_cclkint",	24, "perh0_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_SDIO1_CCLKINT, 	"sdio1_cclkint",	24, "perh1_src"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_AUDIO_ROOT,	"audio_root",		 8, "pll0_out"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_VOUT_SRC,		"vout_src",		 4, "vout_root"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_WDT_CORE,		"wdt_coreclk",		63, "perh0_src"),
-
-	JH7100CLKC_GATEDIV(JH7100_CLK_GMAC_GTX,		"gmac_gtxclk",		255, "gmac_root_div"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_TX,	"gmac_rmii_txclk",	  8, "gmac_rmii_ref"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_RX,	"gmac_rmii_rxclk",	  8, "gmac_rmii_ref"),
-	JH7100CLKC_GATEDIV(JH7100_CLK_GMAC_TOPHYREF,	"gmac_tophyref",	127, "gmac_root_div"),
-
-	JH7100CLKC_FRACDIV(JH7100_CLK_AUDIO_DIV,	"audio_div",		"audio_root"),
-
-	JH7100CLKC_INV(JH7100_CLK_SDIO0_CCLKINT_INV,	"sdio0_cclkint_inv",	"sdio0_cclkint"),
-	JH7100CLKC_INV(JH7100_CLK_SDIO1_CCLKINT_INV,	"sdio1_cclkint_inv",	"sdio1_cclkint"),
-	JH7100CLKC_INV(JH7100_CLK_GMAC_RX_INV,		"gmac_rx_inv",		"gmac_rx_pre"),
-	JH7100CLKC_INV(JH7100_CLK_GMAC_TX_INV,		"gmac_tx_inv",		"gmac_tx"),
+	JH71X0CLKC_DIV(JH7100_CLK_AHB_BUS,		"ahb_bus",	 8, "cpunbus_root_div"),
+	JH71X0CLKC_DIV(JH7100_CLK_APB1_BUS,		"apb1_bus",	 8, "ahb_bus"),
+	JH71X0CLKC_DIV(JH7100_CLK_APB2_BUS,		"apb2_bus",	 8, "ahb_bus"),
+	JH71X0CLKC_DIV(JH7100_CLK_CPU_CORE,		"cpu_core",	 8, "cpunbus_root_div"),
+	JH71X0CLKC_DIV(JH7100_CLK_CPU_AXI,		"cpu_axi",	 8, "cpu_core"),
+	JH71X0CLKC_DIV(JH7100_CLK_GMAC_ROOT_DIV,	"gmac_root_div", 8, "gmacusb_root"),
+	JH71X0CLKC_DIV(JH7100_CLK_DSP_ROOT_DIV,		"dsp_root_div",	 4, "dsp_root"),
+	JH71X0CLKC_DIV(JH7100_CLK_SGDMA1P_BUS,		"sgdma1p_bus",	 8, "cpunbus_root_div"),
+
+	JH71X0CLKC_DIV(JH7100_CLK_DISPBUS_SRC,		"dispbus_src",	 4, "voutbus_root"),
+
+	JH71X0CLKC_DIV(JH7100_CLK_DISP_BUS,		"disp_bus",	 4, "dispbus_src"),
+
+	JH71X0CLKC_GATE(JH7100_CLK_UART0_APB,		"uart0_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_UART1_APB,		"uart1_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_UART2_APB,		"uart2_apb",	"apb2_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_UART3_APB,		"uart3_apb",	"apb2_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SGDMA2P_AXI,		"sgdma2p_axi",	"cpu_axi"),
+	JH71X0CLKC_GATE(JH7100_CLK_SGDMA2P_AHB,		"sgdma2p_ahb",	"ahb_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SGDMA1P_AXI,		"sgdma1p_axi",	"sgdma1p_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_GPIO_APB,		"gpio_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_I2C0_APB,		"i2c0_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_I2C1_APB,		"i2c1_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_I2C2_APB,		"i2c2_apb",	"apb2_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_I2C3_APB,		"i2c3_apb",	"apb2_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_TRNG_APB,		"trng_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SEC_AHB,		"sec_ahb",	"ahb_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_GMAC_AHB,		"gmac_ahb",	"ahb_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_GMAC_AHB,		"gmac_ahb",	"ahb_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_JPEG_APB,		"jpeg_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_PWM_APB,		"pwm_apb",	"apb2_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_QSPI_AHB,		"qspi_ahb",	"ahb_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SPI0_APB,		"spi0_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SPI1_APB,		"spi1_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SPI2_APB,		"spi2_apb",	"apb2_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SPI3_APB,		"spi3_apb",	"apb2_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SDIO0_AHB,		"sdio0_ahb",	"ahb_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_SDIO1_AHB,		"sdio1_ahb",	"ahb_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_OTP_APB,		"otp_apb",	"apb1_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_DOM7AHB_BUS,		"dom7ahb_bus",  "ahb_bus"),
+	JH71X0CLKC_GATE(JH7100_CLK_AUDIO_SRC,		"audio_src",	"audio_div"),
+	JH71X0CLKC_GATE(JH7100_CLK_AUDIO_12288,		"audio_12288",	"osc_aud"),
+
+	JH71X0CLKC_GATE(JH7100_CLK_DISP_AXI,		"disp_axi",	"disp_bus"),
+
+	JH71X0CLKC_GATE(JH7100_CLK_GMAC_RMII,		"gmac_rmii",	"gmac_rmii_ref"),
+
+	JH71X0CLKC_GATE(JH7100_CLK_WDTIMER_APB,		"wdtimer_apb",	"apb2_bus"),
+
+	JH71X0CLKC_GATEDIV(JH7100_CLK_UART0_CORE,	"uart0_core",		 63, "perh1_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_UART1_CORE,	"uart1_core",		 63, "perh1_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_UART2_CORE,	"uart2_core",		 63, "perh0_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_UART3_CORE,	"uart3_core",		 63, "perh0_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_I2C0_CORE,	"i2c0_core",		 63, "perh1_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_I2C1_CORE,	"i2c1_core",		 63, "perh1_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_I2C2_CORE,	"i2c2_core",		 63, "perh0_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_I2C3_CORE,	"i2c3_core",		 63, "perh0_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_PTP_REF,	"gmac_ptp_refclk",	 31, "gmac_root_div"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE,		"vp6_core",		  4, "dsp_root_div"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE,		"vp6_core",		  4, "dsp_root_div"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_SPI0_CORE,	"spi0_core",		 63, "perh1_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_SPI1_CORE,	"spi1_core",		 63, "perh1_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_SPI2_CORE,	"spi2_core",		 63, "perh0_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_SPI3_CORE,	"spi3_core",		 63, "perh0_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE,		"vp6_core",		  4, "dsp_root_div"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_SDIO0_CCLKINT,	"sdio0_cclkint",	 24, "perh0_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_SDIO1_CCLKINT, 	"sdio1_cclkint",	 24, "perh1_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_AUDIO_ROOT,	"audio_root",		  8, "pll0_out"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_VOUT_SRC,		"vout_src",		  4, "vout_root"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_WDT_CORE,		"wdt_coreclk",		 63, "perh0_src"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_GTX,		"gmac_gtxclk",		255, "gmac_root_div"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_TX,	"gmac_rmii_txclk",	  8, "gmac_rmii_ref"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_RX,	"gmac_rmii_rxclk",	  8, "gmac_rmii_ref"),
+	JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_TOPHYREF,	"gmac_tophyref",	127, "gmac_root_div"),
+
+	JH71X0CLKC_FRACDIV(JH7100_CLK_AUDIO_DIV,	"audio_div",		"audio_root"),
+
+	JH71X0CLKC_INV(JH7100_CLK_SDIO0_CCLKINT_INV,	"sdio0_cclkint_inv",	"sdio0_cclkint"),
+	JH71X0CLKC_INV(JH7100_CLK_SDIO1_CCLKINT_INV,	"sdio1_cclkint_inv",	"sdio1_cclkint"),
+	JH71X0CLKC_INV(JH7100_CLK_GMAC_RX_INV,		"gmac_rx_inv",		"gmac_rx_pre"),
+	JH71X0CLKC_INV(JH7100_CLK_GMAC_TX_INV,		"gmac_tx_inv",		"gmac_tx"),
 };
 
+
 static const struct device_compatible_entry compat_data[] = {
 	{ .compat = "starfive,jh7100-clkgen" },
 	DEVICE_COMPAT_EOL
 };
 
-static struct clk *
-jh7100_clkc_get(void *priv, const char *name)
-{
-	struct jh7100_clkc_softc * const sc = priv;
-
-	for (u_int id = 0; id < sc->sc_nclks; id++) {
-		struct jh7100_clkc_clk * const jcc = &sc->sc_clk[id];
-
-		if (strcmp(name, jcc->jcc_clk.name) == 0) {
-			return &jcc->jcc_clk;
-		}
-	}
-
-	return NULL;
-}
-
-static void
-jh7100_clkc_put(void *priv, struct clk *clk)
-{
-}
-
-static int
-jh7100_clkc_set_rate(void *priv, struct clk *clk, u_int rate)
-{
-	struct jh7100_clkc_softc * const sc = priv;
-	struct jh7100_clkc_clk * const jcc =
-	    container_of(clk, struct jh7100_clkc_clk, jcc_clk);
-
-	if (clk->flags & CLK_SET_RATE_PARENT) {
-		struct clk *clk_parent = clk_get_parent(clk);
-		if (clk_parent == NULL) {
-			aprint_debug("%s: no parent for %s\n", __func__,
-			    jcc->jcc_clk.name);
-			return ENXIO;
-		}
-		return clk_set_rate(clk_parent, rate);
-	}
-
-	if (jcc->jcc_ops->jcco_setrate)
-		return jcc->jcc_ops->jcco_setrate(sc, jcc, rate);
-
-	return ENXIO;
-}
-
-static u_int
-jh7100_clkc_get_rate(void *priv, struct clk *clk)
-{
-	struct jh7100_clkc_softc * const sc = priv;
-	struct jh7100_clkc_clk * const jcc =
-	    container_of(clk, struct jh7100_clkc_clk, jcc_clk);
-
-	if (jcc->jcc_ops->jcco_getrate)
-		return jcc->jcc_ops->jcco_getrate(sc, jcc);
-
-	struct clk * const clk_parent = clk_get_parent(clk);
-	if (clk_parent == NULL) {
-		aprint_debug("%s: no parent for %s\n", __func__,
-		    jcc->jcc_clk.name);
-		return 0;
-	}
-
-	return clk_get_rate(clk_parent);
-}
-
-static int
-jh7100_clkc_enable(void *priv, struct clk *clk)
-{
-	struct jh7100_clkc_softc * const sc = priv;
-	struct jh7100_clkc_clk * const jcc =
-	    container_of(clk, struct jh7100_clkc_clk, jcc_clk);
-
-	struct clk * const clk_parent = clk_get_parent(clk);
-	if (clk_parent != NULL) {
-		int error = clk_enable(clk_parent);
-		if (error != 0)
-			return error;
-	}
-
-	switch (jcc->jcc_type) {
-	case JH7100CLK_GATE:
-		jh7100_clkc_update(sc, jcc, JH7100_CLK_ENABLE, 0);
-		break;
-
-	case JH7100CLK_DIV: {
-		struct jh7100_clkc_div * const jcc_div = &jcc->jcc_div;
-		if (jcc_div->jcd_flags & JH7100CLKC_DIV_GATE) {
-			jh7100_clkc_update(sc, jcc, JH7100_CLK_ENABLE, 0);
-			break;
-		}
-		break;
-	    }
-
-	case JH7100CLK_FIXED_FACTOR:
-	case JH7100CLK_MUX:
-	case JH7100CLK_INV:
-		break;
-
-	default:
-		printf("%s: type %d\n", __func__, jcc->jcc_type);
-		return ENXIO;
-	}
-	return 0;
-}
-
-static int
-jh7100_clkc_disable(void *priv, struct clk *clk)
-{
-	struct jh7100_clkc_softc * const sc = priv;
-	struct jh7100_clkc_clk * const jcc =
-	    container_of(clk, struct jh7100_clkc_clk, jcc_clk);
-
-	switch (jcc->jcc_type) {
-	case JH7100CLK_GATE:
-		jh7100_clkc_update(sc, jcc, JH7100_CLK_ENABLE, 0);
-		return 0;
-
-	default:
-		return ENXIO;
-	}
-}
-
-
-static struct jh7100_clkc_clk *
-jh7100_clkc_clock_find(struct jh7100_clkc_softc *sc, const char *name)
-{
-	for (size_t id = 0; id < sc->sc_nclks; id++) {
-		struct jh7100_clkc_clk * const jcc = &sc->sc_clk[id];
-
-		if (jcc->jcc_clk.name == NULL)
-			continue;
-		if (strcmp(jcc->jcc_clk.name, name) == 0)
-			return jcc;
-	}
-
-	return NULL;
-}
-
-
-static int
-jh7100_clkc_set_parent(void *priv, struct clk *clk,
-    struct clk *clk_parent)
-{
-	struct jh7100_clkc_softc * const sc = priv;
-	struct jh7100_clkc_clk * const jcc =
-	    container_of(clk, struct jh7100_clkc_clk, jcc_clk);
-
-	if (jcc->jcc_ops->jcco_setparent == NULL)
-		return EINVAL;
-
-	return jcc->jcc_ops->jcco_setparent(sc, jcc, clk_parent->name);
-}
-
-
-static struct clk *
-jh7100_clkc_get_parent(void *priv, struct clk *clk)
-{
-	struct jh7100_clkc_softc * const sc = priv;
-	struct jh7100_clkc_clk * const jcc =
-	    container_of(clk, struct jh7100_clkc_clk, jcc_clk);
-
-	if (jcc->jcc_ops->jcco_getparent == NULL)
-		return NULL;
-
-	const char *parent = jcc->jcc_ops->jcco_getparent(sc, jcc);
-	if (parent == NULL)
-		return NULL;
-
-	struct jh7100_clkc_clk *jcc_parent = jh7100_clkc_clock_find(sc, parent);
-	if (jcc_parent != NULL)
-		return &jcc_parent->jcc_clk;
-
-	/* No parent in this domain, try FDT */
-	return fdtbus_clock_get(sc->sc_phandle, parent);
-}
-
-
-static const struct clk_funcs jh7100_clkc_funcs = {
-	.get = jh7100_clkc_get,
-	.put = jh7100_clkc_put,
-	.set_rate = jh7100_clkc_set_rate,
-	.get_rate = jh7100_clkc_get_rate,
-	.enable = jh7100_clkc_enable,
-	.disable = jh7100_clkc_disable,
-	.set_parent = jh7100_clkc_set_parent,
-	.get_parent = jh7100_clkc_get_parent,
-};
-
 
 static struct clk *
 jh7100_clkc_fdt_decode(device_t dev, int phandle, const void *data,
     size_t len)
 {
-	struct jh7100_clkc_softc * const sc = device_private(dev);
+	struct jh71x0_clkc_softc * const sc = device_private(dev);
 
 	if (len != 4)
 		return NULL;
@@ -834,7 +298,7 @@ jh7100_clkc_fdt_decode(device_t dev, int
 	if (id >= sc->sc_nclks)
 		return NULL;
 
-	if (sc->sc_clk[id].jcc_type == JH7100CLK_UNKNOWN) {
+	if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN) {
 		printf("Unknown clock %d\n", id);
 		return NULL;
 	}
@@ -856,7 +320,7 @@ jh7100_clkc_match(device_t parent, cfdat
 static void
 jh7100_clkc_attach(device_t parent, device_t self, void *aux)
 {
-	struct jh7100_clkc_softc * const sc = device_private(self);
+	struct jh71x0_clkc_softc * const sc = device_private(self);
 	struct fdt_attach_args * const faa = aux;
 	const int phandle = faa->faa_phandle;
 	bus_addr_t addr;
@@ -883,23 +347,23 @@ jh7100_clkc_attach(device_t parent, devi
 		aprint_error(": couldn't get osc_sys\n");
 		return;
 	}
-	sc->sc_osclk = clk_get_rate(osclk);
+	u_int osclk_rate = clk_get_rate(osclk);
 
 	struct clk * const oaclk = fdtbus_clock_get(phandle, "osc_aud");
 	if (oaclk == NULL) {
 		aprint_error(": couldn't get osc_aud\n");
 		return;
 	}
-	sc->sc_oaclk = clk_get_rate(oaclk);
+	u_int oaclk_rate = clk_get_rate(oaclk);
 
 	sc->sc_clkdom.name = device_xname(self);
-	sc->sc_clkdom.funcs = &jh7100_clkc_funcs;
+	sc->sc_clkdom.funcs = &jh71x0_clkc_funcs;
 	sc->sc_clkdom.priv = sc;
 
 	sc->sc_clk = jh7100_clocks;
 	sc->sc_nclks = __arraycount(jh7100_clocks);
 	for (size_t id = 0; id < sc->sc_nclks; id++) {
-		if (sc->sc_clk[id].jcc_type == JH7100CLK_UNKNOWN)
+		if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
 			continue;
 
 		sc->sc_clk[id].jcc_clk.domain = &sc->sc_clkdom;
@@ -908,10 +372,10 @@ jh7100_clkc_attach(device_t parent, devi
 
 	aprint_naive("\n");
 	aprint_normal(": JH7100 (OSC0 %u Hz, OSC1 %u Hz)\n",
-	    sc->sc_osclk, sc->sc_oaclk);
+	    osclk_rate, oaclk_rate);
 
 	for (size_t id = 0; id < sc->sc_nclks; id++) {
-		if (sc->sc_clk[id].jcc_type == JH7100CLK_UNKNOWN)
+		if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
 			continue;
 
 		struct clk * const clk = &sc->sc_clk[id].jcc_clk;
@@ -923,5 +387,5 @@ jh7100_clkc_attach(device_t parent, devi
 	fdtbus_register_clock_controller(self, phandle, &jh7100_clkc_fdt_funcs);
 }
 
-CFATTACH_DECL_NEW(jh7100_clkc, sizeof(struct jh7100_clkc_softc),
-	jh7100_clkc_match, jh7100_clkc_attach, NULL, NULL);
+CFATTACH_DECL_NEW(jh7100_clkc, sizeof(struct jh71x0_clkc_softc),
+    jh7100_clkc_match, jh7100_clkc_attach, NULL, NULL);

Added files:

Index: src/sys/arch/riscv/starfive/jh71x0_clkc.c
diff -u /dev/null src/sys/arch/riscv/starfive/jh71x0_clkc.c:1.1
--- /dev/null	Sat Jul 27 07:09:50 2024
+++ src/sys/arch/riscv/starfive/jh71x0_clkc.c	Sat Jul 27 07:09:50 2024
@@ -0,0 +1,588 @@
+/* $NetBSD: jh71x0_clkc.c,v 1.1 2024/07/27 07:09:50 skrll Exp $ */
+
+/*-
+ * Copyright (c) 2023 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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>
+__KERNEL_RCSID(0, "$NetBSD: jh71x0_clkc.c,v 1.1 2024/07/27 07:09:50 skrll Exp $");
+
+#include <sys/param.h>
+
+#include <sys/bus.h>
+#include <sys/device.h>
+
+#include <dev/clk/clk_backend.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <riscv/starfive/jh71x0_clkc.h>
+
+#define	RD4(sc, reg)							\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define	WR4(sc, reg, val)						\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+
+static void
+jh71x0_clkc_update(struct jh71x0_clkc_softc * const sc,
+    struct jh71x0_clkc_clk *jcc, uint32_t set, uint32_t clr)
+{
+	// lock
+	uint32_t val = RD4(sc, jcc->jcc_reg);
+	val &= ~clr;
+	val |=  set;
+	WR4(sc, jcc->jcc_reg, val);
+}
+
+/*
+ * FIXED_FACTOR operations
+ */
+
+static u_int
+jh71x0_clkc_fixed_factor_get_parent_rate(struct clk *clk)
+{
+	struct clk *clk_parent = clk_get_parent(clk);
+	if (clk_parent == NULL)
+		return 0;
+
+	return clk_get_rate(clk_parent);
+}
+
+u_int
+jh71x0_clkc_fixed_factor_get_rate(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_FIXED_FACTOR);
+
+	struct jh71x0_clkc_fixed_factor * const jcff = &jcc->jcc_ffactor;
+	struct clk *clk = &jcc->jcc_clk;
+
+	uint64_t rate = jh71x0_clkc_fixed_factor_get_parent_rate(clk);
+	if (rate == 0)
+		return 0;
+
+	rate *= jcff->jcff_mult;
+	rate /= jcff->jcff_div;
+
+	return rate;
+}
+
+static int
+jh71x0_clkc_fixed_factor_set_parent_rate(struct clk *clk, u_int rate)
+{
+	struct clk *clk_parent = clk_get_parent(clk);
+	if (clk_parent == NULL)
+		return ENXIO;
+
+	return clk_set_rate(clk_parent, rate);
+}
+
+int
+jh71x0_clkc_fixed_factor_set_rate(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc, u_int rate)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_FIXED_FACTOR);
+
+	struct jh71x0_clkc_fixed_factor * const jcff = &jcc->jcc_ffactor;
+	struct clk *clk = &jcc->jcc_clk;
+
+
+	uint64_t tmp = rate;
+	tmp *= jcff->jcff_div;
+	tmp /= jcff->jcff_mult;
+
+	return jh71x0_clkc_fixed_factor_set_parent_rate(clk, tmp);
+}
+
+const char *
+jh71x0_clkc_fixed_factor_get_parent(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_FIXED_FACTOR);
+
+	struct jh71x0_clkc_fixed_factor * const jcff = &jcc->jcc_ffactor;
+
+	return jcff->jcff_parent;
+}
+
+
+/*
+ * MUX operations
+ */
+
+int
+jh71x0_clkc_mux_set_parent(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc, const char *name)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_MUX);
+
+	struct jh71x0_clkc_mux * const jcm = &jcc->jcc_mux;
+
+	size_t i;
+	for (i = 0; i < jcm->jcm_nparents; i++) {
+		if (jcm->jcm_parents[i] != NULL &&
+		    strcmp(jcm->jcm_parents[i], name) == 0)
+			break;
+	}
+	if (i >= jcm->jcm_nparents)
+		return EINVAL;
+
+	uint32_t val = RD4(sc, jcc->jcc_reg);
+	val &= ~JH71X0_CLK_MUX_MASK;
+	val |= __SHIFTIN(i, JH71X0_CLK_MUX_MASK);
+	WR4(sc, jcc->jcc_reg, val);
+
+	return 0;
+}
+
+
+const char *
+jh71x0_clkc_mux_get_parent(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_MUX);
+
+	uint32_t val = RD4(sc, jcc->jcc_reg);
+	size_t pindex = __SHIFTOUT(val, JH71X0_CLK_MUX_MASK);
+
+	if (pindex >= jcc->jcc_mux.jcm_nparents)
+		return NULL;
+
+	return jcc->jcc_mux.jcm_parents[pindex];
+}
+
+
+/*
+ * GATE operations
+ */
+
+int
+jh71x0_clkc_gate_enable(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc, int enable)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_GATE);
+
+	jh71x0_clkc_update(sc, jcc,
+	    (enable ? JH71X0_CLK_ENABLE : 0), JH71X0_CLK_ENABLE);
+
+	return 0;
+}
+
+const char *
+jh71x0_clkc_gate_get_parent(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_GATE);
+
+	struct jh71x0_clkc_gate *jcc_gate = &jcc->jcc_gate;
+
+	return jcc_gate->jcg_parent;
+}
+
+
+/*
+ * DIVIDER operations
+ */
+
+u_int
+jh71x0_clkc_div_get_rate(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_DIV);
+
+	struct clk * const clk = &jcc->jcc_clk;
+	struct clk * const clk_parent = clk_get_parent(clk);
+
+	if (clk_parent == NULL)
+		return 0;
+
+	u_int rate = clk_get_rate(clk_parent);
+	if (rate == 0)
+		return 0;
+
+	uint32_t val = RD4(sc, jcc->jcc_reg);
+	uint32_t div = __SHIFTOUT(val, JH71X0_CLK_DIV_MASK);
+
+	return rate / div;
+}
+
+int
+jh71x0_clkc_div_set_rate(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc, u_int new_rate)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_DIV);
+
+	struct jh71x0_clkc_div * const jcc_div = &jcc->jcc_div;
+	struct clk * const clk = &jcc->jcc_clk;
+	struct clk * const clk_parent = clk_get_parent(clk);
+
+	if (clk_parent == NULL)
+		return ENXIO;
+
+	if (jcc_div->jcd_maxdiv == 0)
+		return ENXIO;
+
+	u_int parent_rate = clk_get_rate(clk_parent);
+
+	if (parent_rate == 0) {
+		return (new_rate == 0) ? 0 : ERANGE;
+	}
+	u_int ratio = howmany(parent_rate, new_rate);
+	u_int div = uimin(ratio, jcc_div->jcd_maxdiv);
+
+	jh71x0_clkc_update(sc, jcc,
+	    __SHIFTIN(div, JH71X0_CLK_DIV_MASK), JH71X0_CLK_DIV_MASK);
+
+	return 0;
+}
+
+const char *
+jh71x0_clkc_div_get_parent(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_DIV);
+
+	struct jh71x0_clkc_div *jcc_div = &jcc->jcc_div;
+
+	return jcc_div->jcd_parent;
+}
+
+
+/*
+ * FRACTIONAL DIVIDER operations
+ */
+
+u_int
+jh71x0_clkc_fracdiv_get_rate(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_FRACDIV);
+
+	struct clk * const clk = &jcc->jcc_clk;
+	struct clk * const clk_parent = clk_get_parent(clk);
+
+	if (clk_parent == NULL)
+		return 0;
+
+
+	u_int rate = clk_get_rate(clk_parent);
+	if (rate == 0)
+		return 0;
+
+	uint32_t val = RD4(sc, jcc->jcc_reg);
+	unsigned long div100 =
+	    100UL * __SHIFTOUT(val, JH71X0_CLK_INT_MASK) +
+	            __SHIFTOUT(val, JH71X0_CLK_FRAC_MASK);
+
+	return (div100 >= JH71X0_CLK_FRAC_MIN) ? 100UL * rate / div100 : 0;
+}
+
+int
+jh71x0_clkc_fracdiv_set_rate(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc, u_int new_rate)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_FRACDIV);
+
+//	struct jh71x0_clkc_fracdiv * const jcc_fracdiv = &jcc->jcc_fracdiv;
+	struct clk * const clk = &jcc->jcc_clk;
+	struct clk * const clk_parent = clk_get_parent(clk);
+
+	if (clk_parent == NULL)
+		return ENXIO;
+
+#if 0
+	if (jcc_div->jcd_maxdiv == 0)
+		return ENXIO;
+
+	u_int parent_rate = clk_get_rate(clk_parent);
+
+	if (parent_rate == 0) {
+		return (new_rate == 0) ? 0 : ERANGE;
+	}
+	u_int ratio = howmany(parent_rate, new_rate);
+	u_int div = uimin(ratio, jcc_div->jcd_maxdiv);
+
+	jh71x0_clkc_update(sc, jcc,
+	    __SHIFTIN(div, JH71X0_CLK_DIV_MASK), JH71X0_CLK_DIV_MASK);
+#endif
+
+	return 0;
+}
+
+const char *
+jh71x0_clkc_fracdiv_get_parent(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_FRACDIV);
+
+	struct jh71x0_clkc_fracdiv *jcc_fracdiv = &jcc->jcc_fracdiv;
+
+	return jcc_fracdiv->jcd_parent;
+}
+
+
+/*
+ * INV operations
+ */
+const char *
+jh71x0_clkc_inv_get_parent(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc)
+{
+	KASSERT(jcc->jcc_type == JH71X0CLK_INV);
+
+	struct jh71x0_clkc_inv * const jci = &jcc->jcc_inv;
+
+	return jci->jci_parent;
+}
+
+
+struct jh71x0_clkc_clkops jh71x0_clkc_gate_ops = {
+	.jcco_enable = jh71x0_clkc_gate_enable,
+	.jcco_getparent = jh71x0_clkc_gate_get_parent,
+};
+
+struct jh71x0_clkc_clkops jh71x0_clkc_div_ops = {
+	.jcco_setrate = jh71x0_clkc_div_set_rate,
+	.jcco_getrate = jh71x0_clkc_div_get_rate,
+	.jcco_getparent = jh71x0_clkc_div_get_parent,
+};
+
+struct jh71x0_clkc_clkops jh71x0_clkc_fracdiv_ops = {
+	.jcco_setrate = jh71x0_clkc_fracdiv_set_rate,
+	.jcco_getrate = jh71x0_clkc_fracdiv_get_rate,
+	.jcco_getparent = jh71x0_clkc_fracdiv_get_parent,
+};
+
+struct jh71x0_clkc_clkops jh71x0_clkc_ffactor_ops = {
+	.jcco_setrate = jh71x0_clkc_fixed_factor_set_rate,
+	.jcco_getrate = jh71x0_clkc_fixed_factor_get_rate,
+	.jcco_getparent = jh71x0_clkc_fixed_factor_get_parent,
+};
+
+
+struct jh71x0_clkc_clkops jh71x0_clkc_mux_ops = {
+	.jcco_setparent = jh71x0_clkc_mux_set_parent,
+	.jcco_getparent = jh71x0_clkc_mux_get_parent,
+};
+
+
+struct jh71x0_clkc_clkops jh71x0_clkc_inv_ops = {
+	.jcco_getparent = jh71x0_clkc_inv_get_parent,
+};
+
+static struct clk *
+jh71x0_clkc_get(void *priv, const char *name)
+{
+	struct jh71x0_clkc_softc * const sc = priv;
+
+	for (u_int id = 0; id < sc->sc_nclks; id++) {
+		struct jh71x0_clkc_clk * const jcc = &sc->sc_clk[id];
+
+		if (strcmp(name, jcc->jcc_clk.name) == 0) {
+			return &jcc->jcc_clk;
+		}
+	}
+
+	return NULL;
+}
+
+static void
+jh71x0_clkc_put(void *priv, struct clk *clk)
+{
+}
+
+
+static int
+jh71x0_clkc_set_rate(void *priv, struct clk *clk, u_int rate)
+{
+	struct jh71x0_clkc_softc * const sc = priv;
+	struct jh71x0_clkc_clk * const jcc =
+	    container_of(clk, struct jh71x0_clkc_clk, jcc_clk);
+
+	if (clk->flags & CLK_SET_RATE_PARENT) {
+		struct clk *clk_parent = clk_get_parent(clk);
+		if (clk_parent == NULL) {
+			aprint_debug("%s: no parent for %s\n", __func__,
+			    jcc->jcc_clk.name);
+			return ENXIO;
+		}
+		return clk_set_rate(clk_parent, rate);
+	}
+
+	if (jcc->jcc_ops->jcco_setrate)
+		return jcc->jcc_ops->jcco_setrate(sc, jcc, rate);
+
+	return ENXIO;
+}
+
+static u_int
+jh71x0_clkc_get_rate(void *priv, struct clk *clk)
+{
+	struct jh71x0_clkc_softc * const sc = priv;
+	struct jh71x0_clkc_clk * const jcc =
+	    container_of(clk, struct jh71x0_clkc_clk, jcc_clk);
+
+	if (jcc->jcc_ops->jcco_getrate)
+		return jcc->jcc_ops->jcco_getrate(sc, jcc);
+
+	struct clk * const clk_parent = clk_get_parent(clk);
+	if (clk_parent == NULL) {
+		aprint_debug("%s: no parent for %s\n", __func__,
+		    jcc->jcc_clk.name);
+		return 0;
+	}
+
+	return clk_get_rate(clk_parent);
+}
+
+static int
+jh71x0_clkc_enable(void *priv, struct clk *clk)
+{
+	struct jh71x0_clkc_softc * const sc = priv;
+	struct jh71x0_clkc_clk * const jcc =
+	    container_of(clk, struct jh71x0_clkc_clk, jcc_clk);
+
+	struct clk * const clk_parent = clk_get_parent(clk);
+	if (clk_parent != NULL) {
+		int error = clk_enable(clk_parent);
+		if (error != 0)
+			return error;
+	}
+
+	switch (jcc->jcc_type) {
+	case JH71X0CLK_GATE:
+		jh71x0_clkc_update(sc, jcc, JH71X0_CLK_ENABLE, 0);
+		break;
+
+	case JH71X0CLK_DIV: {
+		struct jh71x0_clkc_div * const jcc_div = &jcc->jcc_div;
+		if (jcc_div->jcd_flags & JH71X0CLKC_DIV_GATE) {
+			jh71x0_clkc_update(sc, jcc, JH71X0_CLK_ENABLE, 0);
+			break;
+		}
+		break;
+	    }
+
+	case JH71X0CLK_FIXED_FACTOR:
+	case JH71X0CLK_MUX:
+	case JH71X0CLK_INV:
+		break;
+
+	default:
+		printf("%s: type %d\n", __func__, jcc->jcc_type);
+		return ENXIO;
+	}
+	return 0;
+}
+
+static int
+jh71x0_clkc_disable(void *priv, struct clk *clk)
+{
+	struct jh71x0_clkc_softc * const sc = priv;
+	struct jh71x0_clkc_clk * const jcc =
+	    container_of(clk, struct jh71x0_clkc_clk, jcc_clk);
+
+	switch (jcc->jcc_type) {
+	case JH71X0CLK_GATE:
+		jh71x0_clkc_update(sc, jcc, JH71X0_CLK_ENABLE, 0);
+		return 0;
+
+	default:
+		return ENXIO;
+	}
+}
+
+
+
+static struct jh71x0_clkc_clk *
+jh71x0_clkc_clock_find(struct jh71x0_clkc_softc *sc, const char *name)
+{
+	for (size_t id = 0; id < sc->sc_nclks; id++) {
+		struct jh71x0_clkc_clk * const jcc = &sc->sc_clk[id];
+
+		if (jcc->jcc_clk.name == NULL)
+			continue;
+		if (strcmp(jcc->jcc_clk.name, name) == 0)
+			return jcc;
+	}
+
+	return NULL;
+}
+
+
+
+static int
+jh71x0_clkc_set_parent(void *priv, struct clk *clk,
+    struct clk *clk_parent)
+{
+	struct jh71x0_clkc_softc * const sc = priv;
+	struct jh71x0_clkc_clk * const jcc =
+	    container_of(clk, struct jh71x0_clkc_clk, jcc_clk);
+
+	if (jcc->jcc_ops->jcco_setparent == NULL)
+		return EINVAL;
+
+	return jcc->jcc_ops->jcco_setparent(sc, jcc, clk_parent->name);
+}
+
+
+static struct clk *
+jh71x0_clkc_get_parent(void *priv, struct clk *clk)
+{
+	struct jh71x0_clkc_softc * const sc = priv;
+	struct jh71x0_clkc_clk * const jcc =
+	    container_of(clk, struct jh71x0_clkc_clk, jcc_clk);
+
+	if (jcc->jcc_ops->jcco_getparent == NULL)
+		return NULL;
+
+	const char *parent = jcc->jcc_ops->jcco_getparent(sc, jcc);
+	if (parent == NULL)
+		return NULL;
+
+	struct jh71x0_clkc_clk *jcc_parent = jh71x0_clkc_clock_find(sc, parent);
+	if (jcc_parent != NULL)
+		return &jcc_parent->jcc_clk;
+
+	/* No parent in this domain, try FDT */
+	return fdtbus_clock_get(sc->sc_phandle, parent);
+}
+
+
+const struct clk_funcs jh71x0_clkc_funcs = {
+	.get = jh71x0_clkc_get,
+	.put = jh71x0_clkc_put,
+	.set_rate = jh71x0_clkc_set_rate,
+	.get_rate = jh71x0_clkc_get_rate,
+	.enable = jh71x0_clkc_enable,
+	.disable = jh71x0_clkc_disable,
+	.set_parent = jh71x0_clkc_set_parent,
+	.get_parent = jh71x0_clkc_get_parent,
+};
+
Index: src/sys/arch/riscv/starfive/jh71x0_clkc.h
diff -u /dev/null src/sys/arch/riscv/starfive/jh71x0_clkc.h:1.1
--- /dev/null	Sat Jul 27 07:09:50 2024
+++ src/sys/arch/riscv/starfive/jh71x0_clkc.h	Sat Jul 27 07:09:50 2024
@@ -0,0 +1,304 @@
+/* $NetBSD: jh71x0_clkc.h,v 1.1 2024/07/27 07:09:50 skrll Exp $ */
+
+/*-
+ * Copyright (c) 2023 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#ifndef _STARFIVE_JH71X0CLKC_H
+#define _STARFIVE_JH71X0CLKC_H
+
+#include <dev/clk/clk_backend.h>
+#include <dev/fdt/syscon.h>
+
+/*
+ * Each clock has a 32-bit register indexed from the register base with
+ * the following bit field definitions depending on type.
+ */
+
+/* register fields */
+#define JH71X0_CLK_ENABLE	__BIT(31)
+#define JH71X0_CLK_INVERT	__BIT(30)
+#define JH71X0_CLK_MUX_MASK	__BITS(27, 24)
+#define JH71X0_CLK_DIV_MASK	__BITS(23, 0)
+#define JH71X0_CLK_FRAC_MASK	__BITS(15, 8)
+#define JH71X0_CLK_INT_MASK	__BITS(7, 0)
+
+/* fractional divider min/max */
+#define JH71X0_CLK_FRAC_MIN	100UL
+#define JH71X0_CLK_FRAC_MAX	(26600UL - 1)
+
+
+struct jh71x0_clkc_clk;
+
+struct jh71x0_clkc_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	int			sc_phandle;
+	struct clk_domain	sc_clkdom;
+	struct jh71x0_clkc_clk *sc_clk;
+	size_t			sc_nclks;
+};
+
+enum jh71x0_clkc_clktype {
+	JH71X0CLK_UNKNOWN,
+	JH71X0CLK_FIXED_FACTOR,
+	JH71X0CLK_GATE,
+	JH71X0CLK_DIV,
+	JH71X0CLK_FRACDIV,
+	JH71X0CLK_MUX,
+	JH71X0CLK_INV,
+};
+
+/*
+ * Fixed-factor clocks
+ */
+
+struct jh71x0_clkc_fixed_factor {
+	const char *	jcff_parent;
+	u_int		jcff_div;
+	u_int		jcff_mult;
+};
+
+u_int	jh71x0_clkc_fixed_factor_get_rate(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *);
+int	jh71x0_clkc_fixed_factor_set_rate(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *, u_int);
+const char *
+	jh71x0_clkc_fixed_factor_get_parent(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *);
+
+extern struct jh71x0_clkc_clkops jh71x0_clkc_ffactor_ops;
+
+#define	JH71X0CLKC_FIXED_FACTOR(_id, _name, _parent, _div, _mult)	      \
+	[_id] = {							      \
+		.jcc_type = JH71X0CLK_FIXED_FACTOR,			      \
+		.jcc_clk.name = (_name),				      \
+		.jcc_ffactor.jcff_parent = (_parent),			      \
+		.jcc_ffactor.jcff_div = (_div),				      \
+		.jcc_ffactor.jcff_mult = (_mult),			      \
+		.jcc_ops = &jh71x0_clkc_ffactor_ops,			      \
+	}
+
+/*
+ * Gate clocks
+ */
+
+struct jh71x0_clkc_gate {
+	const char	*jcg_parent;
+};
+
+int	jh71x0_clkc_gate_enable(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *, int);
+const char *
+	jh71x0_clkc_gate_get_parent(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *);
+
+extern struct jh71x0_clkc_clkops jh71x0_clkc_gate_ops;
+
+#define	JH71X0CLKC_GATE(_id, _name, _pname)				      \
+	[_id] = {							      \
+		.jcc_type = JH71X0CLK_GATE,				      \
+		.jcc_clk = {						      \
+			.name = (_name),				      \
+			.flags = CLK_SET_RATE_PARENT,			      \
+		},							      \
+		.jcc_reg = (_id) * sizeof(uint32_t),			      \
+		.jcc_gate.jcg_parent = (_pname),			      \
+		.jcc_ops = &jh71x0_clkc_gate_ops,			      \
+	}
+
+/*
+ * Divider clocks
+ */
+
+struct jh71x0_clkc_div {
+	bus_size_t	jcd_reg;
+	const char *	jcd_parent;
+	uint32_t	jcd_maxdiv;
+	uint32_t	jcd_flags;
+#define	JH71X0CLKC_DIV_GATE	__BIT(0)
+};
+
+u_int	jh71x0_clkc_div_get_rate(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *);
+int	jh71x0_clkc_div_set_rate(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *, u_int);
+const char *
+	jh71x0_clkc_div_get_parent(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *);
+
+extern struct jh71x0_clkc_clkops jh71x0_clkc_div_ops;
+
+#define	JH71X0CLKC_DIV_FLAGS(_id, _name, _maxdiv, _parent, _flags)	      \
+	[_id] = {							      \
+		.jcc_type = JH71X0CLK_DIV,				      \
+		.jcc_clk = {						      \
+			.name = (_name),				      \
+		},							      \
+		.jcc_reg = (_id) * sizeof(uint32_t),			      \
+		.jcc_div = {						      \
+			.jcd_parent = (_parent),			      \
+			.jcd_maxdiv = (_maxdiv),			      \
+			.jcd_flags = (_flags),				      \
+		},							      \
+		.jcc_ops = &jh71x0_clkc_div_ops,			      \
+	}
+
+#define	JH71X0CLKC_DIV(_id, _n, _m, _p)		  			      \
+    JH71X0CLKC_DIV_FLAGS((_id), (_n), (_m), (_p), 0)
+
+#define	JH71X0CLKC_GATEDIV(_id, _n, _m, _p)				      \
+    JH71X0CLKC_DIV_FLAGS((_id), (_n), (_m), (_p), JH71X0CLKC_DIV_GATE)
+
+/*
+ * Fractional Divider clocks
+ */
+
+struct jh71x0_clkc_fracdiv {
+	bus_size_t	jcd_reg;
+	const char *	jcd_parent;
+	uint32_t	jcd_flags;
+#define	JH71X0CLKC_DIV_GATE	__BIT(0)
+};
+
+u_int	jh71x0_clkc_fracdiv_get_rate(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *);
+int	jh71x0_clkc_fracdiv_set_rate(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *, u_int);
+const char *
+	jh71x0_clkc_fracdiv_get_parent(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *);
+
+extern struct jh71x0_clkc_clkops jh71x0_clkc_fracdiv_ops;
+
+#define	JH71X0CLKC_FRACDIV(_id, _name, _parent)				      \
+	[_id] = {							      \
+		.jcc_type = JH71X0CLK_FRACDIV,				      \
+		.jcc_clk = {						      \
+			.name = (_name),				      \
+		},							      \
+		.jcc_reg = (_id) * sizeof(uint32_t),			      \
+		.jcc_fracdiv = {					      \
+			.jcd_parent = (_parent),			      \
+		},							      \
+		.jcc_ops = &jh71x0_clkc_fracdiv_ops,			      \
+	}
+
+
+/*
+ * Mux clocks
+ */
+
+struct jh71x0_clkc_mux {
+	size_t		jcm_nparents;
+	const char **	jcm_parents;
+};
+
+int	jh71x0_clkc_mux_set_parent(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *, const char *);
+const char *
+	jh71x0_clkc_mux_get_parent(struct jh71x0_clkc_softc *,
+	    struct jh71x0_clkc_clk *);
+
+extern struct jh71x0_clkc_clkops jh71x0_clkc_mux_ops;
+
+#define	JH71X0CLKC_MUX_FLAGS(_id, _name, _parents, _cflags)		      \
+	[_id] = {							      \
+		.jcc_type = JH71X0CLK_MUX,				      \
+		.jcc_clk = {						      \
+			.name = (_name),				      \
+			.flags = (_cflags),				      \
+		},							      \
+		.jcc_reg = (_id) * sizeof(uint32_t),			      \
+		.jcc_mux = {						      \
+			.jcm_parents = (_parents),			      \
+			.jcm_nparents = __arraycount(_parents),		      \
+		},							      \
+		.jcc_ops = &jh71x0_clkc_mux_ops,			      \
+	}
+
+#define	JH71X0CLKC_MUX(_id, _n, _p)		  			      \
+    JH71X0CLKC_MUX_FLAGS((_id), (_n), (_p), 0)
+
+struct jh71x0_clkc_inv {
+	const char *	jci_parent;
+};
+
+const char *
+jh71x0_clkc_inv_get_parent(struct jh71x0_clkc_softc *sc,
+    struct jh71x0_clkc_clk *jcc);
+
+extern struct jh71x0_clkc_clkops jh71x0_clkc_inv_ops;
+
+#define	JH71X0CLKC_INV(_id, _name, _pname)				      \
+	[_id] = {							      \
+		.jcc_type = JH71X0CLK_INV,				      \
+		.jcc_clk = {						      \
+			.name = (_name),				      \
+			.flags = CLK_SET_RATE_PARENT,			      \
+		},							      \
+		.jcc_reg = (_id) * sizeof(uint32_t),			      \
+		.jcc_inv.jci_parent = (_pname),				      \
+		.jcc_ops = &jh71x0_clkc_inv_ops,			      \
+	}
+
+
+struct jh71x0_clkc_clkops {
+
+	int		(*jcco_enable)(struct jh71x0_clkc_softc *,
+			    struct jh71x0_clkc_clk *, int);
+	u_int		(*jcco_getrate)(struct jh71x0_clkc_softc *,
+			    struct jh71x0_clkc_clk *);
+	int		(*jcco_setrate)(struct jh71x0_clkc_softc *,
+			    struct jh71x0_clkc_clk *, u_int);
+	const char *    (*jcco_getparent)(struct jh71x0_clkc_softc *,
+			    struct jh71x0_clkc_clk *);
+	int		(*jcco_setparent)(struct jh71x0_clkc_softc *,
+			    struct jh71x0_clkc_clk *, const char *);
+};
+
+
+struct jh71x0_clkc_clk {
+	struct clk		 		jcc_clk;
+	enum jh71x0_clkc_clktype 		jcc_type;
+	bus_size_t				jcc_reg;
+	union {
+		struct jh71x0_clkc_gate		jcc_gate;
+		struct jh71x0_clkc_div		jcc_div;
+		struct jh71x0_clkc_fracdiv	jcc_fracdiv;
+		struct jh71x0_clkc_fixed_factor jcc_ffactor;
+		struct jh71x0_clkc_mux		jcc_mux;
+		struct jh71x0_clkc_inv		jcc_inv;
+	};
+	struct jh71x0_clkc_clkops *		jcc_ops;
+};
+
+extern const struct clk_funcs jh71x0_clkc_funcs;
+
+#endif

Reply via email to