On 31.05.21 09:38, Ahmad Fatoum wrote: > All clocks seem to share a common format: > > struct starfive_clk { > u32 divisor : 24; > u32 mux : 6; > u32 invert : 1; > u32 enable : 1; > }; > > 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>. If someone's curious: https://gist.github.com/a3f/085ea5d58e3bf3e5536e441b1a45f0ce Advising to rinse your eyes afterwards. > > Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> > --- > 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..7e4104993580 > --- /dev/null > +++ b/drivers/clk/starfive/Makefile > @@ -0,0 +1,3 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +obj-$(CONFIG_SOC_STARFIVE_JH7100) += 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 > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox