From: Wayne Lin <wayne....@amd.com>

[Why & How]
In order to leverage igt tool to maintain mst feature, expose new
debugfs entry "mst_progress_status".

In our dm flow, record down the result of each phase of mst and user
can examine the mst result by checking whether each phase get completed
successfully.

Reviewed-by: Hersen Wu <hersenxs...@amd.com>
Acked-by: Alan Liu <haoping....@amd.com>
Signed-off-by: Wayne Lin <wayne....@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 20 ++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 46 ++++++++++++++++++-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 18 +++++++-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 13 ++++++
 4 files changed, 94 insertions(+), 3 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 33d66d4897dc..cdfd32c4128c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -571,6 +571,14 @@ struct dsc_preferred_settings {
        bool dsc_force_disable_passthrough;
 };
 
+enum mst_progress_status {
+       MST_STATUS_DEFAULT = 0,
+       MST_PROBE = BIT(0),
+       MST_REMOTE_EDID = BIT(1),
+       MST_ALLOCATE_NEW_PAYLOAD = BIT(2),
+       MST_CLEAR_ALLOCATED_PAYLOAD = BIT(3),
+};
+
 struct amdgpu_dm_connector {
 
        struct drm_connector base;
@@ -623,8 +631,20 @@ struct amdgpu_dm_connector {
        struct drm_display_mode freesync_vid_base;
 
        int psr_skip_count;
+
+       /* Record progress status of mst*/
+       uint8_t mst_status;
 };
 
+static inline void amdgpu_dm_set_mst_status(uint8_t *status,
+               uint8_t flags, bool set)
+{
+       if (set)
+               *status |= flags;
+       else
+               *status &= ~flags;
+}
+
 #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, 
base)
 
 extern const struct amdgpu_ip_block_version dm_ip_block;
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 991e58a3a78c..cd8db385eda0 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
@@ -49,6 +49,13 @@ struct dmub_debugfs_trace_entry {
        uint32_t param1;
 };
 
+static const char *const mst_progress_status[] = {
+       "probe",
+       "remote_edid",
+       "allocate_new_payload",
+       "clear_allocated_payload",
+};
+
 static inline const char *yesno(bool v)
 {
        return v ? "yes" : "no";
@@ -2607,6 +2614,41 @@ static int dp_is_mst_connector_show(struct seq_file *m, 
void *unused)
        return 0;
 }
 
+/*
+ * function description: Read out the mst progress status
+ *
+ * This function helps to determine the mst progress status of
+ * a mst connector.
+ *
+ * Access it with the following command:
+ *
+ *     cat /sys/kernel/debug/dri/0/DP-X/mst_progress_status
+ *
+ */
+static int dp_mst_progress_status_show(struct seq_file *m, void *unused)
+{
+       struct drm_connector *connector = m->private;
+       struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+       struct amdgpu_device *adev = drm_to_adev(connector->dev);
+       int i;
+
+       mutex_lock(&aconnector->hpd_lock);
+       mutex_lock(&adev->dm.dc_lock);
+
+       if (aconnector->mst_status == MST_STATUS_DEFAULT) {
+               seq_puts(m, "disabled\n");
+       } else {
+               for (i = 0; i < sizeof(mst_progress_status)/sizeof(char *); i++)
+                       seq_printf(m, "%s:%s\n",
+                               mst_progress_status[i],
+                               aconnector->mst_status & BIT(i) ? "done" : 
"not_done");
+       }
+
+       mutex_unlock(&adev->dm.dc_lock);
+       mutex_unlock(&aconnector->hpd_lock);
+
+       return 0;
+}
 
 DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support);
 DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
@@ -2619,6 +2661,7 @@ DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
 DEFINE_SHOW_ATTRIBUTE(internal_display);
 DEFINE_SHOW_ATTRIBUTE(psr_capability);
 DEFINE_SHOW_ATTRIBUTE(dp_is_mst_connector);
