diff mbox series

[v1,2/2] clocking-wizard: Add support for versal clocking wizard

Message ID 20230418102855.6791-3-shubhrajyoti.datta@amd.com
State New
Headers show
Series clocking-wizard: Added support for versal clocking wizard | expand

Commit Message

Shubhrajyoti Datta April 18, 2023, 10:28 a.m. UTC
The Clocking Wizard for Versal adaptive compute acceleration platforms.
Add Versal clocking wizard support.

Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
---

 drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 506 ++++++++++++++++-----
 1 file changed, 400 insertions(+), 106 deletions(-)

Comments

kernel test robot April 18, 2023, 4:57 p.m. UTC | #1
Hi Shubhrajyoti,

kernel test robot noticed the following build warnings:

[auto build test WARNING on clk/clk-next]
[also build test WARNING on next-20230417]
[cannot apply to xilinx-xlnx/master robh/for-next linus/master v6.3-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shubhrajyoti-Datta/dt-bindings-clocking-wizard-add-versal-compatible/20230418-183046
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/20230418102855.6791-3-shubhrajyoti.datta%40amd.com
patch subject: [PATCH v1 2/2] clocking-wizard: Add support for versal clocking wizard
config: arc-randconfig-r043-20230417 (https://download.01.org/0day-ci/archive/20230419/202304190011.BMtXurPJ-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/143916412aa6a419e20fa37059004329e300ca95
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Shubhrajyoti-Datta/dt-bindings-clocking-wizard-add-versal-compatible/20230418-183046
        git checkout 143916412aa6a419e20fa37059004329e300ca95
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash drivers/clk/xilinx/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304190011.BMtXurPJ-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/clk/xilinx/clk-xlnx-clock-wizard.c: In function 'clk_wzrd_get_divisors':
>> drivers/clk/xilinx/clk-xlnx-clock-wizard.c:102:41: warning: unsigned conversion from 'long long int' to 'long unsigned int' changes value from '4320000000' to '25032704' [-Woverflow]
     102 | #define VER_WZRD_VCO_MAX                4320000000
         |                                         ^~~~~~~~~~
   drivers/clk/xilinx/clk-xlnx-clock-wizard.c:332:26: note: in expansion of macro 'VER_WZRD_VCO_MAX'
     332 |                 vcomax = VER_WZRD_VCO_MAX;
         |                          ^~~~~~~~~~~~~~~~


vim +102 drivers/clk/xilinx/clk-xlnx-clock-wizard.c

    88	
    89	#define WZRD_M_MIN			2
    90	#define WZRD_M_MAX			128
    91	#define WZRD_D_MIN			1
    92	#define WZRD_D_MAX			106
    93	#define WZRD_VCO_MIN			800000000
    94	#define WZRD_VCO_MAX			1600000000
    95	#define WZRD_O_MIN			1
    96	#define WZRD_O_MAX			128
    97	#define VER_WZRD_M_MIN			4
    98	#define VER_WZRD_M_MAX			432
    99	#define VER_WZRD_D_MIN			1
   100	#define VER_WZRD_D_MAX			123
   101	#define VER_WZRD_VCO_MIN		2160000000
 > 102	#define VER_WZRD_VCO_MAX		4320000000
   103	#define VER_WZRD_O_MIN			2
   104	#define VER_WZRD_O_MAX			511
   105	#define WZRD_MIN_ERR			20000
   106	#define WZRD_FRAC_POINTS		1000
   107
kernel test robot April 19, 2023, 4:42 a.m. UTC | #2
Hi Shubhrajyoti,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shubhrajyoti-Datta/dt-bindings-clocking-wizard-add-versal-compatible/20230418-183046
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/20230418102855.6791-3-shubhrajyoti.datta%40amd.com
patch subject: [PATCH v1 2/2] clocking-wizard: Add support for versal clocking wizard
config: csky-randconfig-m041-20230418 (https://download.01.org/0day-ci/archive/20230419/202304190429.UOH2nE9u-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Link: https://lore.kernel.org/r/202304190429.UOH2nE9u-lkp@intel.com/

smatch warnings:
drivers/clk/xilinx/clk-xlnx-clock-wizard.c:264 clk_wzrd_dynamic_reconfig() error: uninitialized symbol 'value'.

vim +/value +264 drivers/clk/xilinx/clk-xlnx-clock-wizard.c

5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  226  static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  227  				     unsigned long parent_rate)
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  228  {
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  229  	struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  230  	void __iomem *div_addr = divider->base + divider->offset;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  231  	u32 value, regh, edged, p5en, p5fedge, regval, regval1;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  232  	unsigned long flags = 0;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  233  	int err;
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  234  
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  235  	if (divider->lock)
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  236  		spin_lock_irqsave(divider->lock, flags);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  237  	else
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  238  		__acquire(divider->lock);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  239  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  240  	if (!divider->is_versal) {
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  241  		value = DIV_ROUND_CLOSEST(parent_rate, rate);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  242  
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  243  		/* Cap the value to max */
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  244  		min_t(u32, value, WZRD_DR_MAX_INT_DIV_VALUE);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  245  
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  246  		/* Set divisor and clear phase offset */
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  247  		writel(value, div_addr);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  248  		writel(0x00, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  249  
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  250  		/* Check status register */
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  251  		err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  252  					 value, value & WZRD_DR_LOCK_BIT_MASK,
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  253  					 WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  254  		if (err)
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  255  			goto err_reconfig;
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  256  
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  257  		/* Initiate reconfiguration */
dd5e7431ac54e0 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2022-04-11  258  		writel(WZRD_DR_BEGIN_DYNA_RECONF_5_2,
dd5e7431ac54e0 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2022-04-11  259  		       divider->base + WZRD_DR_INIT_REG_OFFSET);
dd5e7431ac54e0 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2022-04-11  260  		writel(WZRD_DR_BEGIN_DYNA_RECONF1_5_2,
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  261  		       divider->base + WZRD_DR_INIT_REG_OFFSET);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  262  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  263  	} else {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18 @264  		regh = (value / 4);
                                                                                                                                ^^^^^
Uninitialized.

143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  265  		regval1 = readl(div_addr);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  266  		regval1 |= WZRD_CLKFBOUT_PREDIV2;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  267  		regval1 = regval1 & ~(WZRD_CLKFBOUT_EDGE | WZRD_P5EN | WZRD_P5FEDGE);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  268  		if (value % 4 > 1) {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  269  			edged = 1;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  270  			regval1 |= (edged << WZRD_EDGE_SHIFT);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  271  		}
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  272  		p5fedge = value % 2;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  273  		p5en = value % 2;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  274  		regval1 = regval1 | p5en << WZRD_P5EN_SHIFT | p5fedge << WZRD_P5FEDGE_SHIFT;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  275  		writel(regval1, div_addr);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  276  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  277  		regval = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  278  		writel(regval, div_addr + 4);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  279  		/* Check status register */
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  280  		err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  281  					 value, value & WZRD_DR_LOCK_BIT_MASK,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  282  					 WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  283  		if (err)
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  284  			goto err_reconfig;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  285  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  286  		/* Initiate reconfiguration */
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  287  		writel(WZRD_DR_BEGIN_DYNA_RECONF,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  288  		       divider->base + WZRD_DR_INIT_VERSAL_OFFSET);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  289  	}
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  290  	/* Check status register */
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  291  	err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  292  				 value, value & WZRD_DR_LOCK_BIT_MASK,
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  293  				 WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  294  err_reconfig:
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  295  	if (divider->lock)
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  296  		spin_unlock_irqrestore(divider->lock, flags);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  297  	else
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  298  		__release(divider->lock);
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  299  	return err;
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  300  }
Dan Carpenter April 21, 2023, 10:15 a.m. UTC | #3
Hi Shubhrajyoti,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shubhrajyoti-Datta/dt-bindings-clocking-wizard-add-versal-compatible/20230418-183046
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/20230418102855.6791-3-shubhrajyoti.datta%40amd.com
patch subject: [PATCH v1 2/2] clocking-wizard: Add support for versal clocking wizard
config: arm64-randconfig-m041-20230419 (https://download.01.org/0day-ci/archive/20230421/202304211427.AoG9GhQ1-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Link: https://lore.kernel.org/r/202304211427.AoG9GhQ1-lkp@intel.com/

New smatch warnings:
drivers/clk/xilinx/clk-xlnx-clock-wizard.c:1075 clk_wzrd_probe() warn: 'clk_wzrd->axi_clk' from clk_prepare_enable() not released on lines: 897.

vim +1075 drivers/clk/xilinx/clk-xlnx-clock-wizard.c

812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   832  static int clk_wzrd_probe(struct platform_device *pdev)
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   833  {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   834  	const char *clkout_name, *clk_name, *clk_mul_name;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   835  	u32 regl, regh, edge, regld, reghd, edged, div;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   836  	const struct versal_clk_data *data;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   837  	const struct of_device_id *match;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   838  	int i, ret;
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   839  	u32 reg, reg_f, mult;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   840  	unsigned long rate;
87a40bfb09f213 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   841  	void __iomem *ctrl_reg;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   842  	struct clk_wzrd *clk_wzrd;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   843  	struct device_node *np = pdev->dev.of_node;
92a7590427d666 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   844  	int nr_outputs;
87a40bfb09f213 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   845  	unsigned long flags = 0;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   846  	bool is_versal = 0;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   847  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   848  	clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   849  	if (!clk_wzrd)
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   850  		return -ENOMEM;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   851  	platform_set_drvdata(pdev, clk_wzrd);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   852  
f595f03bfdfc3c drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c YueHaibing         2019-10-09   853  	clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   854  	if (IS_ERR(clk_wzrd->base))
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   855  		return PTR_ERR(clk_wzrd->base);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   856  
17aa33ff569980 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   857  	ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   858  	if (!ret) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   859  		if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   860  			dev_warn(&pdev->dev, "invalid speed grade '%d'\n",
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   861  				 clk_wzrd->speed_grade);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   862  			clk_wzrd->speed_grade = 0;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   863  		}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   864  	}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   865  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   866  	clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1");
fd30ac84f3022e drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Yang Yingliang     2022-09-13   867  	if (IS_ERR(clk_wzrd->clk_in1))
fd30ac84f3022e drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Yang Yingliang     2022-09-13   868  		return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1),
fd30ac84f3022e drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Yang Yingliang     2022-09-13   869  				     "clk_in1 not found\n");
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   870  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   871  	clk_wzrd->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
fd30ac84f3022e drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Yang Yingliang     2022-09-13   872  	if (IS_ERR(clk_wzrd->axi_clk))
fd30ac84f3022e drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Yang Yingliang     2022-09-13   873  		return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk),
fd30ac84f3022e drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Yang Yingliang     2022-09-13   874  				     "s_axi_aclk not found\n");
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   875  	ret = clk_prepare_enable(clk_wzrd->axi_clk);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   876  	if (ret) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   877  		dev_err(&pdev->dev, "enabling s_axi_aclk failed\n");
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   878  		return ret;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   879  	}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   880  	rate = clk_get_rate(clk_wzrd->axi_clk);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   881  	if (rate > WZRD_ACLK_MAX_FREQ) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   882  		dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n",
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   883  			rate);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   884  		ret = -EINVAL;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   885  		goto err_disable_clk;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   886  	}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   887  
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   888  	ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs);
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   889  	if (ret || nr_outputs > WZRD_NUM_OUTPUTS) {
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   890  		ret = -EINVAL;
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   891  		goto err_disable_clk;
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   892  	}
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   893  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   894  	match = of_match_node(clk_wzrd_ids, np);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   895  	if (!match) {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   896  		dev_err(&pdev->dev, "of_match_node failed\n");
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   897  		return -ENODEV;

goto err_disable_clk;

Might be better to convert this to devm_clk_get_enabled().

143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   898  	}
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   899  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   900  	data = match->data;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   901  	if (data)
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   902  		is_versal = data->is_versal;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   903  
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   904  	clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev));
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   905  	if (nr_outputs == 1) {
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   906  		clk_wzrd->clkout[0] = clk_wzrd_register_divider
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   907  				(&pdev->dev, clkout_name,
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   908  				__clk_get_name(clk_wzrd->clk_in1), 0,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   909  				clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3),
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   910  				WZRD_CLKOUT_DIVIDE_SHIFT,
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   911  				WZRD_CLKOUT_DIVIDE_WIDTH,
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   912  				CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   913  				DIV_ALL, is_versal, &clkwzrd_lock);
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   914  
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   915  		goto out;
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   916  	}
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   917  	if (is_versal) {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   918  		/* register multiplier */
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   919  		edge = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)) &
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   920  				BIT(8));
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   921  		regl = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 1)) &
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   922  			     WZRD_CLKFBOUT_L_MASK) >> WZRD_CLKFBOUT_L_SHIFT;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   923  		regh = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 1)) &
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   924  			     WZRD_CLKFBOUT_H_MASK) >> WZRD_CLKFBOUT_H_SHIFT;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   925  		mult = regl + regh + edge;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   926  		if (!mult)
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   927  			mult = 1;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   928  		mult = mult * WZRD_FRAC_GRADIENT;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   929  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   930  		regl = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 51)) &
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   931  			     WZRD_CLKFBOUT_FRAC_EN;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   932  		if (regl) {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   933  			regl = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 48)) &
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   934  				WZRD_VERSAL_FRAC_MASK;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   935  			mult = mult + regl;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   936  		}
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   937  	} else {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   938  		reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0));
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   939  		reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK;
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   940  		reg_f =  reg_f >> WZRD_CLKFBOUT_FRAC_SHIFT;
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   941  
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   942  		reg = reg & WZRD_CLKFBOUT_MULT_MASK;
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   943  		reg =  reg >> WZRD_CLKFBOUT_MULT_SHIFT;
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   944  		mult = (reg * 1000) + reg_f;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   945  	}
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   946  	clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev));
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   947  	if (!clk_name) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   948  		ret = -ENOMEM;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   949  		goto err_disable_clk;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   950  	}
d5213236151ba6 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Ioannis Valasakis  2018-10-04   951  	clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor
d5213236151ba6 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Ioannis Valasakis  2018-10-04   952  			(&pdev->dev, clk_name,
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   953  			 __clk_get_name(clk_wzrd->clk_in1),
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   954  			0, mult, 1000);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   955  	if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   956  		dev_err(&pdev->dev, "unable to register fixed-factor clock\n");
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   957  		ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   958  		goto err_disable_clk;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   959  	}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   960  
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   961  	clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev));
5f18611038f9c9 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Devendra Naga      2014-11-29   962  	if (!clk_name) {
5f18611038f9c9 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Devendra Naga      2014-11-29   963  		ret = -ENOMEM;
5f18611038f9c9 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Devendra Naga      2014-11-29   964  		goto err_rm_int_clk;
5f18611038f9c9 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Devendra Naga      2014-11-29   965  	}
5f18611038f9c9 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Devendra Naga      2014-11-29   966  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   967  	if (is_versal) {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   968  		edged = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 20)) &
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   969  			     BIT(10));
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   970  		regld = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 21)) &
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   971  			     WZRD_CLKFBOUT_L_MASK) >> WZRD_CLKFBOUT_L_SHIFT;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   972  		reghd = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 21)) &
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   973  		     WZRD_CLKFBOUT_H_MASK) >> WZRD_CLKFBOUT_H_SHIFT;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   974  		div = (regld  + reghd + edged);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   975  		if (!div)
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   976  			div = 1;
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   977  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   978  		clk_mul_name = __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   979  		clk_wzrd->clks_internal[wzrd_clk_mul_div] =
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   980  			clk_register_fixed_factor(&pdev->dev, clk_name,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   981  						  clk_mul_name, 0, 1, div);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   982  	} else {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   983  		ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0);
87a40bfb09f213 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   984  		clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
d5213236151ba6 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Ioannis Valasakis  2018-10-04   985  			(&pdev->dev, clk_name,
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   986  			 __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
87a40bfb09f213 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   987  			flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED |
87a40bfb09f213 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   988  			CLK_DIVIDER_ALLOW_ZERO, &clkwzrd_lock);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18   989  	}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   990  	if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   991  		dev_err(&pdev->dev, "unable to register divider clock\n");
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   992  		ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   993  		goto err_rm_int_clk;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   994  	}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   995  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02   996  	/* register div per output */
a0d1a3864cad08 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24   997  	for (i = nr_outputs - 1; i >= 0 ; i--) {
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   998  		clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27   999  					     "%s_out%d", dev_name(&pdev->dev), i);
a0d1a3864cad08 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1000  		if (!clkout_name) {
a0d1a3864cad08 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1001  			ret = -ENOMEM;
a0d1a3864cad08 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1002  			goto err_rm_int_clk;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1003  		}
a0d1a3864cad08 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1004  
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1005  		if (is_versal) {
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1006  			clk_wzrd->clkout[i] = clk_wzrd_register_divider
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1007  						(&pdev->dev,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1008  						 clkout_name, clk_name, 0,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1009  						 clk_wzrd->base,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1010  						 (WZRD_CLK_CFG_REG(is_versal, 3) + i * 8),
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1011  						 WZRD_CLKOUT_DIVIDE_SHIFT,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1012  						 WZRD_CLKOUT_DIVIDE_WIDTH,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1013  						 CLK_DIVIDER_ONE_BASED |
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1014  						 CLK_DIVIDER_ALLOW_ZERO,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1015  						 DIV_O, true, &clkwzrd_lock);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1016  		} else {
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1017  			if (!i)
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1018  				clk_wzrd->clkout[i] = clk_wzrd_register_divf
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1019  					(&pdev->dev, clkout_name, clk_name, flags, clk_wzrd->base,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1020  					(WZRD_CLK_CFG_REG(is_versal, 2) + i * 12),
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1021  					WZRD_CLKOUT_DIVIDE_SHIFT,
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1022  					WZRD_CLKOUT_DIVIDE_WIDTH,
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1023  					CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27  1024  					DIV_O, &clkwzrd_lock);
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1025  			else
91d695d71841ab drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1026  				clk_wzrd->clkout[i] = clk_wzrd_register_divider
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1027  					(&pdev->dev, clkout_name, clk_name, 0, clk_wzrd->base,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1028  					(WZRD_CLK_CFG_REG(is_versal, 2) + i * 12),
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1029  					WZRD_CLKOUT_DIVIDE_SHIFT,
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1030  					WZRD_CLKOUT_DIVIDE_WIDTH,
5a853722eb3218 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1031  					CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1032  					DIV_O, false,  &clkwzrd_lock);
143916412aa6a4 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-04-18  1033  		}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1034  		if (IS_ERR(clk_wzrd->clkout[i])) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1035  			int j;
e66f7a27521119 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Athira Sharikkal   2014-11-30  1036  
a0d1a3864cad08 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Shubhrajyoti Datta 2021-02-24  1037  			for (j = i + 1; j < nr_outputs; j++)
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1038  				clk_unregister(clk_wzrd->clkout[j]);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1039  			dev_err(&pdev->dev,
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1040  				"unable to register divider clock\n");
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1041  			ret = PTR_ERR(clk_wzrd->clkout[i]);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1042  			goto err_rm_int_clks;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1043  		}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1044  	}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1045  
595c88cda65d30 drivers/clk/xilinx/clk-xlnx-clock-wizard.c              Shubhrajyoti Datta 2023-03-27  1046  out:
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1047  	clk_wzrd->clk_data.clks = clk_wzrd->clkout;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1048  	clk_wzrd->clk_data.clk_num = ARRAY_SIZE(clk_wzrd->clkout);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1049  	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_wzrd->clk_data);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1050  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1051  	if (clk_wzrd->speed_grade) {
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1052  		clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1053  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1054  		ret = clk_notifier_register(clk_wzrd->clk_in1,
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1055  					    &clk_wzrd->nb);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1056  		if (ret)
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1057  			dev_warn(&pdev->dev,
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1058  				 "unable to register clock notifier\n");
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1059  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1060  		ret = clk_notifier_register(clk_wzrd->axi_clk, &clk_wzrd->nb);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1061  		if (ret)
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1062  			dev_warn(&pdev->dev,
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1063  				 "unable to register clock notifier\n");
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1064  	}
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1065  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1066  	return 0;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1067  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1068  err_rm_int_clks:
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1069  	clk_unregister(clk_wzrd->clks_internal[1]);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1070  err_rm_int_clk:
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1071  	clk_unregister(clk_wzrd->clks_internal[0]);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1072  err_disable_clk:
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1073  	clk_disable_unprepare(clk_wzrd->axi_clk);
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1074  
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02 @1075  	return ret;
812283cd546376 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c Soren Brinkmann    2014-10-02  1076  }
diff mbox series

