[PATCH 22/41] drm/amd/display: Unify force_yuv debugfs into force_yuv_pixel_format
<[email protected]> Fri, 31 Jul 2026 17:12:43 -0400
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: Ivan Lipski <[email protected]> [Why] The connector exposed a single force_yuv420_output boolean debugfs and carried force_yuv420_output / force_yuv422_output boolean fields to force a chroma encoding. This cannot express "force RGB" or "force YCbCr444", and diverges from the upstream amdgpu_dm which uses a single force_yuv_pixel_format field keyed on enum dc_pixel_encoding. [How] - Replace the two boolean fields with a single uint8_t force_yuv_pixel_format holding an enum dc_pixel_encoding value (PIXEL_ENCODING_UNDEFINED == no override). - Replace the force_yuv420_output boolean debugfs with a read/write force_yuv_pixel_format file that takes the encoding directly (1=RGB, 2=YCbCr422, 3=YCbCr444, 4=YCbCr420), validated against PIXEL_ENCODING_COUNT. - Convert the existing readers/writers in amdgpu_dm_connector.c to the new field, preserving current behaviour. - Add YCbCr444 force support now that the field can express it. Assisted-by: Copilot:claude-opus-4.8 Reviewed-by: Jerry Zuo <[email protected]> Signed-off-by: Ivan Lipski <[email protected]> Signed-off-by: Roman Li <[email protected]> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 2 - .../display/amdgpu_dm/amdgpu_dm_connector.c | 23 +++++--- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 57 +++++++------------ 3 files changed, 34 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 1ddf5bc88a03..3524931451c8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -857,8 +857,6 @@ struct amdgpu_dm_connector { struct mutex hpd_lock; bool fake_enable; - bool force_yuv420_output; - bool force_yuv422_output; uint8_t force_yuv_pixel_format; struct dsc_preferred_settings dsc_settings; struct psr_caps psr_caps; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c index 825c3408763c..4304520d2484 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c @@ -147,7 +147,7 @@ STATIC_IFN_KUNIT int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, int max_bpc = conn_state->max_requested_bpc; is_y420 = drm_mode_is_420_also(&connector->display_info, adjusted_mode) && - aconnector->force_yuv420_output; + aconnector->force_yuv_pixel_format == PIXEL_ENCODING_YCBCR420; color_depth = amdgpu_dm_convert_color_depth_from_display_info(connector, is_y420, max_bpc); @@ -2280,20 +2280,25 @@ amdgpu_dm_create_validate_stream_for_sink(struct drm_connector *connector, * - RGB is the mandatory baseline and always available. * - YCbCr444 is only meaningful for native HDMI sinks. * - A 420-only mode collapses the mask to YCbCr420 alone. - * - The debugfs force_yuv420_output / force_yuv422_output overrides - * pin the encoding to a single value when set. An explicit YCbCr420 - * force is honoured even on modes the sink only lists as RGB/4:4:4 - * capable (drm_mode_is_420_also() clear), as required for HDMI - * compliance testing; dc_validate_stream() still rejects anything - * the link genuinely cannot carry. The YCbCr422 force stays gated on + * - The debugfs force_yuv_pixel_format override pins the encoding to a + * single dc_pixel_encoding when set (PIXEL_ENCODING_UNDEFINED means + * "no override"). An explicit YCbCr420 force is honoured even on + * modes the sink only lists as RGB/4:4:4 capable + * (drm_mode_is_420_also() clear), as required for HDMI compliance + * testing; dc_validate_stream() still rejects anything the link + * genuinely cannot carry. The YCbCr422/YCbCr444 forces stay gated on * the sink's advertised caps. */ if (drm_mode_is_420_only(info, drm_mode) || - aconnector->force_yuv420_output) { + aconnector->force_yuv_pixel_format == PIXEL_ENCODING_YCBCR420) { encoding_mask = BIT(PIXEL_ENCODING_YCBCR420); - } else if (aconnector->force_yuv422_output && + } else if (aconnector->force_yuv_pixel_format == PIXEL_ENCODING_YCBCR422 && (info->color_formats & BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422))) { encoding_mask = BIT(PIXEL_ENCODING_YCBCR422); + } else if (aconnector->force_yuv_pixel_format == PIXEL_ENCODING_YCBCR444 && + (info->color_formats & BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444)) && + is_hdmi_ep) { + encoding_mask = BIT(PIXEL_ENCODING_YCBCR444); } else { encoding_mask = BIT(PIXEL_ENCODING_RGB); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 830cf8da06b4..c4b2fc690fd7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -3199,57 +3199,42 @@ static const struct { }; /* - * Force YUV420 output if available from the given mode + * Force a specific pixel encoding for the given connector, overriding the + * encoding that stream validation would otherwise pick. The value is an + * enum dc_pixel_encoding: + * + * 0 - PIXEL_ENCODING_UNDEFINED (no override, default) + * 1 - PIXEL_ENCODING_RGB + * 2 - PIXEL_ENCODING_YCBCR422 + * 3 - PIXEL_ENCODING_YCBCR444 + * 4 - PIXEL_ENCODING_YCBCR420 */ -static int force_yuv420_output_set(void *data, u64 val) +static int force_yuv_pixel_format_set(void *data, u64 val) { struct amdgpu_dm_connector *connector = data; - connector->force_yuv420_output = (bool)val; - connector->force_yuv_pixel_format = PIXEL_ENCODING_YCBCR420; + if (val >= PIXEL_ENCODING_COUNT) + return -EINVAL; + + connector->force_yuv_pixel_format = (uint8_t)val; return 0; } /* - * Check if YUV420 is forced when available from the given mode + * Read back the pixel encoding currently forced on the given connector. */ -static int force_yuv420_output_get(void *data, u64 *val) +static int force_yuv_pixel_format_get(void *data, u64 *val) { struct amdgpu_dm_connector *connector = data; - *val = connector->force_yuv420_output; + *val = connector->force_yuv_pixel_format; return 0; } -DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get, - force_yuv420_output_set, "%llu\n"); - -static int force_yuv422_output_set(void *data, u64 val) -{ - struct amdgpu_dm_connector *connector = data; - - connector->force_yuv422_output = (bool)val; - connector->force_yuv_pixel_format = PIXEL_ENCODING_YCBCR422; - - return 0; -} - -DEFINE_DEBUGFS_ATTRIBUTE(force_yuv422_output_fops, NULL, - force_yuv422_output_set, "%llu\n"); - -static int force_yuv444_output_set(void *data, u64 val) -{ - struct amdgpu_dm_connector *connector = data; - - connector->force_yuv_pixel_format = PIXEL_ENCODING_YCBCR444; - - return 0; -} - -DEFINE_DEBUGFS_ATTRIBUTE(force_yuv444_output_fops, NULL, - force_yuv444_output_set, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(force_yuv_pixel_format_fops, force_yuv_pixel_format_get, + force_yuv_pixel_format_set, "%llu\n"); /* * Read Replay state @@ -3699,9 +3684,7 @@ static const struct { char *name; const struct file_operations *fops; } connector_debugfs_entries[] = { - {"force_yuv420_output", &force_yuv420_output_fops}, - {"force_yuv422_output", &force_yuv422_output_fops}, - {"force_yuv444_output", &force_yuv444_output_fops}, + {"force_yuv_pixel_format", &force_yuv_pixel_format_fops}, {"trigger_hotplug", &trigger_hotplug_debugfs_fops}, {"internal_display", &internal_display_fops}, {"odm_combine_segments", &odm_combine_segments_fops} -- 2.34.1