Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices
@ 2026-09-06  5:42 Xiao Lu
  2026-09-06  5:52 ` ✗ Fi.CI.BUILD: failure for " Patchwork
  2026-09-06  6:02 ` [PATCH] " sashiko-bot
  0 siblings, 2 replies; 3+ messages in thread
From: Xiao Lu @ 2026-09-06  5:42 UTC (permalink / raw)
  To: intel-gfx
  Cc: jani.nikula, ville.syrjala, imre.deak, ankit.k.nautiyal, Xiao Lu

HDMI 2.1 PCON devices (e.g. Parade PS196) that do not have an internal
DSC encoder can still forward a DSC-compressed stream from the DP source
to the downstream HDMI 2.1 sink unchanged (passthrough mode). The HDMI
sink (e.g. Lenovo ThinkVision Pro 27UD-10) then decompresses the stream
itself. This mode is signalled by DP_DSC_PASSTHROUGH_IS_SUPPORTED (DPCD
0x060 bit1) on the PCON.

Previously the driver had no awareness of this path: the PCON would fall
back to its autonomous passthrough mode and write 0x160=0x02 by itself,
leaving the source with no control over DSC parameters or DPCD 0x160.

This patch adds explicit driver control of PCON DSC passthrough:

- Detect passthrough capability at connect time from DPCD 0x060 bit1
  (DP_DSC_PASSTHROUGH_IS_SUPPORTED) combined with the downstream HDMI
  2.1 sink's DSC 1.2 support from EDID HF-VSDB. Cache the result in
  connector->dp.pcon_dsc_passthrough (same lifecycle as fec_capability
  and dsc_dpcd) to avoid repeated lookups on every modeset.

- Treat the PCON as DSC-capable in intel_dp_has_dsc() when passthrough
  is supported, allowing the normal DSC compute_config path to proceed.

- Derive DSC parameters (slice count, bpc limits) from the downstream
  HDMI sink's EDID DSC capabilities (dsc_cap.max_slices,
  dsc_cap.clk_per_slice, dsc_cap.bpc_supported) rather than from the
  PCON's DSC encoder DPCD (which is all-zero for passthrough-only PCONs).
  This ensures the source VDSC engine produces a stream the HDMI sink
  can actually decompress.

- Write DP_DSC_PASSTHROUGH_EN (0x160 bit1) to the PCON via
  intel_dp_sink_set_dsc_passthrough() on enable, and clear it on
  disable. The existing MST hub passthrough path in that function is
  preserved; the PCON case is handled by redirecting aux to
  intel_dp->aux when pcon_dsc_passthrough is set.

- Short-circuit intel_dp_sink_set_dsc_decompression() for PCON
  passthrough since the PCON itself does not decompress (the HDMI sink
  does); writing DP_DECOMPRESSION_EN to the PCON would be incorrect.

Tested with Parade PS196G (HW 0.2, SW 241.62) connected to a Lenovo
ThinkVision Pro 27UD-10 (HDMI 2.1, DSC 1.2, max 16 slices, 400 MHz/
slice). At 4K@240Hz DSC compression is required (10.5625 bpp, 8 slices);
driver now writes 0x160=0x02 explicitly and slice count is correctly
derived from the HDMI sink EDID rather than from PCON DPCD.

Signed-off-by: Xiao Lu <xiaolu.xie@intel.com>
---
 .../drm/i915/display/intel_display_types.h    |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 147 +++++++++++++++++-
 2 files changed, 140 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index b7cc361fd955..3e7a362fd4dd 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -564,6 +564,7 @@ struct intel_connector {
 		u8 dsc_hblank_expansion_quirk:1;
 		u8 dsc_throughput_quirk:1;
 		u8 dsc_decompression_enabled:1;
+		u8 pcon_dsc_passthrough:1; /* PCON DSC PT supported and HDMI sink DSC 1.2 */
 
 		struct {
 			struct {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 113d767e62e9..ad55b08ecdea 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1259,8 +1259,14 @@ bool intel_dp_has_dsc(const struct intel_connector *connector)
 	    connector->panel.vbt.edp.dsc_disable)
 		return false;
 
-	if (!drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd))
-		return false;
+	if (!drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd)) {
+		/*
+		 * PCON passthrough: PCON has no DSC decoder so dsc_dpcd is
+		 * zero, but if pcon_dsc_passthrough is set (cached at connect
+		 * time) the downstream HDMI 2.1 sink will decompress instead.
+		 */
+		return connector->dp.pcon_dsc_passthrough;
+	}
 
 	return true;
 }
