[PATCH] drm/i915/display: Add debugfs entry to prefer YCbCr420 for sink output
Dibin Moolakadan Subrahmanian
dibin.moolakadan.subrahmanian at intel.com
Tue Jul 15 10:33:19 UTC 2025
This patch introduces a `prefer_sink_yuv420` flag to the `intel_connector`
structure, allowing users to prefer YCbCr 4:2:0 output format on capable
sinks(HDMI/DP). The output format selection logic will attempt to use
YUV420 if supported by the sink and when above flag is set, where current
selection logic selects RGB by default.
This is useful for validating IGT tests on scaling , Color, CASF
Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian at intel.com>
---
.../drm/i915/display/intel_display_debugfs.c | 75 +++++++++++++++++++
.../drm/i915/display/intel_display_types.h | 6 ++
drivers/gpu/drm/i915/display/intel_dp.c | 9 +++
drivers/gpu/drm/i915/display/intel_hdmi.c | 8 ++
4 files changed, 98 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index ce3f9810c42d..f03dbfb9ff03 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -1304,6 +1304,75 @@ static const struct file_operations i915_joiner_fops = {
.write = i915_joiner_write
};
+static int i915_prefer_sink_yuv420_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = m->private;
+ struct intel_display *display = to_intel_display(connector);
+ struct intel_encoder *encoder = intel_attached_encoder(connector);
+ struct drm_crtc *crtc;
+ struct intel_crtc_state *crtc_state;
+ int ret;
+
+ if (!encoder)
+ return -ENODEV;
+
+ ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
+ if (ret)
+ return ret;
+
+ crtc = connector->base.state->crtc;
+ if (connector->base.status != connector_status_connected || !crtc) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ crtc_state = to_intel_crtc_state(crtc->state);
+ seq_printf(m, "prefer_sink_yuv420:%s sink_format: %x\n",
+ str_yes_no(connector->prefer_sink_yuv420), crtc_state->sink_format);
+
+out:
+ drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
+ return ret;
+}
+
+static ssize_t i915_prefer_sink_yuv420_write(struct file *file,
+ const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct seq_file *m = file->private_data;
+ struct intel_connector *connector = m->private;
+ struct intel_encoder *encoder = intel_attached_encoder(connector);
+ int prefer_sink_yuv420 = 0;
+ int ret;
+
+ if (!encoder)
+ return -ENODEV;
+
+ ret = kstrtoint_from_user(ubuf, len, 0, &prefer_sink_yuv420);
+ if (ret < 0)
+ return ret;
+
+ connector->prefer_sink_yuv420 = !!prefer_sink_yuv420;
+ *offp += len;
+
+ return len;
+}
+
+static int i915_prefer_sink_yuv420_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, i915_prefer_sink_yuv420_show, inode->i_private);
+}
+
+static const struct file_operations i915_prefer_sink_yuv420_fops = {
+ .owner = THIS_MODULE,
+ .open = i915_prefer_sink_yuv420_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = i915_prefer_sink_yuv420_write
+};
+
/**
* intel_connector_debugfs_add - add i915 specific connector debugfs files
* @connector: pointer to a registered intel_connector
@@ -1359,6 +1428,12 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
connector_type == DRM_MODE_CONNECTOR_HDMIB)
debugfs_create_file("i915_lpsp_capability", 0444, root,
connector, &i915_lpsp_capability_fops);
+
+ if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
+ connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+ connector_type == DRM_MODE_CONNECTOR_HDMIB)
+ debugfs_create_file("i915_prefer_sink_yuv420", 0644, root,
+ connector, &i915_prefer_sink_yuv420_fops);
}
/**
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index ce45261c4a8f..93b17ff764a6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -564,6 +564,12 @@ struct intel_connector {
struct work_struct modeset_retry_work;
struct intel_hdcp hdcp;
+
+ /**
+ * Indicates that the driver should prefer using YCbCr 4:2:0 output format
+ * when the sink supports it. This flag can be toggled via debugfs.
+ */
+ bool prefer_sink_yuv420;
};
struct intel_digital_connector_state {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index f48912f308df..50ad4a096693 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3048,6 +3048,15 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
crtc_state->sink_format = intel_dp_sink_format(connector, adjusted_mode);
}
+ /* Check if prefer_sink_yuv420 is enabled and sink supports it, then override RGB */
+ if (connector->prefer_sink_yuv420 &&
+ drm_mode_is_420_also(info, adjusted_mode) &&
+ connector->base.ycbcr_420_allowed) {
+ crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
+ drm_dbg_kms(display->drm, "prefer_sink_yuv420 enabled, selected format %d\n",
+ crtc_state->sink_format);
+ }
+
crtc_state->output_format = intel_dp_output_format(connector, crtc_state->sink_format);
ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 9961ff259298..4e5916d8afb8 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2264,6 +2264,14 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
}
+ /* Check if prefer_sink_yuv420 is enabled and sink supports it, then override RGB */
+ else if (connector->prefer_sink_yuv420 &&
+ drm_mode_is_420_also(info, adjusted_mode)) {
+ crtc_state->sink_format = intel_hdmi_sink_format(crtc_state, connector, true);
+ drm_dbg_kms(display->drm, "prefer_sink_yuv420 enabled, selected format %d\n",
+ crtc_state->sink_format);
+ }
+
crtc_state->output_format = intel_hdmi_output_format(crtc_state);
ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
if (ret) {
--
2.43.0
More information about the Intel-gfx-trybot
mailing list