From: Xiao Lu <xiaolu.xie@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: jani.nikula@linux.intel.com, ville.syrjala@linux.intel.com,
imre.deak@intel.com, ankit.k.nautiyal@intel.com,
Xiao Lu <xiaolu.xie@intel.com>
Subject: [PATCH v9] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices
Date: Wed, 9 Sep 2026 13:42:25 +0800 [thread overview]
Message-ID: <20260909054225.456573-1-xiaolu.xie@intel.com> (raw)
In-Reply-To: <20260909041041.244531-2-xiaolu.xie@intel.com>
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
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).
- 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 rather than from the PCON encoder
DPCD (all-zero for passthrough-only PCONs).
- Add PCON passthrough branch in intel_dp_dsc_compute_params() to use
DSC 1.2 defaults (version 1.2, convert_rgb per output format,
line_buf_depth=13, block_pred=true) instead of the PCON dsc_dpcd
fields which reflect passthrough device constraints, not the actual
HDMI sink decompressor.
- Skip align_max_sink_dsc_input_bpp() for PCON passthrough to prevent
the PCON dsc_dpcd color_depth_cap from zeroing pipe.max_bpp.
- 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 is preserved; the PCON
case is handled by redirecting aux to intel_dp->aux (SST) or
connector->mst.port->aux (MST via REMOTE_DPCD_WRITE) when
pcon_dsc_passthrough is set.
- Short-circuit intel_dp_sink_set_dsc_decompression() for PCON
passthrough since the PCON itself does not decompress.
- Add passthrough branch in intel_dp_mode_valid_with_dsc() to use
EDID max_slices capped by PCON dsc_dpcd slice capability.
Tested with Parade PS196G (HW 0.2, SW 241.62) connected directly (SST)
and via PS8650 MST hub 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; driver now writes 0x160=0x02 explicitly and DSC parameters are
correctly derived from the HDMI sink EDID. Depends on the preceding
drm/dp/mst patch for MST topology support.
Signed-off-by: Xiao Lu <xiaolu.xie@intel.com>
---
v9: Based on Sashiko AI review feedback:
Fix intel_dp_pcon_passthrough_dsc_slice_config() to accept an
explicit connector parameter instead of intel_dp->attached_connector,
fixing incorrect HDMI sink EDID lookup in MST paths (connector was
always the SST root connector regardless of which MST stream was
being configured).
Fix src_max_slices to use drm_dp_dsc_sink_max_slice_count() from
the PCON dsc_dpcd instead of hdmi_max_slices, so the PCON hardware
slice limit is respected as an upper bound alongside the HDMI sink
EDID limit.
v8: Sincere apologies - v7 was sent with a typo that left the old
single-parameter signature for intel_dp_pcon_set_dsc_passthrough_cap()
in place, causing the build failure. This version correctly updates
the function to accept an explicit struct intel_connector * parameter.
v7: Fix intel_dp_pcon_set_dsc_passthrough_cap() to accept an explicit
connector parameter instead of deriving it from
intel_dp->attached_connector, fixing incorrect root SST connector
access in MST paths. Make the function non-static and add a header
declaration so intel_dp_mst.c can call it. Update both SST
(intel_dp_set_edid) and MST (mst_connector_get_ddc_modes) call
sites to pass the correct per-connector context.
Remove the !connector->mst.port early-return so MST connectors
can also have pcon_dsc_passthrough set.
Remove the !connector->mst.dp guard in
intel_dp_sink_set_dsc_decompression() so MST PCON passthrough
connectors are also short-circuited correctly.
Fix intel_dp_mode_valid_with_dsc() to handle all-zero PCON dsc_dpcd
by falling back to EDID max_slices when pcon_max is zero.
v6: Add intel_dp_pcon_set_dsc_passthrough_cap() call in
mst_connector_get_ddc_modes() after EDID parsing so that MST
connectors also have pcon_dsc_passthrough evaluated correctly.
Fix checkpatch warnings.
v5: Split into two patches. Inline PCON passthrough DSC parameter
overrides into intel_dp_dsc_compute_params(). Fix convert_rgb to
depend on output_format. Remove intel_dp_pcon_set_dsc_passthrough_cap()
from intel_dp_get_dsc_sink_cap(). Pass INT_MAX as src_max_slice_width.
Add hdisplay divisibility check. Add PCON passthrough branch in
intel_dp_mode_valid_with_dsc().
v4: Rebase onto drm-intel-next-2026-09-03 to fix compilation failures.
v3: Restrict PCON DSC passthrough to SST direct connections only.
v2: Fix build failure on drm-tip.
---
.../drm/i915/display/intel_display_types.h | 1 +
drivers/gpu/drm/i915/display/intel_dp.c | 287 +++++++++++++++---
drivers/gpu/drm/i915/display/intel_dp.h | 2 +
drivers/gpu/drm/i915/display/intel_dp_mst.c | 7 +
4 files changed, 263 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 5f0fe18c0..90d77aa4d 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 c46397edf..1768ca6df 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;
}
@@ -1866,28 +1872,49 @@ static int intel_dp_dsc_compute_params(const struct intel_connector *connector,
if (ret)
return ret;
- vdsc_cfg->dsc_version_major =
- (connector->dp.dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] &
- DP_DSC_MAJOR_MASK) >> DP_DSC_MAJOR_SHIFT;
- vdsc_cfg->dsc_version_minor =
- min(intel_dp_source_dsc_version_minor(display),
- intel_dp_sink_dsc_version_minor(connector->dp.dsc_dpcd));
- if (vdsc_cfg->convert_rgb)
- vdsc_cfg->convert_rgb =
- connector->dp.dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] &
- DP_DSC_RGB;
-
- vdsc_cfg->line_buf_depth = min(INTEL_DP_DSC_MAX_LINE_BUF_DEPTH,
- drm_dp_dsc_sink_line_buf_depth(connector->dp.dsc_dpcd));
- if (!vdsc_cfg->line_buf_depth) {
- drm_dbg_kms(display->drm,
- "DSC Sink Line Buffer Depth invalid\n");
- return -EINVAL;
- }
+ if (connector->dp.pcon_dsc_passthrough) {
+ /*
+ * For PCON passthrough the HDMI 2.1 sink decompresses, not the
+ * PCON. The PCON dsc_dpcd fields reflect passthrough device
+ * constraints and are not valid for configuring the source VDSC
+ * engine. Use DSC 1.2 sink defaults instead.
+ */
+ vdsc_cfg->dsc_version_major = 1;
+ vdsc_cfg->dsc_version_minor = min(intel_dp_source_dsc_version_minor(display), 2);
+ /* Only set convert_rgb for RGB output; leave unchanged for YCbCr */
+ if (vdsc_cfg->convert_rgb)
+ vdsc_cfg->convert_rgb =
+ (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB);
+ vdsc_cfg->line_buf_depth = min(INTEL_DP_DSC_MAX_LINE_BUF_DEPTH, 13);
+ vdsc_cfg->block_pred_enable = true;
+ } else {
+ vdsc_cfg->dsc_version_major =
+ (connector->dp.dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] &
+ DP_DSC_MAJOR_MASK) >> DP_DSC_MAJOR_SHIFT;
+ vdsc_cfg->dsc_version_minor =
+ min(intel_dp_source_dsc_version_minor(display),
+ intel_dp_sink_dsc_version_minor(connector->dp.dsc_dpcd));
+ if (vdsc_cfg->convert_rgb) {
+ u8 color_fmt_cap =
+ connector->dp.dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP -
+ DP_DSC_SUPPORT];
+
+ vdsc_cfg->convert_rgb = color_fmt_cap & DP_DSC_RGB;
+ }
+
+ vdsc_cfg->line_buf_depth =
+ min(INTEL_DP_DSC_MAX_LINE_BUF_DEPTH,
+ drm_dp_dsc_sink_line_buf_depth(connector->dp.dsc_dpcd));
+ if (!vdsc_cfg->line_buf_depth) {
+ drm_dbg_kms(display->drm,
+ "DSC Sink Line Buffer Depth invalid\n");
+ return -EINVAL;
+ }
- vdsc_cfg->block_pred_enable =
- connector->dp.dsc_dpcd[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] &
- DP_DSC_BLK_PREDICTION_IS_SUPPORTED;
+ vdsc_cfg->block_pred_enable =
+ connector->dp.dsc_dpcd[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] &
+ DP_DSC_BLK_PREDICTION_IS_SUPPORTED;
+ }
return drm_dsc_compute_rc_parameters(vdsc_cfg);
}
@@ -2316,6 +2343,11 @@ void intel_dp_dsc_reset_config(struct intel_crtc_state *crtc_state)
memset(&crtc_state->dsc.config, 0, sizeof(crtc_state->dsc.config));
}
+static bool intel_dp_pcon_passthrough_dsc_slice_config(struct intel_dp *intel_dp,
+ const struct intel_connector *connector,
+ const struct intel_crtc_state *crtc_state,
+ struct intel_dsc_slice_config *config_ret);
+
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
@@ -2354,7 +2386,20 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
}
}
- if (!intel_dp_dsc_get_slice_config(connector, adjusted_mode->crtc_clock,
+ if (connector->dp.pcon_dsc_passthrough) {
+ /*
+ * PCON passthrough: no PCON encoder DPCD, derive slice config
+ * from the downstream HDMI 2.1 sink DSC capabilities in EDID.
+ */
+ if (!intel_dp_pcon_passthrough_dsc_slice_config(intel_dp,
+ connector,
+ pipe_config,
+ &pipe_config->dsc.slice_config)) {
+ drm_dbg_kms(display->drm,
+ "PCON DSC passthrough: no valid slice config\n");
+ return -EINVAL;
+ }
+ } 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;
@@ -2485,10 +2530,27 @@ bool intel_dp_mode_valid_with_dsc(struct intel_connector *connector,
num_joined_pipes,
output_format,
pipe_bpp, INT_MAX);
- int dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
- mode_clock,
- mode_hdisplay,
- num_joined_pipes);
+ int dsc_slice_count;
+
+ if (connector->dp.pcon_dsc_passthrough) {
+ /*
+ * For PCON passthrough, use the HDMI sink EDID max_slices
+ * capped by the PCON's own slice capability from dsc_dpcd.
+ * If the PCON dsc_dpcd is all-zero, fall back to EDID only.
+ */
+ const struct drm_display_info *info = &connector->base.display_info;
+ int pcon_max = drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd,
+ false);
+
+ dsc_slice_count = pcon_max ?
+ min_t(int, info->hdmi.dsc_cap.max_slices, pcon_max) :
+ info->hdmi.dsc_cap.max_slices;
+ } else {
+ dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
+ mode_clock,
+ mode_hdisplay,
+ num_joined_pipes);
+ }
if (min_bpp_x16 <= 0 || min_bpp_x16 > max_bpp_x16)
return false;
@@ -2683,8 +2745,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 /
@@ -2697,7 +2784,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
*/
limits->pipe.max_bpp = clamp(crtc_state->pipe_bpp, limits->pipe.min_bpp,
limits->pipe.max_bpp);
- if (dsc)
+ if (dsc && !connector->dp.pcon_dsc_passthrough)
limits->pipe.max_bpp = align_max_sink_dsc_input_bpp(connector,
limits->pipe.max_bpp);
@@ -3716,6 +3803,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->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,
@@ -3728,8 +3819,22 @@ 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->dp.pcon_dsc_passthrough) {
+ /*
+ * HDMI 2.1 PCON passthrough: write DP_DSC_PASSTHROUGH_EN
+ * directly to the PCON so it forwards the compressed stream
+ * to the HDMI sink. For SST use the root port aux; for MST
+ * use the MST port aux which routes via REMOTE_DPCD_WRITE.
+ */
+ if (connector->mst.port)
+ aux = &connector->mst.port->aux;
+ else
+ aux = &intel_attached_dp((struct intel_connector *)connector)->aux;
+ } else if (connector->mst.port) {
+ aux = connector->mst.port->passthrough_aux;
+ }
if (!aux)
return;
@@ -3737,7 +3842,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));
}
@@ -4259,6 +4364,112 @@ 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).
+ */
+void
+intel_dp_pcon_set_dsc_passthrough_cap(struct intel_dp *intel_dp,
+ struct intel_connector *connector)
+{
+ const struct drm_display_info *info = &connector->base.display_info;
+
+ connector->dp.pcon_dsc_passthrough = false;
+
+ /*
+ * Check PCON HDMI 2.1 capability directly from this connector's
+ * display_info so that MST connectors use their own EDID data
+ * rather than intel_dp->attached_connector (the SST root connector).
+ */
+ if (!drm_dp_is_branch(intel_dp->dpcd))
+ return;
+
+ if (!info->is_hdmi)
+ return;
+
+ if (!info->hdmi.max_frl_rate_per_lane)
+ return;
+
+ if (!(connector->dp.dsc_dpcd[0] & DP_DSC_PASSTHROUGH_IS_SUPPORTED))
+ return;
+
+ connector->dp.pcon_dsc_passthrough = info->hdmi.dsc_cap.v_1p2;
+}
+
+static bool
+intel_dp_pcon_passthrough_dsc_slice_config(struct intel_dp *intel_dp,
+ const struct intel_connector *connector,
+ const struct intel_crtc_state *crtc_state,
+ struct intel_dsc_slice_config *config_ret)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ const struct drm_display_info *info = &connector->base.display_info;
+ int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state);
+ int hdmi_throughput = info->hdmi.dsc_cap.clk_per_slice;
+ int hdmi_max_slices = info->hdmi.dsc_cap.max_slices;
+ /*
+ * Use the PCON's own DSC passthrough capability (from its virtual
+ * DPCD) as the source constraint, mirroring what
+ * intel_dp_pcon_dsc_enc_slices() does for encoder mode. This handles
+ * multi-hop topologies (e.g. MST hub -> PCON) where the intermediate
+ * hub virtual DPCD may be more restrictive than the HDMI sink EDID.
+ */
+ int pcon_max_slices = drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, false);
+ int target_slices;
+ int slices_per_pipe;
+
+ /*
+ * src_max_slice_width: pass INT_MAX so the HDMI spec limit of 2720px
+ * applies; the source VDSC HW limit (5120px) is not the binding constraint.
+ * src_max_slices: use PCON dsc_dpcd slice capability as upper bound.
+ */
+ target_slices = intel_hdmi_dsc_get_num_slices(&crtc_state->hw.adjusted_mode,
+ crtc_state->output_format,
+ pcon_max_slices, INT_MAX,
+ hdmi_max_slices,
+ hdmi_throughput);
+ if (!target_slices)
+ return false;
+
+ drm_dbg_kms(display->drm,
+ "PCON DSC passthrough: target %d slices from HDMI sink EDID cap"
+ " (max_slices=%d clk_per_slice=%d MHz)\n",
+ target_slices, hdmi_max_slices, hdmi_throughput);
+
+ for (slices_per_pipe = 1; slices_per_pipe <= 4; slices_per_pipe++) {
+ struct intel_dsc_slice_config config;
+ int line_slices;
+
+ if (!intel_dsc_get_slice_config(display,
+ num_joined_pipes, slices_per_pipe,
+ &config))
+ continue;
+
+ line_slices = intel_dsc_line_slice_count(&config);
+ if (line_slices != target_slices)
+ continue;
+
+ /* Slice count must evenly divide the horizontal display width */
+ if (crtc_state->hw.adjusted_mode.hdisplay % line_slices)
+ continue;
+
+ *config_ret = config;
+ return true;
+ }
+
+ return false;
+}
+
static int
intel_dp_pcon_dsc_enc_slice_height(const struct intel_crtc_state *crtc_state)
{
@@ -4510,6 +4721,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;
@@ -6148,6 +6360,12 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
intel_dp_update_dfp(intel_dp, drm_edid);
intel_dp_update_420(intel_dp);
+ /*
+ * Re-evaluate PCON DSC passthrough capability now that the EDID has
+ * been parsed and display_info.hdmi.dsc_cap is up to date.
+ */
+ intel_dp_pcon_set_dsc_passthrough_cap(intel_dp, connector);
+
drm_dp_cec_attach(&intel_dp->aux,
connector->base.display_info.source_physical_address);
}
@@ -6170,6 +6388,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
intel_dp->dfp.ycbcr_444_to_420 = false;
connector->base.ycbcr_420_allowed = false;
+ connector->dp.pcon_dsc_passthrough = false;
drm_connector_set_vrr_capable_property(&connector->base,
false);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 04fae203b..42c2fb5c2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -187,6 +187,8 @@ void intel_dp_sync_state(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void intel_dp_check_frl_training(struct intel_dp *intel_dp);
+void intel_dp_pcon_set_dsc_passthrough_cap(struct intel_dp *intel_dp,
+ struct intel_connector *connector);
void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 6a869d0f6..d48fe87ce 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1451,6 +1451,13 @@ static int mst_connector_get_ddc_modes(struct drm_connector *_connector)
ret = intel_connector_update_modes(&connector->base, drm_edid);
+ /*
+ * Re-evaluate PCON DSC passthrough capability now that the MST
+ * connector's EDID has been parsed and display_info.hdmi.dsc_cap
+ * is populated.
+ */
+ intel_dp_pcon_set_dsc_passthrough_cap(intel_dp, connector);
+
drm_edid_free(drm_edid);
if (intel_dp_tunnel_uhbr_lanes_wa_setup(intel_dp)) {
--
2.43.0
next prev parent reply other threads:[~2026-09-09 5:44 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-06 9:41 [PATCH v4] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
2026-09-06 10:00 ` sashiko-bot
2026-09-06 10:23 ` ✓ i915.CI.BAT: success for drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices (rev4) Patchwork
2026-09-06 12:28 ` ✗ i915.CI.Full: failure " Patchwork
2026-09-07 4:41 ` [PATCH v5 1/2] drm/dp/mst: recognize DP-to-HDMI PCON as virtual DPCD in DP-to-DP topology Xiao Lu
2026-09-07 4:41 ` [PATCH v5 2/2] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
2026-09-07 4:56 ` sashiko-bot
2026-09-07 4:53 ` [PATCH v5 1/2] drm/dp/mst: recognize DP-to-HDMI PCON as virtual DPCD in DP-to-DP topology sashiko-bot
2026-09-07 4:44 ` [PATCH v5 0/2] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
2026-09-07 4:44 ` [PATCH v5 1/2] drm/dp/mst: recognize DP-to-HDMI PCON as virtual DPCD in DP-to-DP topology Xiao Lu
2026-09-07 4:54 ` sashiko-bot
2026-09-07 4:44 ` [PATCH v5 2/2] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
2026-09-07 5:04 ` sashiko-bot
2026-09-09 3:35 ` [PATCH v6 1/2] drm/dp/mst: recognize DP-to-HDMI PCON as virtual DPCD in DP-to-DP topology Xiao Lu
2026-09-09 3:35 ` [PATCH v6 2/2] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
2026-09-09 3:47 ` sashiko-bot
2026-09-09 4:10 ` [PATCH v7 1/2] drm/dp/mst: recognize DP-to-HDMI PCON as virtual DPCD in DP-to-DP topology Xiao Lu
2026-09-09 4:10 ` [PATCH v7 2/2] drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices Xiao Lu
2026-09-09 4:21 ` sashiko-bot
2026-09-09 5:13 ` [PATCH v8] " Xiao Lu
2026-09-09 5:29 ` sashiko-bot
2026-09-09 5:42 ` Xiao Lu [this message]
2026-09-09 5:57 ` [PATCH v9] " sashiko-bot
2026-09-09 4:20 ` [PATCH v7 1/2] drm/dp/mst: recognize DP-to-HDMI PCON as virtual DPCD in DP-to-DP topology sashiko-bot
2026-09-07 6:30 ` ✓ i915.CI.BAT: success for drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices (rev7) Patchwork
2026-09-07 11:33 ` ✓ i915.CI.Full: " Patchwork
2026-09-09 3:50 ` ✗ Fi.CI.BUILD: failure for drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices (rev9) Patchwork
2026-09-09 4:24 ` ✗ Fi.CI.BUILD: failure for drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices (rev11) Patchwork
2026-09-09 6:01 ` ✓ i915.CI.BAT: success for drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices (rev12) Patchwork
2026-09-09 6:36 ` ✓ i915.CI.BAT: success for drm/i915/dp: enable DSC passthrough for HDMI 2.1 PCON devices (rev13) Patchwork
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=20260909054225.456573-1-xiaolu.xie@intel.com \
--to=xiaolu.xie@intel.com \
--cc=ankit.k.nautiyal@intel.com \
--cc=imre.deak@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=ville.syrjala@linux.intel.com \
/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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox