public inbox for linux-rockchip@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576
@ 2026-04-17 15:11 Alexey Charkov
  2026-04-17 15:11 ` [PATCH RFC 1/4] arm64: dts: rockchip: rk3576: assign dclk_vp1_src to VPLL Alexey Charkov
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Alexey Charkov @ 2026-04-17 15:11 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Michael Turquette, Stephen Boyd
  Cc: Pavel Zhovner, Sebastian Reichel, Andy Yan, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, linux-clk,
	Alexey Charkov

Dear all,

Need the help of the collective wisdom of the community.

The problem I'm trying to solve is reliably obtaining the exact pixel
clock for arbitrary display modes supported by the RK3576 SoC.

Rockchip RK3576 has three display output processors VP0~VP2, each
supporting different ranges of display modes, roughly as follows:
- VP0: 4K 120Hz
- VP1: 2.5k 60Hz
- VP2: 1080p 60Hz

Each one obviously needs a pixel clock. The required frequencies for the
pixel clocks vary greatly depending on the display mode, and need to be
matched within a tight tolerance, or else many displays will refuse to
work. E.g. the preferred (maximum) display mode out of VP1 is particularly
awkward, because it requires a pixel clock of 248.88 MHz, which cannot
be obtained using integer dividers from its default clock source (GPLL
at 1188 MHz), and the nearest approximation is 237.6 MHz, which is well
outside the tolerance of e.g. DP specification, resulting in a blank
screen on most displays by default.

The clock sources are of course configurable, in particular there are muxes
connected to each VP for selecting the source of the pixel clock:
- Each VP can take the clock either from the (single!) HDMI PHY or from
  its dedicated dclk_vpX_src mux
- The dclk_vpX_src mux can select the clock from a number of system PLLs
  (GPLL, CPLL, VPLL, BPLL, LPLL)

While the system PLLs can be configured to output a wide range of
frequencies, they are shared between many system components. E.g. on the
current mainline kernel on one of my RK3576 boards I've got the following:
GPLL: 1188 MHz, enable count 20
CPLL: 1000 MHz, enable count 17
VPLL: 594 MHz, enable count 0 (yaay!)
BPLL, LPLL: 816 MHz, enable count 0 (but these last ones don't have
            predividers, so are less flexible)

So ultimately there is exactly one free fractional PLL (VPLL) which can be
used to generate arbitrary pixel clocks, but we have up to three consumers
trying to drive different display modes from it (e.g. HDMI on VP0, DP on
VP1 and MIPI DSI on VP2). We also want to be able to adjust the PLL output
frequency on the fly to satisfy the requirements of the selected display
mode.

And this is where I'm stuck. Trying to satisfy the requirements of up to
three consumers while changing the PLL frequency on the fly sounds like
a poorly tractable mathematical problem (is it 3-SAT?). We can take the
HDMI output out of the equation, because it can be driven from the HDMI
PHY (which is capable of arbitrary rates) instead of the mux, but that
makes the decision of which dclk source to use for a VP block dependent on
which downstream consumer is connected to it (HDMI vs. something else).
Even then we somehow need two devices to cooperate in picking a PLL
frequency that satisfies the requirements of both of them, and change to it
without display corruption. I'm not even sure if the CCF has mechanisms
for that?..

What follows is a brief set of patches which illustrate a partial solution
for the case of "I just need 2.5k60Hz on VP1 via DP and don't care about
the rest". It switches the VP1 unconditionally to use VPLL as the source
for its dclk mux, allows changing the VPLL frequency on the fly, and also
changes the frequency calculation logic to allow for nearest-match
frequencies which are not necessarily rounded down. These are not meant
to be merged as-is, as I see the following issues:
- The flag allowing the PLL to change rate is in the clock driver, while
  the reparenting to an unused PLL is in the device tree. If these go out
  of sync, we might end up trying to change the frequency of a PLL which
  is used by other consumers (I presume that could be dangerous)
- If VP0 happens to be driving DP output, it won't be able to produce the
  2560x1440@60Hz mode for the same reasons as VP1 - then it must also be
  reparented to VPLL and allowed to change its frequency on the fly

It does bring me from a state of "always blank screen on DP output until
the mode is switched to something magically working" to a state of
"most monitors work at the default preferred mode" though.

It is tempting to just reparent both VP0 and VP1 to VPLL and allow both of
them to change its frequency, while leaving VP2 on the default (fixed)
GPLL and relying on the fact that 148.5 MHz (the required frequency for
its maximum supported mode of 1920x1080@60Hz) is conveniently 1188/8 MHz -
just what GPLL can provide. Then also force whichever VP is driving HDMI
output to use the HDMI PHY as its clock source. But we still have the
problem of DT vs. driver coordination, and I'm not sure how to define
the policy for "if you've got HDMI connected, you must use the HDMI PHY
clock for the respective VP, whichever VP that is".

I would very much appreciate any thoughts on how to approach this.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
Alexey Charkov (4):
      arm64: dts: rockchip: rk3576: assign dclk_vp1_src to VPLL
      clk: rockchip: pll: use round-nearest in determine_rate
      clk: rockchip: rk3576: allow dclk_vp1_src to propagate rate to parent PLL
      clk: rockchip: rk3576: add ROUND_CLOSEST to dclk_vp1_src divider

 arch/arm64/boot/dts/rockchip/rk3576.dtsi |  2 ++
 drivers/clk/rockchip/clk-pll.c           | 16 ++++++++--------
 drivers/clk/rockchip/clk-rk3576.c        |  4 ++--
 3 files changed, 12 insertions(+), 10 deletions(-)
---
base-commit: c7275b05bc428c7373d97aa2da02d3a7fa6b9f66
change-id: 20260417-rk3576-dclk-4c95bbb67581

Best regards,
-- 
Alexey Charkov <alchark@flipper.net>


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH RFC 1/4] arm64: dts: rockchip: rk3576: assign dclk_vp1_src to VPLL
  2026-04-17 15:11 [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Alexey Charkov
@ 2026-04-17 15:11 ` Alexey Charkov
  2026-04-17 15:11 ` [PATCH RFC 2/4] clk: rockchip: pll: use round-nearest in determine_rate Alexey Charkov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Alexey Charkov @ 2026-04-17 15:11 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Michael Turquette, Stephen Boyd
  Cc: Pavel Zhovner, Sebastian Reichel, Andy Yan, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, linux-clk,
	Alexey Charkov

Reparent dclk_vp1_src from GPLL to VPLL at the SoC level. VPLL is a
programmable PLL with no other consumers, allowing the CRU to synthesize
accurate pixel clocks for VP1's output with arbitrary display modes.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index e12a2a0cfb89..2b05900c6c1c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1338,6 +1338,8 @@ vop: vop@27d00000 {
 				      "dclk_vp1",
 				      "dclk_vp2",
 				      "pll_hdmiphy0";
+			assigned-clocks = <&cru DCLK_VP1_SRC>;
+			assigned-clock-parents = <&cru PLL_VPLL>;
 			iommus = <&vop_mmu>;
 			power-domains = <&power RK3576_PD_VOP>;
 			rockchip,grf = <&sys_grf>;

-- 
2.52.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH RFC 2/4] clk: rockchip: pll: use round-nearest in determine_rate
  2026-04-17 15:11 [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Alexey Charkov
  2026-04-17 15:11 ` [PATCH RFC 1/4] arm64: dts: rockchip: rk3576: assign dclk_vp1_src to VPLL Alexey Charkov
