drm/amd/display: Add debugfs for connector's FEC & DSC capabilities
authorEryk Brol <eryk.brol@amd.com>
Mon, 10 Aug 2020 18:02:55 +0000 (14:02 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 26 Aug 2020 20:40:18 +0000 (16:40 -0400)
[why & how]
Useful entry to understand if link has DSC or FEC capabilities,
implemented to read DPCD caps stored on the link. Better than
manually reading the registers with aux dpcd helper.

Signed-off-by: Eryk Brol <eryk.brol@amd.com>
Signed-off-by: Mikita Lipski <mikita.lipski@amd.com>
Reviewed-by: Mikita Lipski <Mikita.Lipski@amd.com>
Acked-by: Eryk Brol <eryk.brol@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c

index f878575d17bbccdd16a9c061ce38406f32f457f4..e097a60596308512dc21893796b85c70a31b4833 100644 (file)
@@ -49,6 +49,10 @@ struct dmub_debugfs_trace_entry {
        uint32_t param1;
 };
 
+static inline const char *yesno(bool v)
+{
+       return v ? "yes" : "no";
+}
 
 /* parse_write_buffer_into_params - Helper function to parse debugfs write buffer into an array
  *
@@ -980,6 +984,71 @@ static ssize_t dp_dpcd_data_read(struct file *f, char __user *buf,
        return read_size - r;
 }
 
+/* function: Read link's DSC & FEC capabilities
+ *
+ *
+ * Access it with the following command (you need to specify
+ * connector like DP-1):
+ *
+ *     cat /sys/kernel/debug/dri/0/DP-X/dp_dsc_fec_support
+ *
+ */
+static int dp_dsc_fec_support_show(struct seq_file *m, void *data)
+{
+       struct drm_connector *connector = m->private;
+       struct drm_modeset_acquire_ctx ctx;
+       struct drm_device *dev = connector->dev;
+       struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+       int ret = 0;
+       bool try_again = false;
+       bool is_fec_supported = false;
+       bool is_dsc_supported = false;
+       struct dpcd_caps dpcd_caps;
+
+       drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
+       do {
+               try_again = false;
+               ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
+               if (ret) {
+                       if (ret == -EDEADLK) {
+                               ret = drm_modeset_backoff(&ctx);
+                               if (!ret) {
+                                       try_again = true;
+                                       continue;
+                               }
+                       }
+                       break;
+               }
+               if (connector->status != connector_status_connected) {
+                       ret = -ENODEV;
+                       break;
+               }
+               dpcd_caps = aconnector->dc_link->dpcd_caps;
+               if (aconnector->port) {
+                       /* aconnector sets dsc_aux during get_modes call
+                        * if MST connector has it means it can either
+                        * enable DSC on the sink device or on MST branch
+                        * its connected to.
+                        */
+                       if (aconnector->dsc_aux) {
+                               is_fec_supported = true;
+                               is_dsc_supported = true;
+                       }
+               } else {
+                       is_fec_supported = dpcd_caps.fec_cap.raw & 0x1;
+                       is_dsc_supported = dpcd_caps.dsc_caps.dsc_basic_caps.raw[0] & 0x1;
+               }
+       } while (try_again);
+
+       drm_modeset_drop_locks(&ctx);
+       drm_modeset_acquire_fini(&ctx);
+
+       seq_printf(m, "FEC_Sink_Support: %s\n", yesno(is_fec_supported));
+       seq_printf(m, "DSC_Sink_Support: %s\n", yesno(is_dsc_supported));
+
+       return ret;
+}
+
 /* function: read DSC status on the connector
  *
  * The read function: dp_dsc_clock_en_read
@@ -1838,6 +1907,7 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
        return result;
 }
 
+DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support);
 DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
 DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer);
 DEFINE_SHOW_ATTRIBUTE(output_bpc);
@@ -1963,7 +2033,8 @@ static const struct {
                {"dsc_pic_width", &dp_dsc_pic_width_debugfs_fops},
                {"dsc_pic_height", &dp_dsc_pic_height_debugfs_fops},
                {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops},
-               {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops}
+               {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops},
+               {"dp_dsc_fec_support", &dp_dsc_fec_support_fops}
 };
 
 #ifdef CONFIG_DRM_AMD_DC_HDCP