Patch

diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index e83f104fad02..18247984582a 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -23,15 +23,41 @@ 
 #define WZRD_NUM_OUTPUTS	7
 #define WZRD_ACLK_MAX_FREQ	250000000UL
 
-#define WZRD_CLK_CFG_REG(n)	(0x200 + 4 * (n))
+#define WZRD_CLK_CFG_REG(v, n)	(0x200 + 0x130 * (v) + 4 * (n))
 
 #define WZRD_CLKOUT0_FRAC_EN	BIT(18)
-#define WZRD_CLKFBOUT_FRAC_EN	BIT(26)
+#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_MULT_SHIFT	8
 #define WZRD_CLKFBOUT_MULT_MASK		(0xff << WZRD_CLKFBOUT_MULT_SHIFT)
+#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		(0x3ff << WZRD_CLKFBOUT_FRAC_SHIFT)
+#define WZRD_VERSAL_FRAC_MASK		GENMASK(5, 0)
 #define WZRD_DIVCLK_DIVIDE_SHIFT	0
 #define WZRD_DIVCLK_DIVIDE_MASK		(0xff << WZRD_DIVCLK_DIVIDE_SHIFT)
 #define WZRD_CLKOUT_DIVIDE_SHIFT	0
@@ -45,6 +71,7 @@ 
 #define WZRD_DR_STATUS_REG_OFFSET	0x04
 #define WZRD_DR_LOCK_BIT_MASK		0x00000001
 #define WZRD_DR_INIT_REG_OFFSET		0x25C
