From: Michael Tretter <m.tretter@pengutronix.de> To: linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Cc: m.mtretter@pengutronix.de, michals@xilinx.com, kernel@pengutronix.de, mturquette@baylibre.com, sboyd@kernel.org Subject: [PATCH v3 09/15] soc: xilinx: vcu: make pll post divider explicit Date: Thu, 21 Jan 2021 08:16:53 +0100 [thread overview] Message-ID: <20210121071659.1226489-10-m.tretter@pengutronix.de> (raw) In-Reply-To: <20210121071659.1226489-1-m.tretter@pengutronix.de> According to the downstream driver documentation due to timing constraints the output divider of the PLL has to be set to 1/2. Add a helper function for that check instead of burying the code in one large setup function. The bit is undocumented and marked as reserved in the register reference. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> Acked-by: Michal Simek <michal.simek@xilinx.com> --- Changelog: v3: - Add kernel doc for pll_post v2: - Use clk_hw instead of name in xvcu_register_pll_post --- drivers/soc/xilinx/xlnx_vcu.c | 52 ++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/soc/xilinx/xlnx_vcu.c b/drivers/soc/xilinx/xlnx_vcu.c index e38e9c8325a7..9e410d7ffd08 100644 --- a/drivers/soc/xilinx/xlnx_vcu.c +++ b/drivers/soc/xilinx/xlnx_vcu.c @@ -72,6 +72,7 @@ * @logicore_reg_ba: logicore reg base address * @vcu_slcr_ba: vcu_slcr Register base address * @pll: handle for the VCU PLL + * @pll_post: handle for the VCU PLL post divider * @clk_data: clocks provided by the vcu clock provider */ struct xvcu_device { @@ -81,6 +82,7 @@ struct xvcu_device { struct regmap *logicore_reg_ba; void __iomem *vcu_slcr_ba; struct clk_hw *pll; + struct clk_hw *pll_post; struct clk_hw_onecell_data *clk_data; }; @@ -274,6 +276,29 @@ static int xvcu_pll_wait_for_lock(struct xvcu_device *xvcu) return -ETIMEDOUT; } +static struct clk_hw *xvcu_register_pll_post(struct device *dev, + const char *name, + const struct clk_hw *parent_hw, + void __iomem *reg_base) +{ + u32 div; + u32 vcu_pll_ctrl; + + /* + * The output divider of the PLL must be set to 1/2 to meet the + * timing in the design. + */ + vcu_pll_ctrl = xvcu_read(reg_base, VCU_PLL_CTRL); + div = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT; + div = div & VCU_PLL_CTRL_CLKOUTDIV_MASK; + if (div != 1) + return ERR_PTR(-EINVAL); + + return clk_hw_register_fixed_factor(dev, "vcu_pll_post", + clk_hw_get_name(parent_hw), + CLK_SET_RATE_PARENT, 1, 2); +} + static const struct xvcu_pll_cfg *xvcu_find_cfg(int div) { const struct xvcu_pll_cfg *cfg = NULL; @@ -402,7 +427,7 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) { u32 refclk, coreclk, mcuclk, inte, deci; u32 divisor_mcu, divisor_core, fvco; - u32 clkoutdiv, vcu_pll_ctrl, pll_clk; + u32 pll_clk; u32 mod; int i; int ret; @@ -425,19 +450,6 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) dev_dbg(xvcu->dev, "Core clock from logicoreIP is %uHz\n", coreclk); dev_dbg(xvcu->dev, "Mcu clock from logicoreIP is %uHz\n", mcuclk); - /* - * The divide-by-2 should be always enabled (==1) - * to meet the timing in the design. - * Otherwise, it's an error - */ - vcu_pll_ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_PLL_CTRL); - clkoutdiv = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT; - clkoutdiv = clkoutdiv & VCU_PLL_CTRL_CLKOUTDIV_MASK; - if (clkoutdiv != 1) { - dev_err(xvcu->dev, "clkoutdiv value is invalid\n"); - return -EINVAL; - } - for (i = ARRAY_SIZE(xvcu_pll_cfg) - 1; i >= 0; i--) { const struct xvcu_pll_cfg *cfg = &xvcu_pll_cfg[i]; @@ -484,7 +496,7 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) hw = clk_hw_register_fixed_rate(xvcu->dev, "vcu_pll", __clk_get_name(xvcu->pll_ref), - 0, pll_clk); + 0, fvco); if (IS_ERR(hw)) return PTR_ERR(hw); xvcu->pll = hw; @@ -607,6 +619,7 @@ static int xvcu_register_clock_provider(struct xvcu_device *xvcu) struct clk_parent_data parent_data[2] = { 0 }; struct clk_hw_onecell_data *data; struct clk_hw **hws; + struct clk_hw *hw; void __iomem *reg_base = xvcu->vcu_slcr_ba; data = devm_kzalloc(dev, struct_size(data, hws, CLK_XVCU_NUM_CLOCKS), GFP_KERNEL); @@ -617,8 +630,13 @@ static int xvcu_register_clock_provider(struct xvcu_device *xvcu) xvcu->clk_data = data; + hw = xvcu_register_pll_post(dev, "vcu_pll_post", xvcu->pll, reg_base); + if (IS_ERR(hw)) + return PTR_ERR(hw); + xvcu->pll_post = hw; + parent_data[0].fw_name = "pll_ref"; - parent_data[1].hw = xvcu->pll; + parent_data[1].hw = xvcu->pll_post; hws[CLK_XVCU_ENC_CORE] = xvcu_clk_hw_register_leaf(dev, "venc_core_clk", @@ -657,6 +675,8 @@ static void xvcu_unregister_clock_provider(struct xvcu_device *xvcu) xvcu_clk_hw_unregister_leaf(hws[CLK_XVCU_ENC_MCU]); if (!IS_ERR_OR_NULL(hws[CLK_XVCU_ENC_CORE])) xvcu_clk_hw_unregister_leaf(hws[CLK_XVCU_ENC_CORE]); + + clk_hw_unregister_fixed_factor(xvcu->pll_post); } /** -- 2.20.1
WARNING: multiple messages have this Message-ID (diff)
From: Michael Tretter <m.tretter@pengutronix.de> To: linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Cc: sboyd@kernel.org, mturquette@baylibre.com, m.mtretter@pengutronix.de, michals@xilinx.com, kernel@pengutronix.de Subject: [PATCH v3 09/15] soc: xilinx: vcu: make pll post divider explicit Date: Thu, 21 Jan 2021 08:16:53 +0100 [thread overview] Message-ID: <20210121071659.1226489-10-m.tretter@pengutronix.de> (raw) In-Reply-To: <20210121071659.1226489-1-m.tretter@pengutronix.de> According to the downstream driver documentation due to timing constraints the output divider of the PLL has to be set to 1/2. Add a helper function for that check instead of burying the code in one large setup function. The bit is undocumented and marked as reserved in the register reference. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> Acked-by: Michal Simek <michal.simek@xilinx.com> --- Changelog: v3: - Add kernel doc for pll_post v2: - Use clk_hw instead of name in xvcu_register_pll_post --- drivers/soc/xilinx/xlnx_vcu.c | 52 ++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/soc/xilinx/xlnx_vcu.c b/drivers/soc/xilinx/xlnx_vcu.c index e38e9c8325a7..9e410d7ffd08 100644 --- a/drivers/soc/xilinx/xlnx_vcu.c +++ b/drivers/soc/xilinx/xlnx_vcu.c @@ -72,6 +72,7 @@ * @logicore_reg_ba: logicore reg base address * @vcu_slcr_ba: vcu_slcr Register base address * @pll: handle for the VCU PLL + * @pll_post: handle for the VCU PLL post divider * @clk_data: clocks provided by the vcu clock provider */ struct xvcu_device { @@ -81,6 +82,7 @@ struct xvcu_device { struct regmap *logicore_reg_ba; void __iomem *vcu_slcr_ba; struct clk_hw *pll; + struct clk_hw *pll_post; struct clk_hw_onecell_data *clk_data; }; @@ -274,6 +276,29 @@ static int xvcu_pll_wait_for_lock(struct xvcu_device *xvcu) return -ETIMEDOUT; } +static struct clk_hw *xvcu_register_pll_post(struct device *dev, + const char *name, + const struct clk_hw *parent_hw, + void __iomem *reg_base) +{ + u32 div; + u32 vcu_pll_ctrl; + + /* + * The output divider of the PLL must be set to 1/2 to meet the + * timing in the design. + */ + vcu_pll_ctrl = xvcu_read(reg_base, VCU_PLL_CTRL); + div = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT; + div = div & VCU_PLL_CTRL_CLKOUTDIV_MASK; + if (div != 1) + return ERR_PTR(-EINVAL); + + return clk_hw_register_fixed_factor(dev, "vcu_pll_post", + clk_hw_get_name(parent_hw), + CLK_SET_RATE_PARENT, 1, 2); +} + static const struct xvcu_pll_cfg *xvcu_find_cfg(int div) { const struct xvcu_pll_cfg *cfg = NULL; @@ -402,7 +427,7 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) { u32 refclk, coreclk, mcuclk, inte, deci; u32 divisor_mcu, divisor_core, fvco; - u32 clkoutdiv, vcu_pll_ctrl, pll_clk; + u32 pll_clk; u32 mod; int i; int ret; @@ -425,19 +450,6 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) dev_dbg(xvcu->dev, "Core clock from logicoreIP is %uHz\n", coreclk); dev_dbg(xvcu->dev, "Mcu clock from logicoreIP is %uHz\n", mcuclk); - /* - * The divide-by-2 should be always enabled (==1) - * to meet the timing in the design. - * Otherwise, it's an error - */ - vcu_pll_ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_PLL_CTRL); - clkoutdiv = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT; - clkoutdiv = clkoutdiv & VCU_PLL_CTRL_CLKOUTDIV_MASK; - if (clkoutdiv != 1) { - dev_err(xvcu->dev, "clkoutdiv value is invalid\n"); - return -EINVAL; - } - for (i = ARRAY_SIZE(xvcu_pll_cfg) - 1; i >= 0; i--) { const struct xvcu_pll_cfg *cfg = &xvcu_pll_cfg[i]; @@ -484,7 +496,7 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) hw = clk_hw_register_fixed_rate(xvcu->dev, "vcu_pll", __clk_get_name(xvcu->pll_ref), - 0, pll_clk); + 0, fvco); if (IS_ERR(hw)) return PTR_ERR(hw); xvcu->pll = hw; @@ -607,6 +619,7 @@ static int xvcu_register_clock_provider(struct xvcu_device *xvcu) struct clk_parent_data parent_data[2] = { 0 }; struct clk_hw_onecell_data *data; struct clk_hw **hws; + struct clk_hw *hw; void __iomem *reg_base = xvcu->vcu_slcr_ba; data = devm_kzalloc(dev, struct_size(data, hws, CLK_XVCU_NUM_CLOCKS), GFP_KERNEL); @@ -617,8 +630,13 @@ static int xvcu_register_clock_provider(struct xvcu_device *xvcu) xvcu->clk_data = data; + hw = xvcu_register_pll_post(dev, "vcu_pll_post", xvcu->pll, reg_base); + if (IS_ERR(hw)) + return PTR_ERR(hw); + xvcu->pll_post = hw; + parent_data[0].fw_name = "pll_ref"; - parent_data[1].hw = xvcu->pll; + parent_data[1].hw = xvcu->pll_post; hws[CLK_XVCU_ENC_CORE] = xvcu_clk_hw_register_leaf(dev, "venc_core_clk", @@ -657,6 +675,8 @@ static void xvcu_unregister_clock_provider(struct xvcu_device *xvcu) xvcu_clk_hw_unregister_leaf(hws[CLK_XVCU_ENC_MCU]); if (!IS_ERR_OR_NULL(hws[CLK_XVCU_ENC_CORE])) xvcu_clk_hw_unregister_leaf(hws[CLK_XVCU_ENC_CORE]); + + clk_hw_unregister_fixed_factor(xvcu->pll_post); } /** -- 2.20.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-01-21 7:20 UTC|newest] Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-01-21 7:16 [PATCH v3 00/15] soc: xilinx: vcu: Convert driver to clock provider Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-01-21 7:16 ` [PATCH v3 01/15] ARM: dts: vcu: define indexes for output clocks Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:32 ` Stephen Boyd 2021-02-09 2:32 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 02/15] clk: divider: fix initialization with parent_hw Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:32 ` Stephen Boyd 2021-02-09 2:32 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 03/15] soc: xilinx: vcu: drop coreclk from struct xlnx_vcu Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:32 ` Stephen Boyd 2021-02-09 2:32 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 04/15] soc: xilinx: vcu: add helper to wait for PLL locked Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:32 ` Stephen Boyd 2021-02-09 2:32 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 05/15] soc: xilinx: vcu: add helpers for configuring PLL Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:32 ` Stephen Boyd 2021-02-09 2:32 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 06/15] soc: xilinx: vcu: implement PLL disable Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:32 ` Stephen Boyd 2021-02-09 2:32 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 07/15] soc: xilinx: vcu: register PLL as fixed rate clock Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:32 ` Stephen Boyd 2021-02-09 2:32 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 08/15] soc: xilinx: vcu: implement clock provider for output clocks Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:35 ` Stephen Boyd 2021-02-09 2:35 ` Stephen Boyd 2021-01-21 7:16 ` Michael Tretter [this message] 2021-01-21 7:16 ` [PATCH v3 09/15] soc: xilinx: vcu: make pll post divider explicit Michael Tretter 2021-02-09 2:35 ` Stephen Boyd 2021-02-09 2:35 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 10/15] soc: xilinx: vcu: make the PLL configurable Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:35 ` Stephen Boyd 2021-02-09 2:35 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 11/15] soc: xilinx: vcu: remove calculation of PLL configuration Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:35 ` Stephen Boyd 2021-02-09 2:35 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 12/15] soc: xilinx: vcu: use bitfields for register definition Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:35 ` Stephen Boyd 2021-02-09 2:35 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 13/15] soc: xilinx: vcu: fix repeated word the in comment Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:35 ` Stephen Boyd 2021-02-09 2:35 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 14/15] soc: xilinx: vcu: fix alignment to open parenthesis Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:35 ` Stephen Boyd 2021-02-09 2:35 ` Stephen Boyd 2021-01-21 7:16 ` [PATCH v3 15/15] clk: xilinx: move xlnx_vcu clock driver from soc Michael Tretter 2021-01-21 7:16 ` Michael Tretter 2021-02-09 2:35 ` Stephen Boyd 2021-02-09 2:35 ` Stephen Boyd
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210121071659.1226489-10-m.tretter@pengutronix.de \ --to=m.tretter@pengutronix.de \ --cc=kernel@pengutronix.de \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-clk@vger.kernel.org \ --cc=m.mtretter@pengutronix.de \ --cc=michals@xilinx.com \ --cc=mturquette@baylibre.com \ --cc=sboyd@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.