@@ -2365,6 +2371,9 @@ void intel_dp_dsc_reset_config(struct intel_crtc_state *crtc_state)
 	memset(&crtc_state->dsc.config, 0, sizeof(crtc_state->dsc.config));
 }
 
+static u8 intel_dp_pcon_passthrough_dsc_slice_count(struct intel_dp *intel_dp,
+						    const struct intel_crtc_state *crtc_state);
+
 int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 				struct intel_crtc_state *pipe_config,
 				struct drm_connector_state *conn_state,
@@ -2403,7 +2412,21 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 		}
 	}
 
-	if (!intel_dp_dsc_get_slice_config(connector, adjusted_mode->crtc_clock,
+	if (intel_dp->attached_connector->dp.pcon_dsc_passthrough) {
+		/*
+		 * PCON passthrough: no PCON encoder DPCD, derive slice count
+		 * from the downstream HDMI 2.1 sink DSC capabilities.
+		 */
+		u8 pt_slice_count =
+			intel_dp_pcon_passthrough_dsc_slice_count(intel_dp,
+								  pipe_config);
+		if (!pt_slice_count) {
+			drm_dbg_kms(display->drm,
+				    "PCON DSC passthrough: no valid slice count\n");
+			return -EINVAL;
+		}
+		pipe_config->dsc.slice_count = pt_slice_count;
+	} else if (!intel_dp_dsc_get_slice_config(connector, adjusted_mode->crtc_clock,
 					   adjusted_mode->crtc_hdisplay, num_joined_pipes,
 					   &pipe_config->dsc.slice_config))
 		return -EINVAL;
@@ -2732,8 +2755,33 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
 		return false;
 	}
 
-	if (dsc && !intel_dp_dsc_compute_pipe_bpp_limits(connector, limits))
-		return false;
+	if (dsc) {
+		if (connector->dp.pcon_dsc_passthrough) {
+			/*
+			 * PCON passthrough: PCON has no DSC encoder DPCD so
+			 * intel_dp_dsc_compute_pipe_bpp_limits() would see
+			 * all-zero dsc_dpcd and fail.  Use the downstream HDMI
+			 * sink DSC bpc cap to constrain the pipe bpp instead.
+			 */
+			const struct drm_display_info *info =
+				&connector->base.display_info;
+			u8 hdmi_max_bpc = info->hdmi.dsc_cap.bpc_supported ?: 8;
+			int dsc_min_bpc = intel_dp_dsc_min_src_input_bpc();
+			int dsc_max_bpc = min_t(int,
+						intel_dp_dsc_max_src_input_bpc(display),
+						hdmi_max_bpc);
+
+			limits->pipe.min_bpp = max(limits->pipe.min_bpp,
+						   dsc_min_bpc * 3);
+			limits->pipe.max_bpp = min(limits->pipe.max_bpp,
+						   dsc_max_bpc * 3);
+
+			if (limits->pipe.min_bpp > limits->pipe.max_bpp)
+				return false;
+		} else if (!intel_dp_dsc_compute_pipe_bpp_limits(connector, limits)) {
+			return false;
+		}
+	}
 
 	/*
 	 * crtc_state->pipe_bpp is the non-DP specific baseline (platform /
@@ -3745,6 +3793,10 @@ intel_dp_sink_set_dsc_decompression(struct intel_connector *connector,
 {
 	struct intel_display *display = to_intel_display(connector);
 
+	/* PCON passthrough: PCON forwards the stream, sink decompresses. */
+	if (!connector->mst.dp && connector->dp.pcon_dsc_passthrough)
+		return;
+
 	if (write_dsc_decompression_flag(connector->dp.dsc_decompression_aux,
 					 DP_DECOMPRESSION_EN, enable) < 0)
 		drm_dbg_kms(display->drm,
@@ -3757,8 +3809,19 @@ intel_dp_sink_set_dsc_passthrough(const struct intel_connector *connector,
 				  bool enable)
 {
 	struct intel_display *display = to_intel_display(connector);
-	struct drm_dp_aux *aux = connector->mst.port ?
-				 connector->mst.port->passthrough_aux : NULL;
+	struct drm_dp_aux *aux = NULL;
+
+	if (!connector->mst.port) {
+		/*
+		 * HDMI 2.1 PCON passthrough: write DP_DSC_PASSTHROUGH_EN on
+		 * the PCON's own aux channel so it forwards the compressed
+		 * stream to the HDMI sink instead of decoding it.
+		 */
+		if (connector->dp.pcon_dsc_passthrough)
+			aux = &intel_attached_dp((struct intel_connector *)connector)->aux;
+	} else {
+		aux = connector->mst.port->passthrough_aux;
+	}
 
 	if (!aux)
 		return;
@@ -3766,7 +3829,7 @@ intel_dp_sink_set_dsc_passthrough(const struct intel_connector *connector,
 	if (write_dsc_decompression_flag(aux,
 					 DP_DSC_PASSTHROUGH_EN, enable) < 0)
 		drm_dbg_kms(display->drm,
-			    "Failed to %s sink compression passthrough state\n",
+			    "Failed to %s DSC passthrough\n",
 			    str_enable_disable(enable));
 }
 
@@ -4297,6 +4360,71 @@ void intel_dp_check_frl_training(struct intel_dp *intel_dp)
 	}
 }
 
+/*
+ * intel_dp_pcon_set_dsc_passthrough_cap - cache PCON DSC passthrough capability
+ *
+ * Called once at connect time (from intel_dp_get_dsc_sink_cap()) after
+ * dsc_dpcd and the HDMI sink EDID have been read. Caches the result in
+ * connector->dp.pcon_dsc_passthrough so modeset paths can read it cheaply
+ * without repeating the DPCD and EDID lookups.
+ *
+ * A PCON supports DSC passthrough when it explicitly advertises
+ * DP_DSC_PASSTHROUGH_IS_SUPPORTED (DPCD 0x060 bit1) and the downstream
+ * HDMI 2.1 sink supports DSC 1.2. The compressed stream produced by the
+ * source VDSC engine is forwarded unchanged through the PCON to the HDMI
+ * sink for decompression (DP_DSC_ENABLE bit1 on the PCON).
+ */
+static void
+intel_dp_pcon_set_dsc_passthrough_cap(struct intel_dp *intel_dp)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	const struct drm_display_info *info;
+
+	if (!connector)
+		return;
+
+	connector->dp.pcon_dsc_passthrough = false;
+
+	if (!intel_dp_is_hdmi_2_1_sink(intel_dp))
+		return;
+
+	if (!(connector->dp.dsc_dpcd[0] & DP_DSC_PASSTHROUGH_IS_SUPPORTED))
+		return;
+
+	info = &connector->base.display_info;
+	connector->dp.pcon_dsc_passthrough = info->hdmi.dsc_cap.v_1p2;
+}
+
+static u8
+intel_dp_pcon_passthrough_dsc_slice_count(struct intel_dp *intel_dp,
+					  const struct intel_crtc_state *crtc_state)
+{
+	struct intel_display *display = to_intel_display(intel_dp);
+	struct intel_connector *connector = intel_dp->attached_connector;
+	const struct drm_display_info *info = &connector->base.display_info;
+	int hdmi_throughput = info->hdmi.dsc_cap.clk_per_slice;
+	int hdmi_max_slices = info->hdmi.dsc_cap.max_slices;
+	int num_slices;
+
+	/*
+	 * Passthrough: no PCON encoder constraints, use only the HDMI sink
+	 * DSC caps from EDID. Pass hdisplay for pcon_max_slice_width so that
+	 * constraint is effectively unconstrained.
+	 */
+	num_slices = intel_hdmi_dsc_get_num_slices(crtc_state,
+						   hdmi_max_slices,
+						   crtc_state->hw.adjusted_mode.hdisplay,
+						   hdmi_max_slices,
+						   hdmi_throughput);
+
+	drm_dbg_kms(display->drm,
+		     "PCON DSC passthrough: slice count %d from HDMI sink EDID cap"
+		     " (max_slices=%d clk_per_slice=%d MHz)\n",
+		     num_slices, hdmi_max_slices, hdmi_throughput);
+
+	return (u8)num_slices;
+}
+
 static int
 intel_dp_pcon_dsc_enc_slice_height(const struct intel_crtc_state *crtc_state)
 {
@@ -4536,6 +4664,7 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
 
 	memset(&connector->dp.dsc_branch_caps, 0, sizeof(connector->dp.dsc_branch_caps));
 	connector->dp.dsc_throughput_quirk = false;
+	connector->dp.pcon_dsc_passthrough = false;
 
 	if (dpcd_rev < DP_DPCD_REV_14)
 		return;
@@ -4565,6 +4694,8 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
 	if (drm_dp_has_quirk(desc, DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT) &&
 	    desc->ident.hw_rev == 0x10)
 		connector->dp.dsc_throughput_quirk = true;
+
+	intel_dp_pcon_set_dsc_passthrough_cap(intel_attached_dp(connector));
 }
 
 static void intel_edp_get_dsc_sink_cap(u8 edp_dpcd_rev, struct intel_connector *connector)
