All clocks seem to share a common format:

 struct starfive_clk {
        u32 divisor : 24;       /* LSB */
        u32 mux : 6;
        u32 invert : 1;
        u32 enable : 1;         /* MSB */
 };

There is no documentation, what the acceptable divisor values are, but
we could already register gates and muxes, do so for now until
documentation is available.

The bulk of this code has been machine-generated by parsing the macros
in the vendor U-Boot <asm/arch-vic7100/clkgen_ctrl_macro.h>.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 drivers/clk/Makefile                        |   1 +
 drivers/clk/starfive/Makefile               |   3 +
 drivers/clk/starfive/clk.h                  |  64 ++++
 drivers/clk/starfive/jh7100-clkgen.c        | 363 ++++++++++++++++++++
 include/dt-bindings/clock/starfive-jh7100.h | 203 +++++++++++
 5 files changed, 634 insertions(+)
 create mode 100644 drivers/clk/starfive/Makefile
 create mode 100644 drivers/clk/starfive/clk.h
 create mode 100644 drivers/clk/starfive/jh7100-clkgen.c
 create mode 100644 include/dt-bindings/clock/starfive-jh7100.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index b0be8d1bd89a..499df2fe392b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_MACH_MIPS_LOONGSON)+= loongson/
 obj-$(CONFIG_ARCH_LAYERSCAPE)  += clk-qoric.o
 obj-y                          += analogbits/
 obj-$(CONFIG_CLK_SIFIVE)       += sifive/