+#define WZRD_DR_INIT_VERSAL_OFFSET	0x14
 #define WZRD_DR_DIV_TO_PHASE_OFFSET	4
 #define WZRD_DR_BEGIN_DYNA_RECONF	0x03
 #define WZRD_DR_BEGIN_DYNA_RECONF_5_2	0x07
@@ -52,6 +79,8 @@ 
 
 #define WZRD_USEC_POLL		10
 #define WZRD_TIMEOUT_POLL		1000
+#define WZRD_FRAC_GRADIENT		64
+#define PREDIV2_MULT			2
 
 /* Divider limits, from UG572 Table 3-4 for Ultrascale+ */
 #define DIV_O				0x01
@@ -65,6 +94,14 @@ 
 #define WZRD_VCO_MAX			1600000000
 #define WZRD_O_MIN			1
 #define WZRD_O_MAX			128
+#define VER_WZRD_M_MIN			4
+#define VER_WZRD_M_MAX			432
+#define VER_WZRD_D_MIN			1
+#define VER_WZRD_D_MAX			123
+#define VER_WZRD_VCO_MIN		2160000000
+#define VER_WZRD_VCO_MAX		4320000000
+#define VER_WZRD_O_MIN			2
+#define VER_WZRD_O_MAX			511
 #define WZRD_MIN_ERR			20000
 #define WZRD_FRAC_POINTS		1000
 