-- 
2.43.0


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

* ✗ Fi.CI.BUILD: failure for drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices
  2026-09-06  5:42 [PATCH] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
@ 2026-09-06  5:52 ` Patchwork
  2026-09-06  6:02 ` [PATCH] " sashiko-bot
  1 sibling, 0 replies; 3+ messages in thread
From: Patchwork @ 2026-09-06  5:52 UTC (permalink / raw)
  To: Xiao Lu; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices
URL   : https://patchwork.freedesktop.org/series/173452/
State : failure

== Summary ==

Error: make failed
  DESCEND objtool
  CC [M]  drivers/gpu/drm/i915/display/intel_dp.o
drivers/gpu/drm/i915/display/intel_dp.c: In function ‘intel_dp_dsc_compute_config’:
drivers/gpu/drm/i915/display/intel_dp.c:2418:34: error: ‘struct <anonymous>’ has no member named ‘slice_count’; did you mean ‘slice_config’?
 2418 |                 pipe_config->dsc.slice_count = pt_slice_count;
      |                                  ^~~~~~~~~~~
      |                                  slice_config
drivers/gpu/drm/i915/display/intel_dp.c: In function ‘intel_dp_pcon_passthrough_dsc_slice_count’:
drivers/gpu/drm/i915/display/intel_dp.c:4415:52: error: passing argument 1 of ‘intel_hdmi_dsc_get_num_slices’ from incompatible pointer type [-Werror=incompatible-pointer-types]
 4415 |         num_slices = intel_hdmi_dsc_get_num_slices(crtc_state,
      |                                                    ^~~~~~~~~~
      |                                                    |
      |                                                    const struct intel_crtc_state *
In file included from drivers/gpu/drm/i915/display/intel_dp.c:84:
drivers/gpu/drm/i915/display/intel_hdmi.h:60:66: note: expected ‘const struct drm_display_mode *’ but argument is of type ‘const struct intel_crtc_state *’
   60 | int intel_hdmi_dsc_get_num_slices(const struct drm_display_mode *mode,
      |                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
drivers/gpu/drm/i915/display/intel_dp.c:4415:22: error: too few arguments to function ‘intel_hdmi_dsc_get_num_slices’
 4415 |         num_slices = intel_hdmi_dsc_get_num_slices(crtc_state,
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/gpu/drm/i915/display/intel_hdmi.h:60:5: note: declared here
   60 | int intel_hdmi_dsc_get_num_slices(const struct drm_display_mode *mode,
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[6]: *** [scripts/Makefile.build:290: drivers/gpu/drm/i915/display/intel_dp.o] Error 1
make[5]: *** [scripts/Makefile.build:551: drivers/gpu/drm/i915] Error 2
make[4]: *** [scripts/Makefile.build:551: drivers/gpu/drm] Error 2
make[3]: *** [scripts/Makefile.build:551: drivers/gpu] Error 2
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[1]: *** [/home/kbuild/kernel/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
Build failed, no error log produced



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

* Re: [PATCH] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices
  2026-09-06  5:42 [PATCH] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
  2026-09-06  5:52 ` ✗ Fi.CI.BUILD: failure for " Patchwork
@ 2026-09-06  6:02 ` sashiko-bot
  1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-09-06  6:02 UTC (permalink / raw)
  To: Xiao Lu; +Cc: intel-gfx

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Bypassing `intel_dp_dsc_get_slice_config()` leaves `slice_config` zero-initialized, causing a divide-by-zero kernel panic in `intel_dsc_compute_params()`.
- [High] An existing early return prevents the new DSC passthrough capability detection from executing for passthrough-only PCONs.
- [High] Unconditional DPCD capability checks will fail and abort modesets or zero limits for passthrough PCONs with an all-zero `dsc_dpcd`.
- [High] Bypassing `intel_dp_dsc_get_slice_config()` ignores Intel VDSC hardware constraints by selecting slice counts based exclusively on the HDMI sink.
- [High] The `pcon_dsc_passthrough` capability flag is evaluated and cached before the EDID is parsed, using uninitialized or stale display data.
- [Medium] Assignment to a nonexistent struct member `slice_count` in `struct intel_crtc_state`'s `dsc` struct causes a compilation failure.
--

commit 542b41d19d507f8a0d3cdb73bcd6ff8c7a8d22d5
Author: Xiao Lu <xiaolu.xie@intel.com>
Subject: drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices

This patch adds explicit driver control of PCON DSC passthrough for HDMI 2.1
devices. It detects the passthrough capability from DPCD and the HDMI sink
EDID, skipping the PCON's own DSC decompression to forward the stream
unchanged.

> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 113d767e62e9c..ad55b08ecdea6 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c

[ ... ]

> @@ -2403,7 +2412,21 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  		}
>  	}
>  
> -	if (!intel_dp_dsc_get_slice_config(connector, adjusted_mode->crtc_clock,
> +	if (intel_dp->attached_connector->dp.pcon_dsc_passthrough) {

[Severity: High]
Since passthrough-only PCONs have an all-zero dsc_dpcd, won't the 
unconditional call to intel_dp_dsc_supports_format() at the beginning of 
intel_dp_dsc_compute_config() parse the empty DPCD and return -EINVAL
immediately? 

Similarly, in intel_dp_compute_config_limits(), won't the unconditional call
to align_max_sink_dsc_input_bpp() parse the empty dsc_dpcd and clamp the
limits to 0?

> +		/*
> +		 * PCON passthrough: no PCON encoder DPCD, derive slice count
> +		 * from the downstream HDMI 2.1 sink DSC capabilities.
> +		 */
> +		u8 pt_slice_count =
> +			intel_dp_pcon_passthrough_dsc_slice_count(intel_dp,
> +								  pipe_config);
> +		if (!pt_slice_count) {
> +			drm_dbg_kms(display->drm,
> +				    "PCON DSC passthrough: no valid slice count\n");
> +			return -EINVAL;
> +		}
> +		pipe_config->dsc.slice_count = pt_slice_count;

[Severity: Medium]
Does pipe_config->dsc contain a member named slice_count? It looks like
the slice_count member actually resides in the nested struct
drm_dsc_config config, which would cause a build failure here.

[Severity: High]
By taking this branch and bypassing intel_dp_dsc_get_slice_config(),
pipe_config->dsc.slice_config is left zero-initialized. Could this cause a
divide-by-zero kernel panic later in intel_dsc_compute_params() when it
executes:

vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width,
    intel_dsc_line_slice_count(&pipe_config->dsc.slice_config));

because intel_dsc_line_slice_count() returns 0 for a zeroed struct?

> +	} else if (!intel_dp_dsc_get_slice_config(connector, adjusted_mode->crtc_clock,
>  					   adjusted_mode->crtc_hdisplay, num_joined_pipes,
>  					   &pipe_config->dsc.slice_config))
>  		return -EINVAL;

[ ... ]

> @@ -4297,6 +4360,71 @@ void intel_dp_check_frl_training(struct intel_dp *intel_dp)
>  	}
>  }
>  
> +/*
> + * intel_dp_pcon_set_dsc_passthrough_cap - cache PCON DSC passthrough capability
> + *
> + * Called once at connect time (from intel_dp_get_dsc_sink_cap()) after
> + * dsc_dpcd and the HDMI sink EDID have been read. Caches the result in
> + * connector->dp.pcon_dsc_passthrough so modeset paths can read it cheaply
> + * without repeating the DPCD and EDID lookups.
> + *
> + * A PCON supports DSC passthrough when it explicitly advertises
> + * DP_DSC_PASSTHROUGH_IS_SUPPORTED (DPCD 0x060 bit1) and the downstream
> + * HDMI 2.1 sink supports DSC 1.2. The compressed stream produced by the
> + * source VDSC engine is forwarded unchanged through the PCON to the HDMI
> + * sink for decompression (DP_DSC_ENABLE bit1 on the PCON).
> + */
> +static void
> +intel_dp_pcon_set_dsc_passthrough_cap(struct intel_dp *intel_dp)
> +{
> +	struct intel_connector *connector = intel_dp->attached_connector;
> +	const struct drm_display_info *info;
> +
> +	if (!connector)
> +		return;
> +
> +	connector->dp.pcon_dsc_passthrough = false;
> +
> +	if (!intel_dp_is_hdmi_2_1_sink(intel_dp))
> +		return;
> +
> +	if (!(connector->dp.dsc_dpcd[0] & DP_DSC_PASSTHROUGH_IS_SUPPORTED))
> +		return;
> +
> +	info = &connector->base.display_info;
> +	connector->dp.pcon_dsc_passthrough = info->hdmi.dsc_cap.v_1p2;
> +}

[Severity: High]
This capability cache relies on connector->base.display_info, but it is
called from intel_dp_detect_dsc_caps() which executes before 
intel_dp_set_edid() populates display_info. Does this cause the check to
read uninitialized memory or stale EDID data from a previously connected
monitor?

> +static u8
> +intel_dp_pcon_passthrough_dsc_slice_count(struct intel_dp *intel_dp,
> +					  const struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_display *display = to_intel_display(intel_dp);
> +	struct intel_connector *connector = intel_dp->attached_connector;
> +	const struct drm_display_info *info = &connector->base.display_info;
> +	int hdmi_throughput = info->hdmi.dsc_cap.clk_per_slice;
> +	int hdmi_max_slices = info->hdmi.dsc_cap.max_slices;
> +	int num_slices;
> +
> +	/*
> +	 * Passthrough: no PCON encoder constraints, use only the HDMI sink
> +	 * DSC caps from EDID. Pass hdisplay for pcon_max_slice_width so that
> +	 * constraint is effectively unconstrained.
> +	 */
> +	num_slices = intel_hdmi_dsc_get_num_slices(crtc_state,
> +						   hdmi_max_slices,
> +						   crtc_state->hw.adjusted_mode.hdisplay,
> +						   hdmi_max_slices,
> +						   hdmi_throughput);

[Severity: High]
By passing hdmi_max_slices as the src_max_slices parameter, this discards
all source VDSC constraints. If the HDMI sink supports up to 16 slices but
the source VDSC only supports a maximum of 4 slices per pipe, could this
result in misconfiguring the source VDSC with a slice count it physically
cannot generate?

[ ... ]

> @@ -4565,6 +4694,8 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
>  	if (drm_dp_has_quirk(desc, DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT) &&
>  	    desc->ident.hw_rev == 0x10)
>  		connector->dp.dsc_throughput_quirk = true;
> +
> +	intel_dp_pcon_set_dsc_passthrough_cap(intel_attached_dp(connector));
>  }

[Severity: High]
Earlier in intel_dp_get_dsc_sink_cap(), there is an early return:

    if (!(connector->dp.dsc_dpcd[0] & DP_DSC_DECOMPRESSION_IS_SUPPORTED))
        return;
        
Since passthrough-only PCONs lack a DSC decoder and do not set
DP_DSC_DECOMPRESSION_IS_SUPPORTED, doesn't this early return prevent
intel_dp_pcon_set_dsc_passthrough_cap() from ever executing for these
devices?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260906054239.854844-1-xiaolu.xie@intel.com?part=1

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

end of thread, other threads:[~2026-09-06  6:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-06  5:42 [PATCH] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
2026-09-06  5:52 ` ✗ Fi.CI.BUILD: failure for " Patchwork
2026-09-06  6:02 ` [PATCH] " sashiko-bot

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