On 22/11/2022 13:12, Shubhrajyoti Datta wrote: > The Clocking Wizard for Versal adaptive compute acceleration platforms. > Add Versal clocking wizard support. The driver supports configurable > number of outputs. > > Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xxxxxxx> > --- > > Changes in v3: > rename the clocks to clk_in1 and s_axi_clk in driver > > Changes in v2: > rename the clocks clk_in1 to in1 and s_axi_clk to s_axi in driver > update the warn > Update the compatible to reflect versal > > drivers/clk/xilinx/Kconfig | 13 + > drivers/clk/xilinx/Makefile | 1 + > drivers/clk/xilinx/clk-xlnx-clock-wizard-v.c | 739 +++++++++++++++++++ > 3 files changed, 753 insertions(+) > create mode 100644 drivers/clk/xilinx/clk-xlnx-clock-wizard-v.c > > diff --git a/drivers/clk/xilinx/Kconfig b/drivers/clk/xilinx/Kconfig > index f205522c40ff..dd8e4a733d0b 100644 > --- a/drivers/clk/xilinx/Kconfig > +++ b/drivers/clk/xilinx/Kconfig > @@ -29,3 +29,16 @@ config COMMON_CLK_XLNX_CLKWZRD > > If unsure, say N. > > +config COMMON_CLK_XLNX_CLKWZRD_V > + tristate "Xilinx Versal Clocking Wizard" > + depends on COMMON_CLK && OF > + depends on HAS_IOMEM > + help > + Support for the Versal Xilinx Clocking Wizard IP core clock generator. > + This driver supports the Versal Xilinx clocking wizard programmable clock > + synthesizer. The number of output is configurable in the design. > + > + If unsure, say N. > + > + To compile this driver as a module, choose M here: the > + module will be called clk-xlnx-clock-wizard-v. > diff --git a/drivers/clk/xilinx/Makefile b/drivers/clk/xilinx/Makefile > index 7ac1789c6b1b..9e7e1c1c026c 100644 > --- a/drivers/clk/xilinx/Makefile > +++ b/drivers/clk/xilinx/Makefile > @@ -1,3 +1,4 @@ > # SPDX-License-Identifier: GPL-2.0 > obj-$(CONFIG_XILINX_VCU) += xlnx_vcu.o > +obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD_V) += clk-xlnx-clock-wizard-v.o > obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clk-xlnx-clock-wizard.o > diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard-v.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard-v.c > new file mode 100644 > index 000000000000..9afbbd5a2d15 > --- /dev/null > +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard-v.c > @@ -0,0 +1,739 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Xilinx Versal Clocking Wizard driver > + * > + * Copyright (C) 2022, Advanced Micro Devices, Inc. > + * > + * Shubhrajyoti Datta <shubhrajyoti.datta@xxxxxxx> > + */ > + > +#include <linux/bitfield.h> > +#include <linux/clk.h> > +#include <linux/clk-provider.h> > +#include <linux/err.h> > +#include <linux/io.h> > +#include <linux/iopoll.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/platform_device.h> > +#include <linux/slab.h> > + > +#define WZRD_NUM_OUTPUTS 7 > +#define WZRD_ACLK_MAX_FREQ 250000000UL > + > +#define WZRD_CLK_CFG_REG(n) (0x330 + 4 * (n)) > + > +#define WZRD_CLKFBOUT_1 0 > +#define WZRD_CLKFBOUT_2 1 > +#define WZRD_CLKOUT0_1 2 > +#define WZRD_CLKOUT0_2 3 > +#define WZRD_DESKEW_2 20 > +#define WZRD_DIVCLK 21 > +#define WZRD_CLKFBOUT_4 51 > +#define WZRD_CLKFBOUT_3 48 > +#define WZRD_DUTY_CYCLE 2 > +#define WZRD_O_DIV 4 > + > +#define WZRD_CLKFBOUT_FRAC_EN BIT(1) > +#define WZRD_CLKFBOUT_PREDIV2 (BIT(11) | BIT(12) | BIT(9)) > +#define WZRD_MULT_PREDIV2 (BIT(10) | BIT(9) | BIT(12)) > +#define WZRD_CLKFBOUT_EDGE BIT(8) > +#define WZRD_P5EN BIT(13) > +#define WZRD_P5EN_SHIFT 13 > +#define WZRD_P5FEDGE BIT(15) > +#define WZRD_DIVCLK_EDGE BIT(10) > +#define WZRD_P5FEDGE_SHIFT 15 > +#define WZRD_CLKOUT0_PREDIV2 BIT(11) > +#define WZRD_EDGE_SHIFT 8 > + > +#define WZRD_CLKFBOUT_L_SHIFT 0 > +#define WZRD_CLKFBOUT_H_SHIFT 8 > +#define WZRD_CLKFBOUT_L_MASK GENMASK(7, 0) > +#define WZRD_CLKFBOUT_H_MASK GENMASK(15, 8) > +#define WZRD_CLKFBOUT_FRAC_SHIFT 16 > +#define WZRD_CLKFBOUT_FRAC_MASK GENMASK(5, 0) > +#define WZRD_DIVCLK_DIVIDE_MASK GENMASK(7, 0) > +#define WZRD_CLKOUT_DIVIDE_SHIFT 0 > +#define WZRD_CLKOUT_DIVIDE_WIDTH 8 > +#define WZRD_CLKOUT_DIVIDE_MASK GENMASK(7, 0) > +#define WZRD_CLKOUT_FRAC_SHIFT 8 > +#define WZRD_CLKOUT_FRAC_MASK 0x3ff > + > +#define WZRD_DR_MAX_INT_DIV_VALUE 32767 > +#define WZRD_DR_STATUS_REG_OFFSET 0x04 > +#define WZRD_DR_LOCK_BIT_MASK BIT(0) > +#define WZRD_DR_INIT_REG_OFFSET 0x14 > +#define WZRD_DR_DIV_TO_PHASE_OFFSET 4 > +#define WZRD_DR_BEGIN_DYNA_RECONF 0x03 > +#define WZRD_MIN_ERR 500000 > +#define WZRD_USEC_POLL 10 > +#define WZRD_TIMEOUT_POLL 1000 > +#define WZRD_FRAC_GRADIENT 64 > +#define PREDIV2_MULT 2 > + > +#define DIV_O 1 > +#define DIV_ALL 3 > + > +#define WZRD_M_MIN 4 > +#define WZRD_M_MAX 432 > +#define WZRD_D_MIN 1 > +#define WZRD_D_MAX 123 > +#define WZRD_VCO_MIN 2160000000UL > +#define WZRD_VCO_MAX 4320000000UL > +#define WZRD_O_MIN 2 > +#define WZRD_O_MAX 511 > + > +/* Extract divider instance from clock hardware instance */ > +#define to_clk_wzrd_divider(_hw) container_of(_hw, struct clk_wzrd_divider, hw) > + > +enum clk_wzrd_int_clks { > + wzrd_clk_mul, > + wzrd_clk_mul_div, > + wzrd_clk_int_max > +}; > + > +/** > + * struct clk_wzrd - Clock wizard private data structure > + * > + * @clk_data: Clock data > + * @nb: Notifier block > + * @base: Memory base > + * @clk_in1: Handle to input clock 'clk_in1' > + * @axi_clk: Handle to input clock 's_axi_aclk' > + * @clks_internal: Internal clocks > + * @clkout: Output clocks > + */ > +struct clk_wzrd { > + struct clk_onecell_data clk_data; > + struct notifier_block nb; > + void __iomem *base; > + struct clk *clk_in1; > + struct clk *axi_clk; > + struct clk *clks_internal[wzrd_clk_int_max]; > + struct clk *clkout[WZRD_NUM_OUTPUTS]; > +}; This is so similar to existing driver, so no to duplicating drivers. Integrate. Best regards, Krzysztof