@@ -120,6 +157,7 @@  struct clk_wzrd {
  * @d:	value of the common divider
  * @o:	value of the leaf divider
  * @lock:	register lock
+ * @is_versal:	Flag indicating if it versal device
  */
 struct clk_wzrd_divider {
 	struct clk_hw hw;
@@ -133,6 +171,11 @@  struct clk_wzrd_divider {
 	u32 d;
 	u32 o;
 	spinlock_t *lock;  /* divider lock */
+	bool is_versal;
+};
+
+struct versal_clk_data {
+	bool is_versal;
 };
 
 #define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
@@ -152,51 +195,98 @@  static unsigned long clk_wzrd_recalc_rate(struct clk_hw *hw,
 {
 	struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
 	void __iomem *div_addr = divider->base + divider->offset;
-	unsigned int val;
+	u32 div, p5en, edge, prediv2, all;
+	unsigned int val, vall, valh;
 
-	val = readl(div_addr) >> divider->shift;
-	val &= div_mask(divider->width);
+	if (!divider->is_versal) {
+		val = readl(div_addr) >> divider->shift;
+		val &= div_mask(divider->width);
 
-	return divider_recalc_rate(hw, parent_rate, val, divider->table,
-			divider->flags, divider->width);
+		return divider_recalc_rate(hw, parent_rate, val, divider->table,
+				divider->flags, divider->width);
+	}
+
+	edge = !!(readl(div_addr) & WZRD_CLKFBOUT_EDGE);
+	p5en = !!(readl(div_addr) & WZRD_P5EN);
+	prediv2 = !!(readl(div_addr) & WZRD_CLKOUT0_PREDIV2);
+	vall = readl(div_addr + 4) & WZRD_CLKFBOUT_L_MASK;
+	valh = readl(div_addr + 4) >> WZRD_CLKFBOUT_H_SHIFT;
+	all = valh + vall + edge;
+	if (!all)
+		all = 1;
+
+	if (prediv2)
+		div = 2 * all + prediv2 * p5en;
+	else
+		div = all;
+
+	return DIV_ROUND_UP_ULL((u64)parent_rate, div);
 }
 
 static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
 				     unsigned long parent_rate)
 {
-	int err;
-	u32 value;
-	unsigned long flags = 0;
 	struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
 	void __iomem *div_addr = divider->base + divider->offset;
+	u32 value, regh, edged, p5en, p5fedge, regval, regval1;
+	unsigned long flags = 0;
+	int err;
 
 	if (divider->lock)
 		spin_lock_irqsave(divider->lock, flags);
 	else
 		__acquire(divider->lock);
 
-	value = DIV_ROUND_CLOSEST(parent_rate, rate);
-
-	/* Cap the value to max */
-	min_t(u32, value, WZRD_DR_MAX_INT_DIV_VALUE);
-
-	/* Set divisor and clear phase offset */
-	writel(value, div_addr);
-	writel(0x00, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
-
-	/* Check status register */
-	err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
-				 value, value & WZRD_DR_LOCK_BIT_MASK,
-				 WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
-	if (err)
-		goto err_reconfig;
-
-	/* Initiate reconfiguration */
-	writel(WZRD_DR_BEGIN_DYNA_RECONF_5_2,
-	       divider->base + WZRD_DR_INIT_REG_OFFSET);
-	writel(WZRD_DR_BEGIN_DYNA_RECONF1_5_2,
-	       divider->base + WZRD_DR_INIT_REG_OFFSET);
-
+	if (!divider->is_versal) {
+		value = DIV_ROUND_CLOSEST(parent_rate, rate);
+
+		/* Cap the value to max */
+		min_t(u32, value, WZRD_DR_MAX_INT_DIV_VALUE);
+
+		/* Set divisor and clear phase offset */
+		writel(value, div_addr);
+		writel(0x00, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
+
+		/* Check status register */
+		err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
+					 value, value & WZRD_DR_LOCK_BIT_MASK,
+					 WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
+		if (err)
+			goto err_reconfig;
+
+		/* Initiate reconfiguration */
+		writel(WZRD_DR_BEGIN_DYNA_RECONF_5_2,
+		       divider->base + WZRD_DR_INIT_REG_OFFSET);
+		writel(WZRD_DR_BEGIN_DYNA_RECONF1_5_2,
+		       divider->base + WZRD_DR_INIT_REG_OFFSET);
+
+	} else {
+		regh = (value / 4);
+		regval1 = readl(div_addr);
+		regval1 |= WZRD_CLKFBOUT_PREDIV2;
+		regval1 = regval1 & ~(WZRD_CLKFBOUT_EDGE | WZRD_P5EN | WZRD_P5FEDGE);
+		if (value % 4 > 1) {
+			edged = 1;
+			regval1 |= (edged << WZRD_EDGE_SHIFT);
+		}
+		p5fedge = value % 2;
+		p5en = value % 2;
+		regval1 = regval1 | p5en << WZRD_P5EN_SHIFT | p5fedge << WZRD_P5FEDGE_SHIFT;
+		writel(regval1, div_addr);
+
+		regval = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
+		writel(regval, div_addr + 4);
+		/* Check status register */
+		err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
+					 value, value & WZRD_DR_LOCK_BIT_MASK,
+					 WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
+		if (err)
+			goto err_reconfig;
+
+		/* Initiate reconfiguration */
+		writel(WZRD_DR_BEGIN_DYNA_RECONF,
+		       divider->base + WZRD_DR_INIT_VERSAL_OFFSET);
+	}
 	/* Check status register */
 	err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
 				 value, value & WZRD_DR_LOCK_BIT_MASK,
@@ -227,14 +317,35 @@  static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
 				 unsigned long parent_rate)
 {
 	struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
-	unsigned long vco_freq, freq, diff;
+	unsigned long vco_freq, freq, diff, vcomin, vcomax;
 	u32 m, d, o;
+	u32 mmin, mmax, dmin, dmax, omin, omax;
+
+	if (divider->is_versal) {
+		mmin = VER_WZRD_M_MIN;
+		mmax = VER_WZRD_M_MAX;
+		dmin = VER_WZRD_D_MIN;
+		dmax = VER_WZRD_D_MAX;
+		omin = VER_WZRD_O_MIN;
+		omax = VER_WZRD_O_MAX;
+		vcomin = VER_WZRD_VCO_MIN;
+		vcomax = VER_WZRD_VCO_MAX;
+	} else {
+		mmin = WZRD_M_MIN;
+		mmax = WZRD_M_MAX;
+		dmin = WZRD_D_MIN;
+		dmax = WZRD_D_MAX;
+		omin = WZRD_O_MIN;
+		omax = WZRD_O_MAX;
+		vcomin = WZRD_VCO_MIN;
+		vcomax = WZRD_VCO_MAX;
+	}
 
-	for (m = WZRD_M_MIN; m <= WZRD_M_MAX; m++) {
-		for (d = WZRD_D_MIN; d <= WZRD_D_MAX; d++) {
+	for (m = mmin; m <= mmax; m++) {
+		for (d = dmin; d <= dmax; d++) {
 			vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d);
-			if (vco_freq >= WZRD_VCO_MIN && vco_freq <= WZRD_VCO_MAX) {
-				for (o = WZRD_O_MIN; o <= WZRD_O_MAX; o++) {
+			if (vco_freq >= vcomin && vco_freq <= vcomax) {
+				for (o = omin; o <= omax; o++) {
 					freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
 					diff = abs(freq - rate);
 
@@ -254,8 +365,10 @@  static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
 static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
 				       unsigned long parent_rate)
 {
+	u32 regh, edged, p5en, p5fedge, value2, m, regval, regval1;
 	struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
 	unsigned long vco_freq, rate_div, clockout0_div;
+	void __iomem *div_addr = divider->base;
 	u32 reg, pre, value, f;
 	int err;
 
@@ -263,25 +376,80 @@  static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
 	if (err)
 		return err;
 
-	vco_freq = DIV_ROUND_CLOSEST(parent_rate * divider->m, divider->d);
-	rate_div = DIV_ROUND_CLOSEST_ULL((vco_freq * WZRD_FRAC_POINTS), rate);
-
-	clockout0_div = div_u64(rate_div,  WZRD_FRAC_POINTS);
-
-	pre = DIV_ROUND_CLOSEST_ULL(vco_freq * WZRD_FRAC_POINTS, rate);
-	f = (pre - (clockout0_div * WZRD_FRAC_POINTS));
-	f &= WZRD_CLKOUT_FRAC_MASK;
-
-	reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
-	      FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, f);
+	if (divider->is_versal) {
+		writel(0, divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_CLKFBOUT_4));
+
+		m = divider->m;
+		edged = m % WZRD_DUTY_CYCLE;
+		regh = m / WZRD_DUTY_CYCLE;
+		regval1 = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal,
+								 WZRD_CLKFBOUT_1));
+		regval1 |= WZRD_MULT_PREDIV2;
+		if (edged)
+			regval1 = regval1 | WZRD_CLKFBOUT_EDGE;
+		else
+			regval1 = regval1 & ~WZRD_CLKFBOUT_EDGE;
+
+		writel(regval1, divider->base + WZRD_CLK_CFG_REG(divider->is_versal,
+								 WZRD_CLKFBOUT_1));
+		regval1 = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
+		writel(regval1, divider->base + WZRD_CLK_CFG_REG(divider->is_versal,
+								 WZRD_CLKFBOUT_2));
+
+		value2 = divider->d;
+		edged = value2 % WZRD_DUTY_CYCLE;
+		regh = (value2 / WZRD_DUTY_CYCLE);
+		regval1 = FIELD_PREP(WZRD_DIVCLK_EDGE, edged);
+		writel(regval1, divider->base + WZRD_CLK_CFG_REG(divider->is_versal,
+								 WZRD_DESKEW_2));
+		regval1 = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
+		writel(regval1, divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_DIVCLK));
+
+		value = divider->o;
+		regh = value / WZRD_O_DIV;
+		regval1 = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal,
+								 WZRD_CLKOUT0_1));
+		regval1 |= WZRD_CLKFBOUT_PREDIV2;
+		regval1 = regval1 & ~(WZRD_CLKFBOUT_EDGE | WZRD_P5EN | WZRD_P5FEDGE);
+
+		if (value % WZRD_O_DIV > 1) {
+			edged = 1;
+			regval1 |= edged << WZRD_CLKFBOUT_H_SHIFT;
+		}
 
-	writel(reg, divider->base + WZRD_CLK_CFG_REG(2));
-	/* Set divisor and clear phase offset */
-	reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->m) |
-	      FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->d);
-	writel(reg, divider->base + WZRD_CLK_CFG_REG(0));
-	writel(divider->o, divider->base + WZRD_CLK_CFG_REG(2));
-	writel(0, divider->base + WZRD_CLK_CFG_REG(3));
+		p5fedge = value % WZRD_DUTY_CYCLE;
+		p5en = value % WZRD_DUTY_CYCLE;
+
+		regval1 = regval1 | FIELD_PREP(WZRD_P5EN, p5en) | FIELD_PREP(WZRD_P5FEDGE, p5fedge);
+		writel(regval1, divider->base + WZRD_CLK_CFG_REG(divider->is_versal,
+								 WZRD_CLKOUT0_1));
+		regval = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
+		writel(regval, divider->base + WZRD_CLK_CFG_REG(divider->is_versal,
+								WZRD_CLKOUT0_2));
+		div_addr = divider->base + WZRD_DR_INIT_VERSAL_OFFSET;
+
+	} else {
+		vco_freq = DIV_ROUND_CLOSEST(parent_rate * divider->m, divider->d);
+		rate_div = DIV_ROUND_CLOSEST_ULL((vco_freq * WZRD_FRAC_POINTS), rate);
+
+		clockout0_div = div_u64(rate_div,  WZRD_FRAC_POINTS);
+
+		pre = DIV_ROUND_CLOSEST_ULL(vco_freq * WZRD_FRAC_POINTS, rate);
+		f = (pre - (clockout0_div * WZRD_FRAC_POINTS));
+		f &= WZRD_CLKOUT_FRAC_MASK;
+
+		reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
+		      FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, f);
+
+		writel(reg, divider->base + WZRD_CLK_CFG_REG(divider->is_versal, 2));
+		/* Set divisor and clear phase offset */
+		reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->m) |
+		      FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->d);
+		writel(reg, divider->base + WZRD_CLK_CFG_REG(divider->is_versal, 0));
+		writel(divider->o, divider->base + WZRD_CLK_CFG_REG(divider->is_versal, 2));
+		writel(0, divider->base + WZRD_CLK_CFG_REG(divider->is_versal, 3));
+		div_addr = divider->base + WZRD_DR_INIT_REG_OFFSET;
+	}
 	/* Check status register */
 	err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, value,
 				 value & WZRD_DR_LOCK_BIT_MASK,
