Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/bridge: dw-hdmi-qp: compute audio CTS from N when not in TMDS table
@ 2026-05-09  7:09 Simon Wright
  2026-05-18 10:50 ` Luca Ceresoli
  0 siblings, 1 reply; 2+ messages in thread
From: Simon Wright @ 2026-05-09  7:09 UTC (permalink / raw)
  To: Cristian Ciocaltea
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Luca Ceresoli, David Airlie,
	Simona Vetter, Heiko Stuebner, Andy Yan, Sebastian Reichel,
	Dmitry Baryshkov, Algea Cao, dri-devel, linux-rockchip,
	linux-arm-kernel, linux-kernel

dw_hdmi_qp_find_cts() returns 0 for any TMDS character rate not
present in common_tmds_cts_table[] (which terminates at 148.5 MHz).
In that case dw_hdmi_qp_set_sample_rate() calls dw_hdmi_qp_set_cts_n()
with cts == 0, which leaves AUDPKT_ACR_CTS_OVR_EN clear and falls
back to the controller's internal CTS auto-measurement.
On at least the RK3576 hdptx integration, strict HDMI sinks mute
audio in this configuration.  The behaviour reproduces at any rate
not present in the table -- it is not specific to HDMI 2.x:
1920x1080@60 with 10-bit deep colour (185.625 MHz, HDMI 1.4) is
affected, as is 3840x2160@60 8-bit (594 MHz, HDMI 2.0).  Supplying
explicit CTS via the standard set_cts_n() override path resolves
the mute.
The driver already has the symmetric machinery for the N-table-miss
case: dw_hdmi_qp_compute_n() falls back to a dynamic search using
dw_hdmi_qp_audio_math_diff() ((pixel_clk * n) / (128 * freq)) when
no table entry matches.  The CTS path lacks the equivalent fallback.
Compute CTS inline in dw_hdmi_qp_set_sample_rate() from N per the
HDMI spec (CTS = TMDS * N / (128 * Fs)) when find_cts() returns 0.
The same formula appears in the legacy DesignWare HDMI driver
(drivers/gpu/drm/bridge/synopsys/dw-hdmi.c, hdmi_set_clk_regenerator())
under its AHB / GP audio paths.
Tested on R76S (RK3576) on Armbian-edge mainline 7.0.1 with Cristian
Ciocaltea's hdptx-clk-fixes v1 series applied:
   TMDS         Mode             In table?  Audio with fix
   148.5 MHz    1080p60  8-bit   yes        plays (regression check)
   185.625 MHz  1080p60 10-bit   no         plays
   297 MHz      3840p30  8-bit   no         plays
   594 MHz      3840p60  8-bit   no         plays
Sinks tested: LG G3 OLED, LG C4 OLED, TCL 75P7K QLED, Kogan
KALED43XU9210STA (Changhong-OEM 4K LED).  Without the fix, the LG
G3 mutes audio -- this is the originally reported bug
(linux-rockchip 070633).  The LG C4 was verified during this cycle
to mute at 185.625 MHz (1080p60 10-bit) with the unpatched module.
The Kogan TV plays audio with or without the fix; it is a
permissive HDMI 2.0 implementation that does not strictly cross-
check ACR timing.  The TCL 75P7K was tested with the fix loaded
only.
Audio plays at every supported sample rate (32 / 44.1 / 48 / 96 /
192 kHz) verified on the TCL at the 185.625 MHz out-of-table TMDS
rate -- the fallback's CTS = (TMDS * N) / (128 * Fs) computation is
independent of sample rate, as expected.
The LG C4's CTA-861 SVDs do not advertise 3840x2160@60 over TMDS
(it is signalled FRL-only on that model), so that one row is N/A
on the C4.  The same audio-path code is exercised at 297 MHz on
that sink and behaves identically to the G3.
Reported-by: Simon Wright <simon@symple.nz>
Closes: 
https://lists.infradead.org/pipermail/linux-rockchip/2026-May/070633.html
Suggested-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Tested-by: Simon Wright <simon@symple.nz>
Signed-off-by: Simon Wright <simon@symple.nz>
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 15 +++++++++++++++
  1 file changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 0dbb1274360..25ac8d3cfc8 100644
---a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@-461,6 +461,21 @@static void dw_hdmi_qp_set_sample_rate(struct 
dw_hdmi_qp *hdmi, unsigned long lo
   n = dw_hdmi_qp_find_n(hdmi, tmds_char_rate, sample_rate);
   cts = dw_hdmi_qp_find_cts(hdmi, tmds_char_rate, sample_rate);
+ /*
+  * dw_hdmi_qp_find_cts() returns 0 for any TMDS rate not in
+  * common_tmds_cts_table[].  Falling through to the controller's
+  * auto-measure path mutes audio on strict HDMI sinks at out-of-
+  * table rates (e.g. 185.625 MHz, 297 MHz, 594 MHz).  Compute CTS
+  * from N per HDMI spec instead, so the standard override path
+  * supplies it on the wire.
+  */
+ if (!cts && n) {
+   u64 computed = (u64)tmds_char_rate * n;
+
+   do_div(computed, 128ULL * sample_rate);
+   cts = (unsigned int)computed;
+ }
+
   dw_hdmi_qp_set_cts_n(hdmi, cts, n);
  }
-- 
2.53.0.windows.3



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

* Re: [PATCH] drm/bridge: dw-hdmi-qp: compute audio CTS from N when not in TMDS table
  2026-05-09  7:09 [PATCH] drm/bridge: dw-hdmi-qp: compute audio CTS from N when not in TMDS table Simon Wright
@ 2026-05-18 10:50 ` Luca Ceresoli
  0 siblings, 0 replies; 2+ messages in thread
