soc: xilinx: vcu: register PLL as fixed rate clock
authorMichael Tretter <m.tretter@pengutronix.de>
Thu, 21 Jan 2021 07:16:51 +0000 (08:16 +0100)
committerStephen Boyd <sboyd@kernel.org>
Tue, 9 Feb 2021 02:31:25 +0000 (18:31 -0800)
Currently, xvcu_pll_set_rate configures the PLL to a clock rate that is
pre-calculated when probing the driver. To still make the clock
framework aware of the PLL and to allow to configure other clocks based
on the PLL rate, register the PLL as a fixed rate clock.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Acked-by: Michal Simek <michal.simek@xilinx.com>
Link: https://lore.kernel.org/r/20210121071659.1226489-8-m.tretter@pengutronix.de
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
drivers/soc/xilinx/Kconfig
drivers/soc/xilinx/xlnx_vcu.c

index 0b1708dae361e3afea56db98e7ee8fd5fce03777..9fe703772e5ac8806e565e7bde4e14a90e39c884 100644 (file)
@@ -3,7 +3,7 @@ menu "Xilinx SoC drivers"
 
 config XILINX_VCU
        tristate "Xilinx VCU logicoreIP Init"
-       depends on HAS_IOMEM
+       depends on HAS_IOMEM && COMMON_CLK
        select REGMAP_MMIO
        help
          Provides the driver to enable and disable the isolation between the
index 34f3299afc0d756c62e3a90fe7dc7b5f6e41ff23..6a733a1819825d67d5ec7a89e5486bf423f91762 100644 (file)
@@ -7,6 +7,7 @@
  * Contacts   Dhaval Shah <dshah@xilinx.com>
  */
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/io.h>
@@ -73,6 +74,7 @@
  * @aclk: axi clock source
  * @logicore_reg_ba: logicore reg base address
  * @vcu_slcr_ba: vcu_slcr Register base address
+ * @pll: handle for the VCU PLL
  */
 struct xvcu_device {
        struct device *dev;
@@ -80,6 +82,7 @@ struct xvcu_device {
        struct clk *aclk;
        struct regmap *logicore_reg_ba;
        void __iomem *vcu_slcr_ba;
+       struct clk_hw *pll;
 };
 
 static struct regmap_config vcu_settings_regmap_config = {
@@ -403,7 +406,9 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu)
        u32 clkoutdiv, vcu_pll_ctrl, pll_clk;
        u32 mod, ctrl;
        int i;
+       int ret;
        const struct xvcu_pll_cfg *found = NULL;
+       struct clk_hw *hw;
 
        regmap_read(xvcu->logicore_reg_ba, VCU_PLL_CLK, &inte);
        regmap_read(xvcu->logicore_reg_ba, VCU_PLL_CLK_DEC, &deci);
@@ -505,7 +510,18 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu)
        ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) << VCU_SRCSEL_SHIFT;
        xvcu_write(xvcu->vcu_slcr_ba, VCU_DEC_MCU_CTRL, ctrl);
 
-       return xvcu_pll_set_rate(xvcu, fvco, refclk);
+       ret = xvcu_pll_set_rate(xvcu, fvco, refclk);
+       if (ret)
+               return ret;
+
+       hw = clk_hw_register_fixed_rate(xvcu->dev, "vcu_pll",
+                                       __clk_get_name(xvcu->pll_ref),
+                                       0, pll_clk);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       xvcu->pll = hw;
+
+       return 0;
 }
 
 /**
@@ -652,6 +668,7 @@ static int xvcu_remove(struct platform_device *pdev)
        /* Add the the Gasket isolation and put the VCU in reset. */
        regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0);
 
+       clk_hw_unregister_fixed_rate(xvcu->pll);
        xvcu_pll_disable(xvcu);
        clk_disable_unprepare(xvcu->aclk);