@@ -290,9 +458,7 @@  static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
 		return -ETIMEDOUT;
 
 	/* Initiate reconfiguration */
-	writel(WZRD_DR_BEGIN_DYNA_RECONF,
-	       divider->base + WZRD_DR_INIT_REG_OFFSET);
-
+	writel(WZRD_DR_BEGIN_DYNA_RECONF, div_addr);
 	/* Check status register */
 	return readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, value,
 				 value & WZRD_DR_LOCK_BIT_MASK,
@@ -319,17 +485,77 @@  static unsigned long clk_wzrd_recalc_rate_all(struct clk_hw *hw,
 					      unsigned long parent_rate)
 {
 	struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+	u32 edged, div2, p5en, edge, prediv2, all, regl, regh, mult;
 	u32 m, d, o, div, reg, f;
 
-	reg = readl(divider->base + WZRD_CLK_CFG_REG(0));
-	d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
-	m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg);
-	reg = readl(divider->base + WZRD_CLK_CFG_REG(2));
-	o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
-	f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg);
+	if (!divider->is_versal) {
+		reg = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, 0));
+		d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
+		m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg);
+		reg = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, 2));
+		o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
+		f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg);
+
+		div = DIV_ROUND_CLOSEST(d * (WZRD_FRAC_POINTS * o + f), WZRD_FRAC_POINTS);
+		return divider_recalc_rate(hw, parent_rate * m, div, divider->table,
+			divider->flags, divider->width);
+	}
+	edge = !!(readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_CLKFBOUT_1)) &
+			WZRD_CLKFBOUT_EDGE);
+
+	reg = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_CLKFBOUT_2));
+	regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
+	regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
+
+	mult = regl + regh + edge;
+	if (!mult)
+		mult = 1;
+
+	regl = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_CLKFBOUT_4)) &
+		     WZRD_CLKFBOUT_FRAC_EN;
+	if (regl) {
+		regl = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_CLKFBOUT_3))
+				& WZRD_VERSAL_FRAC_MASK;
+		mult = mult * WZRD_FRAC_GRADIENT + regl;
+		parent_rate = DIV_ROUND_CLOSEST((parent_rate * mult), WZRD_FRAC_GRADIENT);
+	} else {
+		parent_rate = parent_rate * mult;
+	}
+
+	/* O Calculation */
+	reg = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_CLKOUT0_1));
+	edged = FIELD_GET(WZRD_CLKFBOUT_EDGE, reg);
+	p5en = FIELD_GET(WZRD_P5EN, reg);
+	prediv2 = FIELD_GET(WZRD_CLKOUT0_PREDIV2, reg);
+
+	reg = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_CLKOUT0_2));
+	/* Low time */
+	regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
+	/* High time */
+	regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
+	all = regh + regl + edged;
+	if (!all)
+		all = 1;
+
+	if (prediv2)
+		div2 = PREDIV2_MULT * all + p5en;
+	else
+		div2 = all;
+
+	/* D calculation */
+	edged = !!(readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_DESKEW_2)) &
+		     WZRD_DIVCLK_EDGE);
+	reg = readl(divider->base + WZRD_CLK_CFG_REG(divider->is_versal, WZRD_DIVCLK));
+	/* Low time */
+	regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
+	/* High time */
+	regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
+	div = regl + regh + edged;
+	if (!div)
+		div = 1;
 
