drm/amd/display: Add debugfs entry to force YUV420 output
authorStylon Wang <stylon.wang@amd.com>
Tue, 20 Aug 2019 18:48:37 +0000 (14:48 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 17 Sep 2019 13:06:54 +0000 (08:06 -0500)
[Why]
Even if YUV420 is available for video mode, YUV444 is still
automatically selected. This poses a problem for compliance tests.

[How]
Add a per-connector debugfs entry "force_yuv420_output" to force
selection of YUV420 mode.

Signed-off-by: Stylon Wang <stylon.wang@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c

index 130da9f1b1dd1459886b3ec2dc14c23646eea9e7..b5ff7cf696c5128483fd08df5ef86eb0818c7f08 100644 (file)
@@ -3312,7 +3312,7 @@ static void fill_stream_properties_from_drm_display_mode(
 {
        struct dc_crtc_timing *timing_out = &stream->timing;
        const struct drm_display_info *info = &connector->display_info;
-
+       struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
        memset(timing_out, 0, sizeof(struct dc_crtc_timing));
 
        timing_out->h_border_left = 0;
@@ -3323,6 +3323,9 @@ static void fill_stream_properties_from_drm_display_mode(
        if (drm_mode_is_420_only(info, mode_in)
                        && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
                timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+       else if (drm_mode_is_420_also(info, mode_in)
+                       && aconnector->force_yuv420_output)
+               timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
        else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444)
                        && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
                timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
index c8c525a2b50529e5ce6413931907ee442590b475..c52ece36f5b2a07e71cf444609bf8624415b085d 100644 (file)
@@ -287,6 +287,7 @@ struct amdgpu_dm_connector {
        uint32_t debugfs_dpcd_address;
        uint32_t debugfs_dpcd_size;
 #endif
+       bool force_yuv420_output;
 };
 
 #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
index f3dfb2887ae0b0adf33e12418ead5e4c5c3895c4..e29c6314f98c4b814f44fb6fe5d1b872f113dd51 100644 (file)
@@ -942,6 +942,33 @@ static const struct {
                {"aux_dpcd_data", &dp_dpcd_data_debugfs_fops}
 };
 
+/*
+ * Force YUV420 output if available from the given mode
+ */
+static int force_yuv420_output_set(void *data, u64 val)
+{
+       struct amdgpu_dm_connector *connector = data;
+
+       connector->force_yuv420_output = (bool)val;
+
+       return 0;
+}
+
+/*
+ * Check if YUV420 is forced when available from the given mode
+ */
+static int force_yuv420_output_get(void *data, u64 *val)
+{
+       struct amdgpu_dm_connector *connector = data;
+
+       *val = connector->force_yuv420_output;
+
+       return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
+                        force_yuv420_output_set, "%llu\n");
+
 void connector_debugfs_init(struct amdgpu_dm_connector *connector)
 {
        int i;
@@ -955,6 +982,10 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
                                            dp_debugfs_entries[i].fops);
                }
        }
+
+       debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
+                                  &force_yuv420_output_fops);
+
 }
 
 /*