From: Luca Ceresoli @ 2026-05-18 10:50 UTC (permalink / raw)
  To: Simon Wright, Cristian Ciocaltea
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Simona Vetter,
	Heiko Stuebner, Andy Yan, Sebastian Reichel, Dmitry Baryshkov,
	Algea Cao, dri-devel, linux-rockchip, linux-arm-kernel,
	linux-kernel

Hello Simon,

On Sat May 9, 2026 at 9:09 AM CEST, Simon Wright wrote:
> dw_hdmi_qp_find_cts() returns 0 for any TMDS character rate not
> present in common_tmds_cts_table[] (which terminates at 148.5 MHz).
> In that case dw_hdmi_qp_set_sample_rate() calls dw_hdmi_qp_set_cts_n()
> with cts == 0, which leaves AUDPKT_ACR_CTS_OVR_EN clear and falls
> back to the controller's internal CTS auto-measurement.
> On at least the RK3576 hdptx integration, strict HDMI sinks mute
> audio in this configuration.  The behaviour reproduces at any rate
> not present in the table -- it is not specific to HDMI 2.x:
> 1920x1080@60 with 10-bit deep colour (185.625 MHz, HDMI 1.4) is
> affected, as is 3840x2160@60 8-bit (594 MHz, HDMI 2.0).  Supplying
> explicit CTS via the standard set_cts_n() override path resolves
> the mute.
> The driver already has the symmetric machinery for the N-table-miss
> case: dw_hdmi_qp_compute_n() falls back to a dynamic search using
> dw_hdmi_qp_audio_math_diff() ((pixel_clk * n) / (128 * freq)) when
> no table entry matches.  The CTS path lacks the equivalent fallback.
> Compute CTS inline in dw_hdmi_qp_set_sample_rate() from N per the
> HDMI spec (CTS = TMDS * N / (128 * Fs)) when find_cts() returns 0.
> The same formula appears in the legacy DesignWare HDMI driver
> (drivers/gpu/drm/bridge/synopsys/dw-hdmi.c, hdmi_set_clk_regenerator())
> under its AHB / GP audio paths.
> Tested on R76S (RK3576) on Armbian-edge mainline 7.0.1 with Cristian
> Ciocaltea's hdptx-clk-fixes v1 series applied:
>    TMDS         Mode             In table?  Audio with fix
>    148.5 MHz    1080p60  8-bit   yes        plays (regression check)
>    185.625 MHz  1080p60 10-bit   no         plays
>    297 MHz      3840p30  8-bit   no         plays
>    594 MHz      3840p60  8-bit   no         plays
> Sinks tested: LG G3 OLED, LG C4 OLED, TCL 75P7K QLED, Kogan
> KALED43XU9210STA (Changhong-OEM 4K LED).  Without the fix, the LG
> G3 mutes audio -- this is the originally reported bug
> (linux-rockchip 070633).  The LG C4 was verified during this cycle
> to mute at 185.625 MHz (1080p60 10-bit) with the unpatched module.
> The Kogan TV plays audio with or without the fix; it is a
> permissive HDMI 2.0 implementation that does not strictly cross-
> check ACR timing.  The TCL 75P7K was tested with the fix loaded
> only.
> Audio plays at every supported sample rate (32 / 44.1 / 48 / 96 /
> 192 kHz) verified on the TCL at the 185.625 MHz out-of-table TMDS
> rate -- the fallback's CTS = (TMDS * N) / (128 * Fs) computation is
> independent of sample rate, as expected.
> The LG C4's CTA-861 SVDs do not advertise 3840x2160@60 over TMDS
> (it is signalled FRL-only on that model), so that one row is N/A
> on the C4.  The same audio-path code is exercised at 297 MHz on
> that sink and behaves identically to the G3.
> Reported-by: Simon Wright <simon@symple.nz>
> Closes:
> https://lists.infradead.org/pipermail/linux-rockchip/2026-May/070633.html
> Suggested-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> Tested-by: Simon Wright <simon@symple.nz>
> Signed-off-by: Simon Wright <simon@symple.nz>
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> index 0dbb1274360..25ac8d3cfc8 100644
> ---a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> +++b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> @@-461,6 +461,21 @@static void dw_hdmi_qp_set_sample_rate(struct
> dw_hdmi_qp *hdmi, unsigned long lo
>    n = dw_hdmi_qp_find_n(hdmi, tmds_char_rate, sample_rate);
>    cts = dw_hdmi_qp_find_cts(hdmi, tmds_char_rate, sample_rate);
> + /*
> +  * dw_hdmi_qp_find_cts() returns 0 for any TMDS rate not in
> +  * common_tmds_cts_table[].  Falling through to the controller's
> +  * auto-measure path mutes audio on strict HDMI sinks at out-of-
> +  * table rates (e.g. 185.625 MHz, 297 MHz, 594 MHz).  Compute CTS
> +  * from N per HDMI spec instead, so the standard override path
> +  * supplies it on the wire.
> +  */
> + if (!cts && n) {
> +   u64 computed = (u64)tmds_char_rate * n;
> +
> +   do_div(computed, 128ULL * sample_rate);
> +   cts = (unsigned int)computed;
> + }
> +
>    dw_hdmi_qp_set_cts_n(hdmi, cts, n);
>   }

Thanks for your patch. I cannot comment on the content but I can point for
formal issues with your submission.

Your patch got mangled by your mailer and cannot be applied. Please don't
try to convince your mailer to send patches the right way: save your time
and use "git-format patch + git send-email", or even better use b4.

Also your commit message is very detailed, and think it would be more
readable if split in paragraphs. You can have a look at various commits in
the kernel log for inspiration.

There's plenty of suggestions on how to send patches in [0], ensure you
read them all.

[0] https://docs.kernel.org/process/submitting-patches.html

Thanks!

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


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

end of thread, other threads:[~2026-05-18 10:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-09  7:09 [PATCH] drm/bridge: dw-hdmi-qp: compute audio CTS from N when not in TMDS table Simon Wright
2026-05-18 10:50 ` Luca Ceresoli

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