+DEFINE_SHOW_ATTRIBUTE(dp_mst_progress_status);
 
 static const struct file_operations dp_dsc_clock_en_debugfs_fops = {
        .owner = THIS_MODULE,
@@ -2762,7 +2805,8 @@ static const struct {
                {"dp_dsc_fec_support", &dp_dsc_fec_support_fops},
                {"max_bpc", &dp_max_bpc_debugfs_fops},
                {"dsc_disable_passthrough", 
&dp_dsc_disable_passthrough_debugfs_fops},
-               {"is_mst_connector", &dp_is_mst_connector_fops}
+               {"is_mst_connector", &dp_is_mst_connector_fops},
+               {"mst_progress_status", &dp_mst_progress_status_fops}
 };
 
 #ifdef CONFIG_DRM_AMD_DC_HDCP
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 137645d40b72..d66e3cd64ebd 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -312,6 +312,8 @@ bool dm_helpers_dp_mst_send_payload_allocation(
        struct amdgpu_dm_connector *aconnector;
        struct drm_dp_mst_topology_mgr *mst_mgr;
        struct drm_dp_mst_port *mst_port;
+       enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD;
+       enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 
        aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
 
@@ -325,8 +327,20 @@ bool dm_helpers_dp_mst_send_payload_allocation(
        if (!mst_mgr->mst_state)
                return false;
 
-       /* It's OK for this to fail */
-       drm_dp_update_payload_part2(mst_mgr);
+       if (!enable) {
+               set_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
+               clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
+       }
+
+       if (drm_dp_update_payload_part2(mst_mgr)) {
+               amdgpu_dm_set_mst_status(&aconnector->mst_status,
+                       set_flag, false);
+       } else {
+               amdgpu_dm_set_mst_status(&aconnector->mst_status,
+                       set_flag, true);
+               amdgpu_dm_set_mst_status(&aconnector->mst_status,
+                       clr_flag, false);
+       }
 
        if (!enable)
                drm_dp_mst_deallocate_vcpi(mst_mgr, mst_port);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 168d5676b657..c69c1086b35c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -179,6 +179,8 @@ amdgpu_dm_mst_connector_early_unregister(struct 
drm_connector *connector)
                aconnector->dc_sink = NULL;
                aconnector->edid = NULL;
        }
+
+       aconnector->mst_status = MST_STATUS_DEFAULT;
        drm_modeset_unlock(&root->mst_mgr.base.lock);
 }
 
@@ -279,6 +281,9 @@ static int dm_dp_mst_get_modes(struct drm_connector 
*connector)
                edid = drm_dp_mst_get_edid(connector, 
&aconnector->mst_port->mst_mgr, aconnector->port);
 
                if (!edid) {
+                       amdgpu_dm_set_mst_status(&aconnector->mst_status,
+                       MST_REMOTE_EDID, false);
+
                        drm_connector_update_edid_property(
                                &aconnector->base,
                                NULL);
@@ -309,6 +314,8 @@ static int dm_dp_mst_get_modes(struct drm_connector 
*connector)
                }
 
                aconnector->edid = edid;
+               amdgpu_dm_set_mst_status(&aconnector->mst_status,
+                       MST_REMOTE_EDID, true);
        }
 
        if (aconnector->dc_sink && aconnector->dc_sink->sink_signal == 
SIGNAL_TYPE_VIRTUAL) {
@@ -430,6 +437,10 @@ dm_dp_mst_detect(struct drm_connector *connector,
                dc_sink_release(aconnector->dc_sink);
                aconnector->dc_sink = NULL;
                aconnector->edid = NULL;
+
+               amdgpu_dm_set_mst_status(&aconnector->mst_status,
+                       MST_REMOTE_EDID | MST_ALLOCATE_NEW_PAYLOAD | 
MST_CLEAR_ALLOCATED_PAYLOAD,
+                       false);
        }
 
        return connection_status;
@@ -526,6 +537,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
        connector = &aconnector->base;
        aconnector->port = port;
        aconnector->mst_port = master;
+       amdgpu_dm_set_mst_status(&aconnector->mst_status,
+                       MST_PROBE, true);
 
        if (drm_connector_init(
                dev,
-- 
2.37.0

Reply via email to