-	div = DIV_ROUND_CLOSEST(d * (WZRD_FRAC_POINTS * o + f), WZRD_FRAC_POINTS);
-	return divider_recalc_rate(hw, parent_rate * m, div, divider->table,
+	div = div * div2;
+	return divider_recalc_rate(hw, parent_rate, div, divider->table,
 			divider->flags, divider->width);
 }
 
@@ -492,6 +718,7 @@  static struct clk *clk_wzrd_register_divider(struct device *dev,
 					     u8 shift, u8 width,
 					     u8 clk_divider_flags,
 					     u32 div_type,
+					     bool is_versal,
 					     spinlock_t *lock)
 {
 	struct clk_wzrd_divider *div;
@@ -520,6 +747,7 @@  static struct clk *clk_wzrd_register_divider(struct device *dev,
 	div->width = width;
 	div->flags = clk_divider_flags;
 	div->lock = lock;
+	div->is_versal = is_versal;
 	div->hw.init = &init;
 
 	hw = &div->hw;
@@ -588,18 +816,34 @@  static int __maybe_unused clk_wzrd_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(clk_wzrd_dev_pm_ops, clk_wzrd_suspend,
 			 clk_wzrd_resume);
 
+static const struct versal_clk_data versal_data = {
+	.is_versal	= true,
+};
+
+static const struct of_device_id clk_wzrd_ids[] = {
+	{ .compatible = "xlnx,versal-clk-wizard", .data = &versal_data },
+	{ .compatible = "xlnx,clocking-wizard"   },
+	{ .compatible = "xlnx,clocking-wizard-v5.2"   },
+	{ .compatible = "xlnx,clocking-wizard-v6.0"  },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, clk_wzrd_ids);
+
 static int clk_wzrd_probe(struct platform_device *pdev)
 {
+	const char *clkout_name, *clk_name, *clk_mul_name;
+	u32 regl, regh, edge, regld, reghd, edged, div;
+	const struct versal_clk_data *data;
+	const struct of_device_id *match;
 	int i, ret;
 	u32 reg, reg_f, mult;
 	unsigned long rate;
-	const char *clk_name;
 	void __iomem *ctrl_reg;
 	struct clk_wzrd *clk_wzrd;
-	const char *clkout_name;
 	struct device_node *np = pdev->dev.of_node;
 	int nr_outputs;
 	unsigned long flags = 0;
+	bool is_versal = 0;
 
 	clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL);
 	if (!clk_wzrd)
@@ -647,27 +891,58 @@  static int clk_wzrd_probe(struct platform_device *pdev)
 		goto err_disable_clk;
 	}
 
+	match = of_match_node(clk_wzrd_ids, np);
+	if (!match) {
+		dev_err(&pdev->dev, "of_match_node failed\n");
+		return -ENODEV;
+	}
+
+	data = match->data;
+	if (data)
+		is_versal = data->is_versal;
+
 	clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev));
 	if (nr_outputs == 1) {
 		clk_wzrd->clkout[0] = clk_wzrd_register_divider
 				(&pdev->dev, clkout_name,
 				__clk_get_name(clk_wzrd->clk_in1), 0,
-				clk_wzrd->base, WZRD_CLK_CFG_REG(3),
+				clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3),
 				WZRD_CLKOUT_DIVIDE_SHIFT,
 				WZRD_CLKOUT_DIVIDE_WIDTH,
 				CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
-				DIV_ALL, &clkwzrd_lock);
+				DIV_ALL, is_versal, &clkwzrd_lock);
 
 		goto out;
 	}