@ 2026-04-17 15:11 ` Alexey Charkov
  2026-04-17 22:59   ` Heiko Stuebner
  2026-04-17 15:11 ` [PATCH RFC 3/4] clk: rockchip: rk3576: allow dclk_vp1_src to propagate rate to parent PLL Alexey Charkov
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Alexey Charkov @ 2026-04-17 15:11 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Michael Turquette, Stephen Boyd
  Cc: Pavel Zhovner, Sebastian Reichel, Andy Yan, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, linux-clk,
	Alexey Charkov

rockchip_pll_determine_rate() walks the rate table in descending order
and picks the first entry <= the requested rate. This floor-rounding
interacts poorly with consumers that use CLK_SET_RATE_PARENT: a divider
iterating candidates asks the PLL for rate*div, and a tiny undershoot
causes the PLL to snap to a much lower entry.

For example, requesting 1991.04 MHz (248.88 MHz * 8) causes the PLL to
return 1968 MHz instead of 1992 MHz — a 24 MHz table gap that produces
a 1.2% pixel clock error when divided back down.

Change to round-to-nearest: for each table entry compute the absolute
distance from the request, and pick the entry with the smallest delta.
The CCF's divider and composite logic handle over/undershoot preferences
via their own ROUND_CLOSEST flags.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
 drivers/clk/rockchip/clk-pll.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 6b853800cb6b..c142f2c4fd99 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -66,19 +66,19 @@ static int rockchip_pll_determine_rate(struct clk_hw *hw,
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 	const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
+	unsigned long best = 0;
 	int i;
 
-	/* Assuming rate_table is in descending order */
 	for (i = 0; i < pll->rate_count; i++) {
-		if (req->rate >= rate_table[i].rate) {
-			req->rate = rate_table[i].rate;
-
-			return 0;
-		}
+		if (abs((long)req->rate - (long)rate_table[i].rate) <
+		    abs((long)req->rate - (long)best))
+			best = rate_table[i].rate;
 	}
 
-	/* return minimum supported value */
-	req->rate = rate_table[i - 1].rate;
+	if (best)
+		req->rate = best;
+	else
+		req->rate = rate_table[pll->rate_count - 1].rate;
 
 	return 0;
 }

-- 
2.52.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH RFC 3/4] clk: rockchip: rk3576: allow dclk_vp1_src to propagate rate to parent PLL
  2026-04-17 15:11 [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Alexey Charkov
  2026-04-17 15:11 ` [PATCH RFC 1/4] arm64: dts: rockchip: rk3576: assign dclk_vp1_src to VPLL Alexey Charkov
  2026-04-17 15:11 ` [PATCH RFC 2/4] clk: rockchip: pll: use round-nearest in determine_rate Alexey Charkov
@ 2026-04-17 15:11 ` Alexey Charkov
  2026-04-17 15:11 ` [PATCH RFC 4/4] clk: rockchip: rk3576: add ROUND_CLOSEST to dclk_vp1_src divider Alexey Charkov
  2026-04-17 22:24 ` [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Sebastian Reichel
  4 siblings, 0 replies; 7+ messages in thread
From: Alexey Charkov @ 2026-04-17 15:11 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Michael Turquette, Stephen Boyd
  Cc: Pavel Zhovner, Sebastian Reichel, Andy Yan, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, linux-clk,
	Alexey Charkov

dclk_vp1_src feeds the display clock for Video Port 1. When parented to
the default GPLL (1188 MHz), the 8-bit divider cannot synthesize the
248.88 MHz pixel clock required for 2560x1440@60 which VP1 supports:
1188 / 5 = 237.6 MHz (-4.53% error). This exceeds DisplayPort's +/-0.5%
tolerance and causes black screens on strict sinks.

Add CLK_SET_RATE_PARENT so that when dclk_vp1_src is reparented to a
programmable PLL (e.g. VPLL via assigned-clock-parents), the CCF divider
can ask the PLL to retune. For example, VPLL at 1992 MHz / 8 = 249 MHz
(0.048% error).

This flag relies on reparenting the VP1 source clock to VPLL at DT level
to ensure no consumer calls clk_set_rate on dclk_vp1 while its parent is
set to the boot-time default of GPLL.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
 drivers/clk/rockchip/clk-rk3576.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk-rk3576.c b/drivers/clk/rockchip/clk-rk3576.c
index 2557358e0b9d..28eb5a802e83 100644
--- a/drivers/clk/rockchip/clk-rk3576.c
+++ b/drivers/clk/rockchip/clk-rk3576.c
@@ -1105,7 +1105,7 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = {
 	COMPOSITE(DCLK_VP0_SRC, "dclk_vp0_src", gpll_cpll_vpll_bpll_lpll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3576_CLKSEL_CON(145), 8, 3, MFLAGS, 0, 8, DFLAGS,
 			RK3576_CLKGATE_CON(61), 10, GFLAGS),
-	COMPOSITE(DCLK_VP1_SRC, "dclk_vp1_src", gpll_cpll_vpll_bpll_lpll_p, CLK_SET_RATE_NO_REPARENT,
+	COMPOSITE(DCLK_VP1_SRC, "dclk_vp1_src", gpll_cpll_vpll_bpll_lpll_p, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
 			RK3576_CLKSEL_CON(146), 8, 3, MFLAGS, 0, 8, DFLAGS,
 			RK3576_CLKGATE_CON(61), 11, GFLAGS),
 	COMPOSITE(DCLK_VP2_SRC, "dclk_vp2_src", gpll_cpll_vpll_bpll_lpll_p, CLK_SET_RATE_NO_REPARENT,

-- 
2.52.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH RFC 4/4] clk: rockchip: rk3576: add ROUND_CLOSEST to dclk_vp1_src divider
  2026-04-17 15:11 [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Alexey Charkov
                   ` (2 preceding siblings ...)
  2026-04-17 15:11 ` [PATCH RFC 3/4] clk: rockchip: rk3576: allow dclk_vp1_src to propagate rate to parent PLL Alexey Charkov
@ 2026-04-17 15:11 ` Alexey Charkov
  2026-04-17 22:24 ` [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Sebastian Reichel
  4 siblings, 0 replies; 7+ messages in thread
From: Alexey Charkov @ 2026-04-17 15:11 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Michael Turquette, Stephen Boyd
  Cc: Pavel Zhovner, Sebastian Reichel, Andy Yan, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, linux-clk,
	Alexey Charkov

Without CLK_DIVIDER_ROUND_CLOSEST, the divider's _is_best_div() only
considers candidates where now <= target, rejecting any rate above the
target even when it is closer. Combined with the PLL round-nearest fix,
this causes the divider to still pick a suboptimal rate: with PLL
round-nearest alone, div=8 produces 249.0 MHz (0.048% over) but is
rejected because it exceeds the target, and div=3/248.0 MHz wins
(-0.354% error).

Add CLK_DIVIDER_ROUND_CLOSEST to dclk_vp1_src's div_flags so the
divider picks the rate closest to the target regardless of direction.
Together with the PLL round-nearest change, this yields:

  VPLL 1992 MHz / 8 = 249.0 MHz (+0.048% error)

instead of the previous:

  VPLL 1488 MHz / 6 = 248.0 MHz (-0.354% error)

This small difference appears to enable more monitors to lock to the VP1
clock when driving output at 2560x1440@60Hz via DisplayPort.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
 drivers/clk/rockchip/clk-rk3576.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk-rk3576.c b/drivers/clk/rockchip/clk-rk3576.c
index 28eb5a802e83..9fc3264ef322 100644
--- a/drivers/clk/rockchip/clk-rk3576.c
+++ b/drivers/clk/rockchip/clk-rk3576.c
@@ -1106,7 +1106,7 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = {
 			RK3576_CLKSEL_CON(145), 8, 3, MFLAGS, 0, 8, DFLAGS,
 			RK3576_CLKGATE_CON(61), 10, GFLAGS),
 	COMPOSITE(DCLK_VP1_SRC, "dclk_vp1_src", gpll_cpll_vpll_bpll_lpll_p, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
-			RK3576_CLKSEL_CON(146), 8, 3, MFLAGS, 0, 8, DFLAGS,
+			RK3576_CLKSEL_CON(146), 8, 3, MFLAGS, 0, 8, DFLAGS | CLK_DIVIDER_ROUND_CLOSEST,
 			RK3576_CLKGATE_CON(61), 11, GFLAGS),
 	COMPOSITE(DCLK_VP2_SRC, "dclk_vp2_src", gpll_cpll_vpll_bpll_lpll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3576_CLKSEL_CON(147), 8, 3, MFLAGS, 0, 8, DFLAGS,

-- 
2.52.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576
  2026-04-17 15:11 [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Alexey Charkov
                   ` (3 preceding siblings ...)
  2026-04-17 15:11 ` [PATCH RFC 4/4] clk: rockchip: rk3576: add ROUND_CLOSEST to dclk_vp1_src divider Alexey Charkov
@ 2026-04-17 22:24 ` Sebastian Reichel
  4 siblings, 0 replies; 7+ messages in thread
From: Sebastian Reichel @ 2026-04-17 22:24 UTC (permalink / raw)
  To: Alexey Charkov
  Cc: Rob Herring, Conor Dooley, Heiko Stuebner, devicetree,
	Stephen Boyd, Michael Turquette, linux-kernel, Pavel Zhovner,
	linux-rockchip, Andy Yan, Krzysztof Kozlowski, linux-clk,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 6942 bytes --]

Hello Alexey,

On Fri, Apr 17, 2026 at 07:11:43PM +0400, Alexey Charkov wrote:
> Dear all,
> 
> Need the help of the collective wisdom of the community.
> 
> The problem I'm trying to solve is reliably obtaining the exact pixel
> clock for arbitrary display modes supported by the RK3576 SoC.
> 
> Rockchip RK3576 has three display output processors VP0~VP2, each
> supporting different ranges of display modes, roughly as follows:
> - VP0: 4K 120Hz
> - VP1: 2.5k 60Hz
> - VP2: 1080p 60Hz
> 
> Each one obviously needs a pixel clock. The required frequencies for the
> pixel clocks vary greatly depending on the display mode, and need to be
> matched within a tight tolerance, or else many displays will refuse to
> work. E.g. the preferred (maximum) display mode out of VP1 is particularly
> awkward, because it requires a pixel clock of 248.88 MHz, which cannot
> be obtained using integer dividers from its default clock source (GPLL
> at 1188 MHz), and the nearest approximation is 237.6 MHz, which is well
> outside the tolerance of e.g. DP specification, resulting in a blank
> screen on most displays by default.
> 
> The clock sources are of course configurable, in particular there are muxes
> connected to each VP for selecting the source of the pixel clock:
> - Each VP can take the clock either from the (single!) HDMI PHY or from
>   its dedicated dclk_vpX_src mux
> - The dclk_vpX_src mux can select the clock from a number of system PLLs
>   (GPLL, CPLL, VPLL, BPLL, LPLL)
> 
> While the system PLLs can be configured to output a wide range of
> frequencies, they are shared between many system components. E.g. on the
> current mainline kernel on one of my RK3576 boards I've got the following:
> GPLL: 1188 MHz, enable count 20
> CPLL: 1000 MHz, enable count 17
> VPLL: 594 MHz, enable count 0 (yaay!)
> BPLL, LPLL: 816 MHz, enable count 0 (but these last ones don't have
>             predividers, so are less flexible)
> 
> So ultimately there is exactly one free fractional PLL (VPLL) which can be
> used to generate arbitrary pixel clocks, but we have up to three consumers
> trying to drive different display modes from it (e.g. HDMI on VP0, DP on
> VP1 and MIPI DSI on VP2). We also want to be able to adjust the PLL output
> frequency on the fly to satisfy the requirements of the selected display
> mode.
> 
> And this is where I'm stuck. Trying to satisfy the requirements of up to
> three consumers while changing the PLL frequency on the fly sounds like
> a poorly tractable mathematical problem (is it 3-SAT?). We can take the
> HDMI output out of the equation, because it can be driven from the HDMI
> PHY (which is capable of arbitrary rates) instead of the mux, but that
> makes the decision of which dclk source to use for a VP block dependent on
> which downstream consumer is connected to it (HDMI vs. something else).

It becomes more messy: The HDMI PHY cannot be used as clock source
for modes exceeding 4K@60Hz.

> Even then we somehow need two devices to cooperate in picking a PLL
> frequency that satisfies the requirements of both of them, and change to it
> without display corruption. I'm not even sure if the CCF has mechanisms
> for that?..
> 
> What follows is a brief set of patches which illustrate a partial solution
> for the case of "I just need 2.5k60Hz on VP1 via DP and don't care about
> the rest". It switches the VP1 unconditionally to use VPLL as the source
> for its dclk mux, allows changing the VPLL frequency on the fly, and also
> changes the frequency calculation logic to allow for nearest-match
> frequencies which are not necessarily rounded down. These are not meant
> to be merged as-is, as I see the following issues:
> - The flag allowing the PLL to change rate is in the clock driver, while
>   the reparenting to an unused PLL is in the device tree. If these go out
>   of sync, we might end up trying to change the frequency of a PLL which
>   is used by other consumers (I presume that could be dangerous)

It is a problem, see e.g. this patch from Heiko removing the flag
for an RK3588 VOP source clock:

https://lore.kernel.org/linux-rockchip/20251008133135.3745785-1-heiko@sntech.de/

Also note, that there is some more general ongoing work regarding
this:

See: https://lore.kernel.org/linux-clk/20260327-clk-scaling-v8-0-86cd0aba3c5f@redhat.com/

> - If VP0 happens to be driving DP output, it won't be able to produce the
>   2560x1440@60Hz mode for the same reasons as VP1 - then it must also be
>   reparented to VPLL and allowed to change its frequency on the fly

There is also the problem that nearest match might be sensible for the
display, but is not generally safe. For other clocks you might
effectively overclock, which shouldn't be done by default.

> It does bring me from a state of "always blank screen on DP output until
> the mode is switched to something magically working" to a state of
> "most monitors work at the default preferred mode" though.
> 
> It is tempting to just reparent both VP0 and VP1 to VPLL and allow both of
> them to change its frequency, while leaving VP2 on the default (fixed)
> GPLL and relying on the fact that 148.5 MHz (the required frequency for
> its maximum supported mode of 1920x1080@60Hz) is conveniently 1188/8 MHz -
> just what GPLL can provide. Then also force whichever VP is driving HDMI
> output to use the HDMI PHY as its clock source. But we still have the
> problem of DT vs. driver coordination, and I'm not sure how to define
> the policy for "if you've got HDMI connected, you must use the HDMI PHY
> clock for the respective VP, whichever VP that is".

Sorry, I don't have any complete solutions - except that I can tell
you that the VOP2 driver already automatically switches the clock
source to the HDMI PHY for HDMI outputs if the pixel rates allows it:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c#n1757

Greetings,

-- Sebastian

> I would very much appreciate any thoughts on how to approach this.
> 
> Signed-off-by: Alexey Charkov <alchark@flipper.net>
> ---
> Alexey Charkov (4):
>       arm64: dts: rockchip: rk3576: assign dclk_vp1_src to VPLL
>       clk: rockchip: pll: use round-nearest in determine_rate
>       clk: rockchip: rk3576: allow dclk_vp1_src to propagate rate to parent PLL
>       clk: rockchip: rk3576: add ROUND_CLOSEST to dclk_vp1_src divider
> 
>  arch/arm64/boot/dts/rockchip/rk3576.dtsi |  2 ++
>  drivers/clk/rockchip/clk-pll.c           | 16 ++++++++--------
>  drivers/clk/rockchip/clk-rk3576.c        |  4 ++--
>  3 files changed, 12 insertions(+), 10 deletions(-)
> ---
> base-commit: c7275b05bc428c7373d97aa2da02d3a7fa6b9f66
> change-id: 20260417-rk3576-dclk-4c95bbb67581
> 
> Best regards,
> -- 
> Alexey Charkov <alchark@flipper.net>
> 

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 170 bytes --]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH RFC 2/4] clk: rockchip: pll: use round-nearest in determine_rate
  2026-04-17 15:11 ` [PATCH RFC 2/4] clk: rockchip: pll: use round-nearest in determine_rate Alexey Charkov
@ 2026-04-17 22:59   ` Heiko Stuebner
  0 siblings, 0 replies; 7+ messages in thread
From: Heiko Stuebner @ 2026-04-17 22:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Michael Turquette,
	Stephen Boyd, Alexey Charkov
  Cc: Pavel Zhovner, Sebastian Reichel, Andy Yan, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, linux-clk,
	Alexey Charkov

Hi Alexey,

Am Freitag, 17. April 2026, 17:11:45 Mitteleuropäische Sommerzeit schrieb Alexey Charkov:
> rockchip_pll_determine_rate() walks the rate table in descending order
> and picks the first entry <= the requested rate. This floor-rounding
> interacts poorly with consumers that use CLK_SET_RATE_PARENT: a divider
> iterating candidates asks the PLL for rate*div, and a tiny undershoot
> causes the PLL to snap to a much lower entry.
> 
> For example, requesting 1991.04 MHz (248.88 MHz * 8) causes the PLL to
> return 1968 MHz instead of 1992 MHz — a 24 MHz table gap that produces
> a 1.2% pixel clock error when divided back down.
> 
> Change to round-to-nearest: for each table entry compute the absolute
> distance from the request, and pick the entry with the smallest delta.
> The CCF's divider and composite logic handle over/undershoot preferences
> via their own ROUND_CLOSEST flags.
> 
> Signed-off-by: Alexey Charkov <alchark@flipper.net>

as Sebastian said, this could cause overclocking in a number of areas.
The rate you get should always be lower or equal to the requested rate.

Additionally, such a core behaviour change, would affect 13 years of
SoCs with unknown side-effects.

If you're missing specific clock rates, you can always add them to the
list :-) . The vendor-kernel does have code that can calculate the
rate params itself, so this could give you a hint where to start.

======= just to explain =======

Though I still don't think that code should be in the mainline-kernel,
as a curated PLL rates allows more control, where that algorithm
creates parameters that are programmatically correct, but essentially
untested.

On the two Chromebook projects, they actually measured things like
clock jitter, which got us more specific params for some rates.


Heiko




_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

end of thread, other threads:[~2026-04-17 22:59 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-17 15:11 [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Alexey Charkov
2026-04-17 15:11 ` [PATCH RFC 1/4] arm64: dts: rockchip: rk3576: assign dclk_vp1_src to VPLL Alexey Charkov
2026-04-17 15:11 ` [PATCH RFC 2/4] clk: rockchip: pll: use round-nearest in determine_rate Alexey Charkov
2026-04-17 22:59   ` Heiko Stuebner
2026-04-17 15:11 ` [PATCH RFC 3/4] clk: rockchip: rk3576: allow dclk_vp1_src to propagate rate to parent PLL Alexey Charkov
2026-04-17 15:11 ` [PATCH RFC 4/4] clk: rockchip: rk3576: add ROUND_CLOSEST to dclk_vp1_src divider Alexey Charkov
2026-04-17 22:24 ` [PATCH RFC 0/4] arm64: rockchip: The hunt for exact pixel clocks on RK3576 Sebastian Reichel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox