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

Reply via email to