-
-	reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0));
-	reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK;
-	reg_f =  reg_f >> WZRD_CLKFBOUT_FRAC_SHIFT;
-
-	reg = reg & WZRD_CLKFBOUT_MULT_MASK;
-	reg =  reg >> WZRD_CLKFBOUT_MULT_SHIFT;
-	mult = (reg * 1000) + reg_f;
+	if (is_versal) {
+		/* register multiplier */
+		edge = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)) &
+				BIT(8));
+		regl = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 1)) &
+			     WZRD_CLKFBOUT_L_MASK) >> WZRD_CLKFBOUT_L_SHIFT;
+		regh = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 1)) &
+			     WZRD_CLKFBOUT_H_MASK) >> WZRD_CLKFBOUT_H_SHIFT;
+		mult = regl + regh + edge;
+		if (!mult)
+			mult = 1;
+		mult = mult * WZRD_FRAC_GRADIENT;
+
+		regl = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 51)) &
+			     WZRD_CLKFBOUT_FRAC_EN;
+		if (regl) {
+			regl = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 48)) &
+				WZRD_VERSAL_FRAC_MASK;
+			mult = mult + regl;
+		}
+	} else {
+		reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0));
+		reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK;
+		reg_f =  reg_f >> WZRD_CLKFBOUT_FRAC_SHIFT;
+
+		reg = reg & WZRD_CLKFBOUT_MULT_MASK;
+		reg =  reg >> WZRD_CLKFBOUT_MULT_SHIFT;
+		mult = (reg * 1000) + reg_f;
+	}
 	clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev));
 	if (!clk_name) {
 		ret = -ENOMEM;
@@ -689,13 +964,29 @@  static int clk_wzrd_probe(struct platform_device *pdev)
 		goto err_rm_int_clk;
 	}
 
