linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] clk: zynqmp: pll: Fix divider calculation to avoid out-of-range rate
@ 2022-09-28 20:16 Laurent Pinchart
  2022-09-29  1:05 ` Quanyang Wang
  0 siblings, 1 reply; 12+ messages in thread
From: Laurent Pinchart @ 2022-09-28 20:16 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-arm-kernel, Michal Simek, Rajan Vaja, Quanyang Wang

When calculating the divider in zynqmp_pll_round_rate() and
zynqmp_pll_set_rate(), the division rounding error may result in an
output frequency that is slightly outside of the PLL output range if the
requested range is close to the low or high limit. As a result, the
limits check in clk_calc_new_rates() would fail, and clk_set_rate()
would return an error, as seen in the zynqmp-dpsub driver:

[   13.672309] zynqmp-dpsub fd4a0000.display: failed to set pixel clock rate to 297000000 (-22)

Fix this by adjusting the divider. The rate calculation then succeeds
for zynqmp-dpsub:

[   13.554849] zynqmp-dpsub fd4a0000.display: requested pixel rate: 297000000 actual rate: 255555553

The resulting PLL configuration, however, is not optimal, as the rate
error is 14%. The hardware can do much better, but CCF doesn't attempt
to find the best overall configuration for cascaded clocks. That's a
candidate for a separate fix.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/clk/zynqmp/pll.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
index 91a6b4cc910e..be6fa44a21e0 100644
--- a/drivers/clk/zynqmp/pll.c
+++ b/drivers/clk/zynqmp/pll.c
@@ -120,6 +120,10 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	}
 
 	fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
+	if (*prate * fbdiv < PS_PLL_VCO_MIN)
+		fbdiv++;
+	if (*prate * fbdiv > PS_PLL_VCO_MAX)
+		fbdiv--;
 	fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
 	return *prate * fbdiv;
 }
@@ -208,6 +212,10 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	}
 
 	fbdiv = DIV_ROUND_CLOSEST(rate, parent_rate);
+	if (parent_rate * fbdiv < PS_PLL_VCO_MIN)
+		fbdiv++;
+	else if (parent_rate * fbdiv > PS_PLL_VCO_MAX)
+		fbdiv--;
 	fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
 	ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv);
 	if (ret)

base-commit: 1c23f9e627a7b412978b4e852793c5e3c3efc555
-- 
Regards,

Laurent Pinchart


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-10-11 12:29 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-28 20:16 [PATCH] clk: zynqmp: pll: Fix divider calculation to avoid out-of-range rate Laurent Pinchart
2022-09-29  1:05 ` Quanyang Wang
2022-10-01  0:05   ` Stephen Boyd
2022-10-01 10:40     ` Maxime Ripard
2022-10-02  2:17       ` Quanyang Wang
2022-10-03  0:06         ` Laurent Pinchart
2022-10-10  8:49         ` Maxime Ripard
2022-10-10 12:12           ` Quanyang Wang
2022-10-10 12:49             ` Maxime Ripard
2022-10-11  3:11               ` Quanyang Wang
2022-10-11 12:27                 ` Maxime Ripard
2022-10-02 23:45   ` Laurent Pinchart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).