+obj-$(CONFIG_SOC_STARFIVE)     += starfive/
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
new file mode 100644
index 000000000000..4e9bf7f2ba83
--- /dev/null
+++ b/drivers/clk/starfive/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SOC_STARFIVE_JH71XX) += jh7100-clkgen.o
diff --git a/drivers/clk/starfive/clk.h b/drivers/clk/starfive/clk.h
new file mode 100644
index 000000000000..cfbf116dcb78
--- /dev/null
+++ b/drivers/clk/starfive/clk.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef STARFIVE_CLK_H_
+#define STARFIVE_CLK_H_
+
+#include <linux/clk.h>
+
+#define STARFIVE_CLK_ENABLE_SHIFT      31
+#define STARFIVE_CLK_INVERT_SHIFT      30
+#define STARFIVE_CLK_MUX_SHIFT         24
+
+static inline struct clk *starfive_clk_underspecifid(const char *name, const 
char *parent)
+{
+       /*
+        * TODO With documentation available, all users of this functions can be
+        * migrated to one of the above or to a clk_fixed_factor with
+        * appropriate factor
+        */
+       return clk_fixed_factor(name, parent, 1, 1, 0);
+}
+
+static inline struct clk *starfive_clk_divider(const char *name, const char 
*parent,
+               void __iomem *reg, u8 width)
+{
+       return starfive_clk_underspecifid(name, parent);
+}
+
+static inline struct clk *starfive_clk_gate(const char *name, const char 
*parent,
+               void __iomem *reg)
+{
+       return clk_gate(name, parent, reg, STARFIVE_CLK_ENABLE_SHIFT, 
CLK_SET_RATE_PARENT, 0);
+}
+
+static inline struct clk *starfive_clk_divider_table(const char *name,
+               const char *parent, void __iomem *reg, u8 width,
+               const struct clk_div_table *table)
+{
+       return clk_divider_table(name, parent, CLK_SET_RATE_PARENT, reg, 0,
+                                width, table, 0);
+}
+
+static inline struct clk *starfive_clk_gated_divider(const char *name,
+               const char *parent, void __iomem *reg, u8 width)
+{
+       /* TODO divider part */
+       return clk_gate(name, parent, reg, STARFIVE_CLK_ENABLE_SHIFT, 
CLK_SET_RATE_PARENT, 0);
+}
+
+static inline struct clk *starfive_clk_gate_dis(const char *name, const char 
*parent,
+               void __iomem *reg)
+{
+       return clk_gate_inverted(name, parent, reg, STARFIVE_CLK_INVERT_SHIFT, 
CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *starfive_clk_mux(const char *name, void __iomem *reg,
+               u8 width, const char * const *parents, u8 num_parents)
+{
+       return clk_mux(name, 0, reg, STARFIVE_CLK_MUX_SHIFT, width, parents, 
num_parents, 0);
+}
+
+#endif
diff --git a/drivers/clk/starfive/jh7100-clkgen.c 
b/drivers/clk/starfive/jh7100-clkgen.c
new file mode 100644
index 000000000000..df5353e8e624
--- /dev/null
+++ b/drivers/clk/starfive/jh7100-clkgen.c
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+
+#include "clk.h"
+
+
+static const char *cpundbus_root_sels[4] = {
+       [0] = "osc_sys",
+       [1] = "pll0_out",
+       [2] = "pll1_out",
+       [3] = "pll2_out",
+};
+
+static const char *dla_root_sels[4] = {
+       [0] = "osc_sys",
+       [1] = "pll1_out",
+       [2] = "pll2_out",
+       [3] = "dummy",
+};
+
+static const char *dsp_root_sels[4] = {
+       [0] = "osc_sys",
+       [1] = "pll0_out",
+       [2] = "pll1_out",
+       [3] = "pll2_out",
+};
+
+static const char *gmacusb_root_sels[4] = {
+       [0] = "osc_sys",
+       [1] = "pll0_out",
+       [2] = "pll2_out",
+       [3] = "dummy",
+};
+
+static const char *perh0_root_sels[2] = {
+       [0] = "osc_sys",
+       [1] = "pll0_out",
+};
+
+static const char *perh1_root_sels[2] = {
+       [0] = "osc_sys",
+       [1] = "pll2_out",
+};
+
+static const char *vin_root_sels[4] = {
+       [0] = "osc_sys",
+       [1] = "pll1_out",
+       [2] = "pll2_out",
+       [3] = "dummy",
+};
+
+static const char *vout_root_sels[4] = {
+       [0] = "osc_aud",
+       [1] = "pll0_out",
+       [2] = "pll2_out",
+       [3] = "dummy",
+};
+
+static const char *cdechifi4_root_sels[4] = {
+       [0] = "osc_sys",
+       [1] = "pll1_out",
+       [2] = "pll2_out",
+       [3] = "dummy",
+};
+
+static const char *cdec_root_sels[4] = {
+       [0] = "osc_sys",
+       [1] = "pll0_out",
+       [2] = "pll1_out",
+       [3] = "dummy",
+};
+
+static const char *voutbus_root_sels[4] = {
+       [0] = "osc_aud",
+       [1] = "pll0_out",
+       [2] = "pll2_out",
+       [3] = "dummy",
+};
+
+static const char *pll2_refclk_sels[2] = {
+       [0] = "osc_sys",
+       [1] = "osc_aud",
+};
+
+static const char *ddrc0_sels[4] = {
+       [0] = "ddrosc_div2",
+       [1] = "ddrpll_div2",
+       [2] = "ddrpll_div4",
+       [3] = "ddrpll_div8",
+};
+
+static const char *ddrc1_sels[4] = {
+       [0] = "ddrosc_div2",
+       [1] = "ddrpll_div2",
+       [2] = "ddrpll_div4",
+       [3] = "ddrpll_div8",
+};
+
+static const char *nne_bus_sels[2] = {
+       [0] = "cpu_axi",
+       [1] = "nnebus_src1",
+};
+
+static const char *usbphy_25m_sels[2] = {
+       [0] = "osc_sys",
+       [1] = "usbphy_plldiv25m",
+};
+
+static const char *gmac_tx_sels[4] = {
+       [0] = "gmac_gtxclk",
+       [1] = "gmac_mii_txclk",
+       [2] = "gmac_rmii_txclk",
+       [3] = "dummy",
+};
+
+static const char *gmac_rx_pre_sels[2] = {
+       [0] = "gmac_gr_mii_rxclk",
+       [1] = "gmac_rmii_rxclk",
+};
+
+static struct clk *clks[CLK_END];
+
+/* assume osc_sys as direct parent for clocks of yet unknown lineage */
+#define UNKNOWN "osc_sys"
+
+static void starfive_clkgen_init(struct device_node *np, void __iomem *base)
+{
+       clks[CLK_OSC_SYS]               = of_clk_get_by_name(np, "osc_sys");
+       clks[CLK_OSC_AUD]               = of_clk_get_by_name(np, "osc_aud");
+       clks[CLK_PLL0_OUT]              = 
starfive_clk_underspecifid("pll0_out", "osc_sys");
+       clks[CLK_PLL1_OUT]              = 
starfive_clk_underspecifid("pll1_out", "osc_sys");
+       clks[CLK_PLL2_OUT]              = 
starfive_clk_underspecifid("pll2_out", "pll2_refclk");
+       clks[CLK_CPUNDBUS_ROOT]         = starfive_clk_mux("cpundbus_root", 
base + 0x0, 2, cpundbus_root_sels, ARRAY_SIZE(cpundbus_root_sels));
+       clks[CLK_DLA_ROOT]              = starfive_clk_mux("dla_root",  base + 
0x4, 2, dla_root_sels, ARRAY_SIZE(dla_root_sels));
+       clks[CLK_DSP_ROOT]              = starfive_clk_mux("dsp_root",  base + 
0x8, 2, dsp_root_sels, ARRAY_SIZE(dsp_root_sels));
+       clks[CLK_GMACUSB_ROOT]          = starfive_clk_mux("gmacusb_root",      
base + 0xC, 2, gmacusb_root_sels, ARRAY_SIZE(gmacusb_root_sels));
+       clks[CLK_PERH0_ROOT]            = starfive_clk_mux("perh0_root",        
base + 0x10, 1, perh0_root_sels, ARRAY_SIZE(perh0_root_sels));
+       clks[CLK_PERH1_ROOT]            = starfive_clk_mux("perh1_root",        
base + 0x14, 1, perh1_root_sels, ARRAY_SIZE(perh1_root_sels));
+       clks[CLK_VIN_ROOT]              = starfive_clk_mux("vin_root",  base + 
0x18, 2, vin_root_sels, ARRAY_SIZE(vin_root_sels));
+       clks[CLK_VOUT_ROOT]             = starfive_clk_mux("vout_root", base + 
0x1C, 2, vout_root_sels, ARRAY_SIZE(vout_root_sels));
+       clks[CLK_AUDIO_ROOT]            = 
starfive_clk_gated_divider("audio_root",              UNKNOWN,        base + 
0x20, 4);
+       clks[CLK_CDECHIFI4_ROOT]        = starfive_clk_mux("cdechifi4_root",    
base + 0x24, 2, cdechifi4_root_sels, ARRAY_SIZE(cdechifi4_root_sels));
+       clks[CLK_CDEC_ROOT]             = starfive_clk_mux("cdec_root", base + 
0x28, 2, cdec_root_sels, ARRAY_SIZE(cdec_root_sels));
+       clks[CLK_VOUTBUS_ROOT]          = starfive_clk_mux("voutbus_root",      
base + 0x2C, 2, voutbus_root_sels, ARRAY_SIZE(voutbus_root_sels));
+       clks[CLK_CPUNBUS_ROOT_DIV]      = 
starfive_clk_divider("cpunbus_root_div",              "cpunbus_root", base + 
0x30, 2);
+       clks[CLK_DSP_ROOT_DIV]          = starfive_clk_divider("dsp_root_div",  
        "dsp_root",     base + 0x34, 3);
+       clks[CLK_PERH0_SRC]             = starfive_clk_divider("perh0_src",     
        "perh0_root",   base + 0x38, 3);
+       clks[CLK_PERH1_SRC]             = starfive_clk_divider("perh1_src",     
        "perh1_root",   base + 0x3C, 3);
+       clks[CLK_PLL0_TESTOUT]          = 
starfive_clk_gated_divider("pll0_testout",            "pll0_out",     base + 
0x40, 5);
+       clks[CLK_PLL1_TESTOUT]          = 
starfive_clk_gated_divider("pll1_testout",            "pll1_out",     base + 
0x44, 5);
+       clks[CLK_PLL2_TESTOUT]          = 
starfive_clk_gated_divider("pll2_testout",            "pll2_out",     base + 
0x48, 5);
+       clks[CLK_PLL2_REF]              = starfive_clk_mux("pll2_refclk",       
base + 0x4C, 1, pll2_refclk_sels, ARRAY_SIZE(pll2_refclk_sels));
+       clks[CLK_CPU_CORE]              = starfive_clk_divider("cpu_core",      
        UNKNOWN,        base + 0x50, 4);
+       clks[CLK_CPU_AXI]               = starfive_clk_divider("cpu_axi",       
        UNKNOWN,        base + 0x54, 4);
+       clks[CLK_AHB_BUS]               = starfive_clk_divider("ahb_bus",       
        UNKNOWN,        base + 0x58, 4);
+       clks[CLK_APB1_BUS]              = starfive_clk_divider("apb1_bus",      
        UNKNOWN,        base + 0x5C, 4);
+       clks[CLK_APB2_BUS]              = starfive_clk_divider("apb2_bus",      
        UNKNOWN,        base + 0x60, 4);
+       clks[CLK_DOM3AHB_BUS]           = starfive_clk_gate("dom3ahb_bus",      
        UNKNOWN,        base + 0x64);
+       clks[CLK_DOM7AHB_BUS]           = starfive_clk_gate("dom7ahb_bus",      
        UNKNOWN,        base + 0x68);
+       clks[CLK_U74_CORE0]             = starfive_clk_gate("u74_core0",        
        UNKNOWN,        base + 0x6C);
+       clks[CLK_U74_CORE1]             = 
starfive_clk_gated_divider("u74_core1",               "",     base + 0x70, 4);
+       clks[CLK_U74_AXI]               = starfive_clk_gate("u74_axi",          
UNKNOWN,        base + 0x74);
+       clks[CLK_U74RTC_TOGGLE]         = starfive_clk_gate("u74rtc_toggle",    
        UNKNOWN,        base + 0x78);
+       clks[CLK_SGDMA2P_AXI]           = starfive_clk_gate("sgdma2p_axi",      
        UNKNOWN,        base + 0x7C);
+       clks[CLK_DMA2PNOC_AXI]          = starfive_clk_gate("dma2pnoc_axi",     
        UNKNOWN,        base + 0x80);
+       clks[CLK_SGDMA2P_AHB]           = starfive_clk_gate("sgdma2p_ahb",      
        UNKNOWN,        base + 0x84);
+       clks[CLK_DLA_BUS]               = starfive_clk_divider("dla_bus",       
        UNKNOWN,        base + 0x88, 3);
+       clks[CLK_DLA_AXI]               = starfive_clk_gate("dla_axi",          
UNKNOWN,        base + 0x8C);
+       clks[CLK_DLANOC_AXI]            = starfive_clk_gate("dlanoc_axi",       
        UNKNOWN,        base + 0x90);
+       clks[CLK_DLA_APB]               = starfive_clk_gate("dla_apb",          
UNKNOWN,        base + 0x94);
+       clks[CLK_VP6_CORE]              = 
starfive_clk_gated_divider("vp6_core",                UNKNOWN,        base + 
0x98, 3);
+       clks[CLK_VP6BUS_SRC]            = starfive_clk_divider("vp6bus_src",    
        UNKNOWN,        base + 0x9C, 3);
+       clks[CLK_VP6_AXI]               = starfive_clk_gated_divider("vp6_axi", 
        UNKNOWN,        base + 0xA0, 3);
+       clks[CLK_VCDECBUS_SRC]          = starfive_clk_divider("vcdecbus_src",  
        UNKNOWN,        base + 0xA4, 3);
+       clks[CLK_VDEC_BUS]              = starfive_clk_divider("vdec_bus",      
        UNKNOWN,        base + 0xA8, 4);
+       clks[CLK_VDEC_AXI]              = starfive_clk_gate("vdec_axi",         
UNKNOWN,        base + 0xAC);
+       clks[CLK_VDECBRG_MAIN]          = starfive_clk_gate("vdecbrg_mainclk",  
        UNKNOWN,        base + 0xB0);
+       clks[CLK_VDEC_BCLK]             = 
starfive_clk_gated_divider("vdec_bclk",               UNKNOWN,        base + 
0xB4, 4);
+       clks[CLK_VDEC_CCLK]             = 
starfive_clk_gated_divider("vdec_cclk",               UNKNOWN,        base + 
0xB8, 4);
+       clks[CLK_VDEC_APB]              = starfive_clk_gate("vdec_apb",         
UNKNOWN,        base + 0xBC);
+       clks[CLK_JPEG_AXI]              = 
starfive_clk_gated_divider("jpeg_axi",                UNKNOWN,        base + 
0xC0, 4);
+       clks[CLK_JPEG_CCLK]             = 
starfive_clk_gated_divider("jpeg_cclk",               UNKNOWN,        base + 
0xC4, 4);
+       clks[CLK_JPEG_APB]              = starfive_clk_gate("jpeg_apb",         
UNKNOWN,        base + 0xC8);
+       clks[CLK_GC300_2X]              = 
starfive_clk_gated_divider("gc300_2x",                UNKNOWN,        base + 
0xCC, 4);
+       clks[CLK_GC300_AHB]             = starfive_clk_gate("gc300_ahb",        
        UNKNOWN,        base + 0xD0);
+       clks[CLK_JPCGC300_AXIBUS]       = 
starfive_clk_divider("jpcgc300_axibus",               UNKNOWN,        base + 
0xD4, 4);
+       clks[CLK_GC300_AXI]             = starfive_clk_gate("gc300_axi",        
        UNKNOWN,        base + 0xD8);
+       clks[CLK_JPCGC300_MAIN]         = starfive_clk_gate("jpcgc300_mainclk", 
        UNKNOWN,        base + 0xDC);
+       clks[CLK_VENC_BUS]              = starfive_clk_divider("venc_bus",      
        UNKNOWN,        base + 0xE0, 4);
+       clks[CLK_VENC_AXI]              = starfive_clk_gate("venc_axi",         
UNKNOWN,        base + 0xE4);
+       clks[CLK_VENCBRG_MAIN]          = starfive_clk_gate("vencbrg_mainclk",  
        UNKNOWN,        base + 0xE8);
+       clks[CLK_VENC_BCLK]             = 
starfive_clk_gated_divider("venc_bclk",               UNKNOWN,        base + 
0xEC, 4);
+       clks[CLK_VENC_CCLK]             = 
starfive_clk_gated_divider("venc_cclk",               UNKNOWN,        base + 
0xF0, 4);
+       clks[CLK_VENC_APB]              = starfive_clk_gate("venc_apb",         
UNKNOWN,        base + 0xF4);
+       clks[CLK_DDRPLL_DIV2]           = 
starfive_clk_gated_divider("ddrpll_div2",             UNKNOWN,        base + 
0xF8, 2);
+       clks[CLK_DDRPLL_DIV4]           = 
starfive_clk_gated_divider("ddrpll_div4",             UNKNOWN,        base + 
0xFC, 2);
+       clks[CLK_DDRPLL_DIV8]           = 
starfive_clk_gated_divider("ddrpll_div8",             UNKNOWN,        base + 
0x100, 2);
+       clks[CLK_DDROSC_DIV2]           = 
starfive_clk_gated_divider("ddrosc_div2",             UNKNOWN,        base + 
0x104, 2);
+       clks[CLK_DDRC0]                 = starfive_clk_mux("ddrc0",     base + 
0x108, 2, ddrc0_sels, ARRAY_SIZE(ddrc0_sels));
+       clks[CLK_DDRC1]                 = starfive_clk_mux("ddrc1",     base + 
0x10C, 2, ddrc1_sels, ARRAY_SIZE(ddrc1_sels));
+       clks[CLK_DDRPHY_APB]            = starfive_clk_gate("ddrphy_apb",       
        UNKNOWN,        base + 0x110);
+       clks[CLK_NOC_ROB]               = starfive_clk_divider("noc_rob",       
        UNKNOWN,        base + 0x114, 4);
+       clks[CLK_NOC_COG]               = starfive_clk_divider("noc_cog",       
        UNKNOWN,        base + 0x118, 4);
+       clks[CLK_NNE_AHB]               = starfive_clk_gate("nne_ahb",          
UNKNOWN,        base + 0x11C);
+       clks[CLK_NNEBUS_SRC1]           = starfive_clk_divider("nnebus_src1",   
        UNKNOWN,        base + 0x120, 3);
+       clks[CLK_NNE_BUS]               = starfive_clk_mux("nne_bus",   base + 
0x124, 2, nne_bus_sels, ARRAY_SIZE(nne_bus_sels));
+       clks[CLK_NNE_AXI]               = starfive_clk_gate("nne_axi",  
UNKNOWN, base + 0x128);
+       clks[CLK_NNENOC_AXI]            = starfive_clk_gate("nnenoc_axi",       
        UNKNOWN,        base + 0x12C);
+       clks[CLK_DLASLV_AXI]            = starfive_clk_gate("dlaslv_axi",       
        UNKNOWN,        base + 0x130);
+       clks[CLK_DSPX2C_AXI]            = starfive_clk_gate("dspx2c_axi",       
        UNKNOWN,        base + 0x134);
+       clks[CLK_HIFI4_SRC]             = starfive_clk_divider("hifi4_src",     
        UNKNOWN,        base + 0x138, 3);
+       clks[CLK_HIFI4_COREFREE]        = 
starfive_clk_divider("hifi4_corefree",                UNKNOWN,        base + 
0x13C, 4);
+       clks[CLK_HIFI4_CORE]            = starfive_clk_gate("hifi4_core",       
        UNKNOWN,        base + 0x140);
+       clks[CLK_HIFI4_BUS]             = starfive_clk_divider("hifi4_bus",     
        UNKNOWN,        base + 0x144, 4);
+       clks[CLK_HIFI4_AXI]             = starfive_clk_gate("hifi4_axi",        
        UNKNOWN,        base + 0x148);
+       clks[CLK_HIFI4NOC_AXI]          = starfive_clk_gate("hifi4noc_axi",     
        UNKNOWN,        base + 0x14C);
+       clks[CLK_SGDMA1P_BUS]           = starfive_clk_divider("sgdma1p_bus",   
        UNKNOWN,        base + 0x150, 4);
+       clks[CLK_SGDMA1P_AXI]           = starfive_clk_gate("sgdma1p_axi",      
        UNKNOWN,        base + 0x154);
+       clks[CLK_DMA1P_AXI]             = starfive_clk_gate("dma1p_axi",        
        UNKNOWN,        base + 0x158);
+       clks[CLK_X2C_AXI]               = starfive_clk_gated_divider("x2c_axi", 
        UNKNOWN,        base + 0x15C, 4);
+       clks[CLK_USB_BUS]               = starfive_clk_divider("usb_bus",       
        UNKNOWN,        base + 0x160, 4);
+       clks[CLK_USB_AXI]               = starfive_clk_gate("usb_axi",          
UNKNOWN,        base + 0x164);
+       clks[CLK_USBNOC_AXI]            = starfive_clk_gate("usbnoc_axi",       
        UNKNOWN,        base + 0x168);
+       clks[CLK_USBPHY_ROOTDIV]        = 
starfive_clk_divider("usbphy_rootdiv",                UNKNOWN,        base + 
0x16C, 3);
+       clks[CLK_USBPHY_125M]           = 
starfive_clk_gated_divider("usbphy_125m",             UNKNOWN,        base + 
0x170, 4);
+       clks[CLK_USBPHY_PLLDIV25M]      = 
starfive_clk_gated_divider("usbphy_plldiv25m",                UNKNOWN,        
base + 0x174, 6);
+       clks[CLK_USBPHY_25M]            = starfive_clk_mux("usbphy_25m",        
base + 0x178, 1, usbphy_25m_sels, ARRAY_SIZE(usbphy_25m_sels));
+       clks[CLK_AUDIO_DIV]             = starfive_clk_divider("audio_div",     
        UNKNOWN,        base + 0x17C, 18);
+       clks[CLK_AUDIO_SRC]             = starfive_clk_gate("audio_src",        
        UNKNOWN,        base + 0x180);
+       clks[CLK_AUDIO_12288]           = starfive_clk_gate("audio_12288",      
        UNKNOWN,        base + 0x184);
+       clks[CLK_VIN_SRC]               = starfive_clk_gated_divider("vin_src", 
        UNKNOWN,        base + 0x188, 3);
+       clks[CLK_ISP0_BUS]              = starfive_clk_divider("isp0_bus",      
        UNKNOWN,        base + 0x18C, 4);
+       clks[CLK_ISP0_AXI]              = starfive_clk_gate("isp0_axi",         
UNKNOWN,        base + 0x190);
+       clks[CLK_ISP0NOC_AXI]           = starfive_clk_gate("isp0noc_axi",      
        UNKNOWN,        base + 0x194);
+       clks[CLK_ISPSLV_AXI]            = starfive_clk_gate("ispslv_axi",       
        UNKNOWN,        base + 0x198);
+       clks[CLK_ISP1_BUS]              = starfive_clk_divider("isp1_bus",      
        UNKNOWN,        base + 0x19C, 4);
+       clks[CLK_ISP1_AXI]              = starfive_clk_gate("isp1_axi",         
UNKNOWN,        base + 0x1A0);
+       clks[CLK_ISP1NOC_AXI]           = starfive_clk_gate("isp1noc_axi",      
        UNKNOWN,        base + 0x1A4);
+       clks[CLK_VIN_BUS]               = starfive_clk_divider("vin_bus",       
        UNKNOWN,        base + 0x1A8, 4);
+       clks[CLK_VIN_AXI]               = starfive_clk_gate("vin_axi",          
UNKNOWN,        base + 0x1AC);
+       clks[CLK_VINNOC_AXI]            = starfive_clk_gate("vinnoc_axi",       
        UNKNOWN,        base + 0x1B0);
+       clks[CLK_VOUT_SRC]              = 
starfive_clk_gated_divider("vout_src",                UNKNOWN,        base + 
0x1B4, 3);
+       clks[CLK_DISPBUS_SRC]           = starfive_clk_divider("dispbus_src",   
        UNKNOWN,        base + 0x1B8, 3);
+       clks[CLK_DISP_BUS]              = starfive_clk_divider("disp_bus",      
        UNKNOWN,        base + 0x1BC, 3);
+       clks[CLK_DISP_AXI]              = starfive_clk_gate("disp_axi",         
UNKNOWN,        base + 0x1C0);
+       clks[CLK_DISPNOC_AXI]           = starfive_clk_gate("dispnoc_axi",      
        UNKNOWN,        base + 0x1C4);
+       clks[CLK_SDIO0_AHB]             = starfive_clk_gate("sdio0_ahb",        
        UNKNOWN,        base + 0x1C8);
+       clks[CLK_SDIO0_CCLKINT]         = 
starfive_clk_gated_divider("sdio0_cclkint",           UNKNOWN,        base + 
0x1CC, 5);
+       clks[CLK_SDIO0_CCLKINT_INV]     = 
starfive_clk_gate_dis("sdio0_cclkint_inv",            UNKNOWN,        base + 
0x1D0);
+       clks[CLK_SDIO1_AHB]             = starfive_clk_gate("sdio1_ahb",        
        UNKNOWN,        base + 0x1D4);
+       clks[CLK_SDIO1_CCLKINT]         = 
starfive_clk_gated_divider("sdio1_cclkint",           UNKNOWN,        base + 
0x1D8, 5);
+       clks[CLK_SDIO1_CCLKINT_INV]     = 
starfive_clk_gate_dis("sdio1_cclkint_inv",            UNKNOWN,        base + 
0x1DC);
+       clks[CLK_GMAC_AHB]              = starfive_clk_gate("gmac_ahb",         
UNKNOWN,        base + 0x1E0);
+       clks[CLK_GMAC_ROOT_DIV]         = starfive_clk_divider("gmac_root_div", 
        UNKNOWN,        base + 0x1E4, 4);
+       clks[CLK_GMAC_PTP_REF]          = 
starfive_clk_gated_divider("gmac_ptp_refclk",         UNKNOWN,        base + 
0x1E8, 5);
+       clks[CLK_GMAC_GTX]              = 
starfive_clk_gated_divider("gmac_gtxclk",             UNKNOWN,        base + 
0x1EC, 8);
+       clks[CLK_GMAC_RMII_TX]          = 
starfive_clk_gated_divider("gmac_rmii_txclk",         UNKNOWN,        base + 
0x1F0, 4);
+       clks[CLK_GMAC_RMII_RX]          = 
starfive_clk_gated_divider("gmac_rmii_rxclk",         UNKNOWN,        base + 
0x1F4, 4);
+       clks[CLK_GMAC_TX]               = starfive_clk_mux("gmac_tx",   base + 
0x1F8, 2, gmac_tx_sels, ARRAY_SIZE(gmac_tx_sels));
+       clks[CLK_GMAC_TX_INV]           = starfive_clk_gate_dis("gmac_tx_inv",  
        UNKNOWN,        base + 0x1FC);
+       clks[CLK_GMAC_RX_PRE]           = starfive_clk_mux("gmac_rx_pre",       
base + 0x200, 1, gmac_rx_pre_sels, ARRAY_SIZE(gmac_rx_pre_sels));
+       clks[CLK_GMAC_RX_INV]           = starfive_clk_gate_dis("gmac_rx_inv",  
        UNKNOWN,        base + 0x204);
+       clks[CLK_GMAC_RMII]             = starfive_clk_gate("gmac_rmii",        
        UNKNOWN,        base + 0x208);
+       clks[CLK_GMAC_TOPHYREF]         = 
starfive_clk_gated_divider("gmac_tophyref",           UNKNOWN,        base + 
0x20C, 7);
+       clks[CLK_SPI2AHB_AHB]           = starfive_clk_gate("spi2ahb_ahb",      
        UNKNOWN,        base + 0x210);
+       clks[CLK_SPI2AHB_CORE]          = 
starfive_clk_gated_divider("spi2ahb_core",            UNKNOWN,        base + 
0x214, 5);
+       clks[CLK_EZMASTER_AHB]          = starfive_clk_gate("ezmaster_ahb",     
        UNKNOWN,        base + 0x218);
+       clks[CLK_E24_AHB]               = starfive_clk_gate("e24_ahb",          
UNKNOWN,        base + 0x21C);
+       clks[CLK_E24RTC_TOGGLE]         = starfive_clk_gate("e24rtc_toggle",    
        UNKNOWN,        base + 0x220);
+       clks[CLK_QSPI_AHB]              = starfive_clk_gate("qspi_ahb",         
UNKNOWN,        base + 0x224);
+       clks[CLK_QSPI_APB]              = starfive_clk_gate("qspi_apb",         
UNKNOWN,        base + 0x228);
+       clks[CLK_QSPI_REF]              = 
starfive_clk_gated_divider("qspi_refclk",             UNKNOWN,        base + 
0x22C, 5);
+       clks[CLK_SEC_AHB]               = starfive_clk_gate("sec_ahb",          
UNKNOWN,        base + 0x230);
+       clks[CLK_AES]                   = starfive_clk_gate("aes_clk",          
UNKNOWN,        base + 0x234);
+       clks[CLK_SHA]                   = starfive_clk_gate("sha_clk",          
UNKNOWN,        base + 0x238);
+       clks[CLK_PKA]                   = starfive_clk_gate("pka_clk",          
UNKNOWN,        base + 0x23C);
+       clks[CLK_TRNG_APB]              = starfive_clk_gate("trng_apb",         
UNKNOWN,        base + 0x240);
+       clks[CLK_OTP_APB]               = starfive_clk_gate("otp_apb",          
UNKNOWN,        base + 0x244);
+       clks[CLK_UART0_APB]             = starfive_clk_gate("uart0_apb",        
        UNKNOWN,        base + 0x248);
+       clks[CLK_UART0_CORE]            = 
starfive_clk_gated_divider("uart0_core",              UNKNOWN,        base + 
0x24C, 6);
+       clks[CLK_UART1_APB]             = starfive_clk_gate("uart1_apb",        
        UNKNOWN,        base + 0x250);
+       clks[CLK_UART1_CORE]            = 
starfive_clk_gated_divider("uart1_core",              UNKNOWN,        base + 
0x254, 6);
+       clks[CLK_SPI0_APB]              = starfive_clk_gate("spi0_apb",         
UNKNOWN,        base + 0x258);
+       clks[CLK_SPI0_CORE]             = 
starfive_clk_gated_divider("spi0_core",               UNKNOWN,        base + 
0x25C, 6);
+       clks[CLK_SPI1_APB]              = starfive_clk_gate("spi1_apb",         
UNKNOWN,        base + 0x260);
+       clks[CLK_SPI1_CORE]             = 
starfive_clk_gated_divider("spi1_core",               UNKNOWN,        base + 
0x264, 6);
+       clks[CLK_I2C0_APB]              = starfive_clk_gate("i2c0_apb",         
UNKNOWN,        base + 0x268);
+       clks[CLK_I2C0_CORE]             = 
starfive_clk_gated_divider("i2c0_core",               UNKNOWN,        base + 
0x26C, 6);
+       clks[CLK_I2C1_APB]              = starfive_clk_gate("i2c1_apb",         
UNKNOWN,        base + 0x270);
+       clks[CLK_I2C1_CORE]             = 
starfive_clk_gated_divider("i2c1_core",               UNKNOWN,        base + 
0x274, 6);
+       clks[CLK_GPIO_APB]              = starfive_clk_gate("gpio_apb",         
UNKNOWN,        base + 0x278);
+       clks[CLK_UART2_APB]             = starfive_clk_gate("uart2_apb",        
        UNKNOWN,        base + 0x27C);
+       clks[CLK_UART2_CORE]            = 
starfive_clk_gated_divider("uart2_core",              UNKNOWN,        base + 
0x280, 6);
+       clks[CLK_UART3_APB]             = starfive_clk_gate("uart3_apb",        
        UNKNOWN,        base + 0x284);
+       clks[CLK_UART3_CORE]            = 
starfive_clk_gated_divider("uart3_core",              UNKNOWN,        base + 
0x288, 6);
+       clks[CLK_SPI2_APB]              = starfive_clk_gate("spi2_apb",         
UNKNOWN,        base + 0x28C);
+       clks[CLK_SPI2_CORE]             = 
starfive_clk_gated_divider("spi2_core",               UNKNOWN,        base + 
0x290, 6);
+       clks[CLK_SPI3_APB]              = starfive_clk_gate("spi3_apb",         
UNKNOWN,        base + 0x294);
+       clks[CLK_SPI3_CORE]             = 
starfive_clk_gated_divider("spi3_core",               UNKNOWN,        base + 
0x298, 6);
+       clks[CLK_I2C2_APB]              = starfive_clk_gate("i2c2_apb",         
UNKNOWN,        base + 0x29C);
+       clks[CLK_I2C2_CORE]             = 
starfive_clk_gated_divider("i2c2_core",               UNKNOWN,        base + 
0x2A0, 6);
+       clks[CLK_I2C3_APB]              = starfive_clk_gate("i2c3_apb",         
UNKNOWN,        base + 0x2A4);
+       clks[CLK_I2C3_CORE]             = 
starfive_clk_gated_divider("i2c3_core",               UNKNOWN,        base + 
0x2A8, 6);
+       clks[CLK_WDTIMER_APB]           = starfive_clk_gate("wdtimer_apb",      
        UNKNOWN,        base + 0x2AC);
+       clks[CLK_WDT_CORE]              = 
starfive_clk_gated_divider("wdt_coreclk",             UNKNOWN,        base + 
0x2B0, 6);
+       clks[CLK_TIMER0_CORE]           = 
starfive_clk_gated_divider("timer0_coreclk",          UNKNOWN,        base + 
0x2B4, 6);
+       clks[CLK_TIMER1_CORE]           = 
starfive_clk_gated_divider("timer1_coreclk",          UNKNOWN,        base + 
0x2B8, 6);
+       clks[CLK_TIMER2_CORE]           = 
starfive_clk_gated_divider("timer2_coreclk",          UNKNOWN,        base + 
0x2BC, 6);
+       clks[CLK_TIMER3_CORE]           = 
starfive_clk_gated_divider("timer3_coreclk",          UNKNOWN,        base + 
0x2C0, 6);
+       clks[CLK_TIMER4_CORE]           = 
starfive_clk_gated_divider("timer4_coreclk",          UNKNOWN,        base + 
0x2C4, 6);
+       clks[CLK_TIMER5_CORE]           = 
starfive_clk_gated_divider("timer5_coreclk",          UNKNOWN,        base + 
0x2C8, 6);
+       clks[CLK_TIMER6_CORE]           = 
starfive_clk_gated_divider("timer6_coreclk",          UNKNOWN,        base + 
0x2CC, 6);
+       clks[CLK_VP6INTC_APB]           = starfive_clk_gate("vp6intc_apb",      
        UNKNOWN,        base + 0x2D0);
+       clks[CLK_PWM_APB]               = starfive_clk_gate("pwm_apb",          
UNKNOWN,        base + 0x2D4);
+       clks[CLK_MSI_APB]               = starfive_clk_gate("msi_apb",          
UNKNOWN,        base + 0x2D8);
+       clks[CLK_TEMP_APB]              = starfive_clk_gate("temp_apb",         
UNKNOWN,        base + 0x2DC);
+       clks[CLK_TEMP_SENSE]            = 
starfive_clk_gated_divider("temp_sense",              UNKNOWN,        base + 
0x2E0, 5);
+       clks[CLK_SYSERR_APB]            = starfive_clk_gate("syserr_apb",       
        UNKNOWN,        base + 0x2E4);
+}
+
+static struct clk_onecell_data clk_data;
+
+static int starfive_clkgen_clk_probe(struct device_d *dev)
+{
+       struct resource *iores;
+
+       iores = dev_request_mem_resource(dev, 0);
+       if (IS_ERR(iores))
+               return PTR_ERR(iores);
+
+       starfive_clkgen_init(dev->device_node, IOMEM(iores->start));
+
+       clk_data.clks = clks;
+       clk_data.clk_num = ARRAY_SIZE(clks);
+       of_clk_add_provider(dev->device_node, of_clk_src_onecell_get,
+                           &clk_data);
+
+       return 0;
+}
+
+static __maybe_unused struct of_device_id starfive_clkgen_clk_dt_ids[] = {
+       { .compatible = "starfive,jh7100-clkgen" },
+       { /* sentinel */ }
+};
+
+static struct driver_d starfive_clkgen_clk_driver = {
+       .probe  = starfive_clkgen_clk_probe,
+       .name   = "starfive-clkgen",
+       .of_compatible = starfive_clkgen_clk_dt_ids,
+};
+core_platform_driver(starfive_clkgen_clk_driver);
diff --git a/include/dt-bindings/clock/starfive-jh7100.h 
b/include/dt-bindings/clock/starfive-jh7100.h
new file mode 100644
index 000000000000..9ad5e7f9bfd5
--- /dev/null
+++ b/include/dt-bindings/clock/starfive-jh7100.h
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0 OR X11 */
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H
+
+#define        CLK_OSC_SYS             0
+#define        CLK_OSC_AUD             1
+#define        CLK_PLL0_OUT            2
+#define        CLK_PLL1_OUT            3
+#define        CLK_PLL2_OUT            4
+#define CLK_CPUNDBUS_ROOT      5
+#define CLK_DLA_ROOT           6
+#define CLK_DSP_ROOT           7
+#define CLK_GMACUSB_ROOT       8
+#define CLK_PERH0_ROOT         9
+#define CLK_PERH1_ROOT         10
+#define CLK_VIN_ROOT           11
+#define CLK_VOUT_ROOT          12
+#define CLK_AUDIO_ROOT         13
+#define CLK_CDECHIFI4_ROOT     14
+#define CLK_CDEC_ROOT          15
+#define CLK_VOUTBUS_ROOT       16
+#define CLK_CPUNBUS_ROOT_DIV   17
+#define CLK_DSP_ROOT_DIV       18
+#define CLK_PERH0_SRC          19
+#define CLK_PERH1_SRC          20
+#define CLK_PLL0_TESTOUT       21
+#define CLK_PLL1_TESTOUT       22
+#define CLK_PLL2_TESTOUT       23
+#define CLK_PLL2_REF           24
+#define CLK_CPU_CORE           25
+#define CLK_CPU_AXI            26
+#define CLK_AHB_BUS            27
+#define CLK_APB1_BUS           28
+#define CLK_APB2_BUS           29
+#define CLK_DOM3AHB_BUS                30
+#define CLK_DOM7AHB_BUS                31
+#define CLK_U74_CORE0          32
+#define CLK_U74_CORE1          33
+#define CLK_U74_AXI            34
+#define CLK_U74RTC_TOGGLE      35
+#define CLK_SGDMA2P_AXI                35
+#define CLK_DMA2PNOC_AXI       37
+#define CLK_SGDMA2P_AHB                37
+#define CLK_DLA_BUS            39
+#define CLK_DLA_AXI            40
+#define CLK_DLANOC_AXI         41
+#define CLK_DLA_APB            42
+#define CLK_VP6_CORE           43
+#define CLK_VP6BUS_SRC         44
+#define CLK_VP6_AXI            45
+#define CLK_VCDECBUS_SRC       46
+#define CLK_VDEC_BUS           47
+#define CLK_VDEC_AXI           48
+#define CLK_VDECBRG_MAIN       49
+#define CLK_VDEC_BCLK          50
+#define CLK_VDEC_CCLK          51
+#define CLK_VDEC_APB           52
+#define CLK_JPEG_AXI           53
+#define CLK_JPEG_CCLK          54
+#define CLK_JPEG_APB           55
+#define CLK_GC300_2X           56
+#define CLK_GC300_AHB          57
+#define CLK_JPCGC300_AXIBUS    58
+#define CLK_GC300_AXI          59
+#define CLK_JPCGC300_MAIN      60
+#define CLK_VENC_BUS           61
+#define CLK_VENC_AXI           62
+#define CLK_VENCBRG_MAIN       63
+#define CLK_VENC_BCLK          64
+#define CLK_VENC_CCLK          65
+#define CLK_VENC_APB           66
+#define CLK_DDRPLL_DIV2                67
+#define CLK_DDRPLL_DIV4                68
+#define CLK_DDRPLL_DIV8                69
+#define CLK_DDROSC_DIV2                70
+#define CLK_DDRC0              71
+#define CLK_DDRC1              72
+#define CLK_DDRPHY_APB         73
+#define CLK_NOC_ROB            74
+#define CLK_NOC_COG            75
+#define CLK_NNE_AHB            76
+#define CLK_NNEBUS_SRC1                77
+#define CLK_NNE_BUS            78
+#define CLK_NNE_AXI            79
+#define CLK_NNENOC_AXI         80
+#define CLK_DLASLV_AXI         81
+#define CLK_DSPX2C_AXI         82
+#define CLK_HIFI4_SRC          83
+#define CLK_HIFI4_COREFREE     84
+#define CLK_HIFI4_CORE         85
+#define CLK_HIFI4_BUS          86
+#define CLK_HIFI4_AXI          87
+#define CLK_HIFI4NOC_AXI       88
+#define CLK_SGDMA1P_BUS                89
+#define CLK_SGDMA1P_AXI                90
+#define CLK_DMA1P_AXI          91
+#define CLK_X2C_AXI            92
+#define CLK_USB_BUS            93
+#define CLK_USB_AXI            94
+#define CLK_USBNOC_AXI         95
+#define CLK_USBPHY_ROOTDIV     96
+#define CLK_USBPHY_125M                97
+#define CLK_USBPHY_PLLDIV25M   98
+#define CLK_USBPHY_25M         99
+#define CLK_AUDIO_DIV          100
+#define CLK_AUDIO_SRC          101
+#define CLK_AUDIO_12288                102
+#define CLK_VIN_SRC            103
+#define CLK_ISP0_BUS           104
+#define CLK_ISP0_AXI           105
+#define CLK_ISP0NOC_AXI                106
+#define CLK_ISPSLV_AXI         107
+#define CLK_ISP1_BUS           108
+#define CLK_ISP1_AXI           109
+#define CLK_ISP1NOC_AXI                110
+#define CLK_VIN_BUS            111
+#define CLK_VIN_AXI            112
+#define CLK_VINNOC_AXI         113
+#define CLK_VOUT_SRC           114
+#define CLK_DISPBUS_SRC                115
+#define CLK_DISP_BUS           116
+#define CLK_DISP_AXI           117
+#define CLK_DISPNOC_AXI                118
+#define CLK_SDIO0_AHB          119
+#define CLK_SDIO0_CCLKINT      120
+#define CLK_SDIO0_CCLKINT_INV  121
+#define CLK_SDIO1_AHB          122
+#define CLK_SDIO1_CCLKINT      123
+#define CLK_SDIO1_CCLKINT_INV  124
+#define CLK_GMAC_AHB           125
+#define CLK_GMAC_ROOT_DIV      126
+#define CLK_GMAC_PTP_REF       127
+#define CLK_GMAC_GTX           128
+#define CLK_GMAC_RMII_TX       129
+#define CLK_GMAC_RMII_RX       130
+#define CLK_GMAC_TX            131
+#define CLK_GMAC_TX_INV                132
+#define CLK_GMAC_RX_PRE                133
+#define CLK_GMAC_RX_INV                134
+#define CLK_GMAC_RMII          135
+#define CLK_GMAC_TOPHYREF      136
+#define CLK_SPI2AHB_AHB                137
+#define CLK_SPI2AHB_CORE       138
+#define CLK_EZMASTER_AHB       139
+#define CLK_E24_AHB            140
+#define CLK_E24RTC_TOGGLE      141
+#define CLK_QSPI_AHB           142
+#define CLK_QSPI_APB           143
+#define CLK_QSPI_REF           144
+#define CLK_SEC_AHB            145
+#define CLK_AES                        146
+#define CLK_SHA                        147
+#define CLK_PKA                        148
+#define CLK_TRNG_APB           149
+#define CLK_OTP_APB            150
+#define CLK_UART0_APB          151
+#define CLK_UART0_CORE         152
+#define CLK_UART1_APB          153
+#define CLK_UART1_CORE         154
+#define CLK_SPI0_APB           155
+#define CLK_SPI0_CORE          156
+#define CLK_SPI1_APB           157
+#define CLK_SPI1_CORE          158
+#define CLK_I2C0_APB           159
+#define CLK_I2C0_CORE          160
+#define CLK_I2C1_APB           161
+#define CLK_I2C1_CORE          162
+#define CLK_GPIO_APB           163
+#define CLK_UART2_APB          164
+#define CLK_UART2_CORE         165
+#define CLK_UART3_APB          166
+#define CLK_UART3_CORE         167
+#define CLK_SPI2_APB           168
+#define CLK_SPI2_CORE          169
+#define CLK_SPI3_APB           170
+#define CLK_SPI3_CORE          171
+#define CLK_I2C2_APB           172
+#define CLK_I2C2_CORE          173
+#define CLK_I2C3_APB           174
+#define CLK_I2C3_CORE          175
+#define CLK_WDTIMER_APB                176
+#define CLK_WDT_CORE           177
+#define CLK_TIMER0_CORE                178
+#define CLK_TIMER1_CORE                179
+#define CLK_TIMER2_CORE                180
+#define CLK_TIMER3_CORE                181
+#define CLK_TIMER4_CORE                182
+#define CLK_TIMER5_CORE                183
+#define CLK_TIMER6_CORE                184
+#define CLK_VP6INTC_APB                185
+#define CLK_PWM_APB            186
+#define CLK_MSI_APB            187
+#define CLK_TEMP_APB           188
+#define CLK_TEMP_SENSE         189
+#define CLK_SYSERR_APB         190
+
+#define CLK_END                        191
+
+#endif
-- 
2.29.2


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to