-	ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(0);
-	/* register div */
-	clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
+	if (is_versal) {
+		edged = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 20)) &
+			     BIT(10));
+		regld = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 21)) &
+			     WZRD_CLKFBOUT_L_MASK) >> WZRD_CLKFBOUT_L_SHIFT;
+		reghd = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 21)) &
+		     WZRD_CLKFBOUT_H_MASK) >> WZRD_CLKFBOUT_H_SHIFT;
+		div = (regld  + reghd + edged);
+		if (!div)
+			div = 1;
+
+		clk_mul_name = __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]);
+		clk_wzrd->clks_internal[wzrd_clk_mul_div] =
+			clk_register_fixed_factor(&pdev->dev, clk_name,
+						  clk_mul_name, 0, 1, div);
+	} else {
+		ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0);
+		clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
 			(&pdev->dev, clk_name,
 			 __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
 			flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED |
 			CLK_DIVIDER_ALLOW_ZERO, &clkwzrd_lock);
+	}
 	if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) {
 		dev_err(&pdev->dev, "unable to register divider clock\n");
 		ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]);
@@ -711,24 +1002,35 @@  static int clk_wzrd_probe(struct platform_device *pdev)
 			goto err_rm_int_clk;
 		}
 
-		if (!i)
-			clk_wzrd->clkout[i] = clk_wzrd_register_divf
-				(&pdev->dev, clkout_name,
-				clk_name, flags,
-				clk_wzrd->base, (WZRD_CLK_CFG_REG(2) + i * 12),
-				WZRD_CLKOUT_DIVIDE_SHIFT,
-				WZRD_CLKOUT_DIVIDE_WIDTH,
-				CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
-				DIV_O, &clkwzrd_lock);
-		else
+		if (is_versal) {
 			clk_wzrd->clkout[i] = clk_wzrd_register_divider
-				(&pdev->dev, clkout_name,
-				clk_name, 0,
-				clk_wzrd->base, (WZRD_CLK_CFG_REG(2) + i * 12),
-				WZRD_CLKOUT_DIVIDE_SHIFT,
-				WZRD_CLKOUT_DIVIDE_WIDTH,
-				CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
-				DIV_O, &clkwzrd_lock);
+						(&pdev->dev,
+						 clkout_name, clk_name, 0,
+						 clk_wzrd->base,
+						 (WZRD_CLK_CFG_REG(is_versal, 3) + i * 8),
+						 WZRD_CLKOUT_DIVIDE_SHIFT,
+						 WZRD_CLKOUT_DIVIDE_WIDTH,
+						 CLK_DIVIDER_ONE_BASED |
+						 CLK_DIVIDER_ALLOW_ZERO,
+						 DIV_O, true, &clkwzrd_lock);
+		} else {
+			if (!i)
+				clk_wzrd->clkout[i] = clk_wzrd_register_divf
+					(&pdev->dev, clkout_name, clk_name, flags, clk_wzrd->base,
+					(WZRD_CLK_CFG_REG(is_versal, 2) + i * 12),
+					WZRD_CLKOUT_DIVIDE_SHIFT,
+					WZRD_CLKOUT_DIVIDE_WIDTH,
+					CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+					DIV_O, &clkwzrd_lock);
+			else
+				clk_wzrd->clkout[i] = clk_wzrd_register_divider
+					(&pdev->dev, clkout_name, clk_name, 0, clk_wzrd->base,
+					(WZRD_CLK_CFG_REG(is_versal, 2) + i * 12),
+					WZRD_CLKOUT_DIVIDE_SHIFT,
+					WZRD_CLKOUT_DIVIDE_WIDTH,
+					CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+					DIV_O, false,  &clkwzrd_lock);
+		}
 		if (IS_ERR(clk_wzrd->clkout[i])) {
 			int j;
 
@@ -793,14 +1095,6 @@  static void clk_wzrd_remove(struct platform_device *pdev)
 	clk_disable_unprepare(clk_wzrd->axi_clk);
 }
 
-static const struct of_device_id clk_wzrd_ids[] = {
-	{ .compatible = "xlnx,clocking-wizard" },
-	{ .compatible = "xlnx,clocking-wizard-v5.2" },
-	{ .compatible = "xlnx,clocking-wizard-v6.0" },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, clk_wzrd_ids);
-
 static struct platform_driver clk_wzrd_driver = {
 	.driver = {
 		.name = "clk-wizard",