Add some extra logs to better help triage blackscreen issues.

* Dump all the links to see if they have sinks associated.
* Print the edid manufacturer & product id associated with a stream that
  was just created.

Reviewed-by: Jerry Zuo <[email protected]>
Signed-off-by: Aurabindo Pillai <[email protected]>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 +++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |  6 +-
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6f5be090b744..5a0652e19890 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3394,6 +3394,67 @@ static void apply_delay_after_dpcd_poweroff(struct 
amdgpu_device *adev,
        }
 }
 
+/**
+ * amdgpu_dm_dump_links_and_sinks - Debug dump of all DC links and their sinks
+ * @adev: amdgpu device pointer
+ *
+ * Iterates through all DC links and dumps information about local and remote
+ * (MST) sinks. Should be called after connector detection is complete to see
+ * the final state of all links.
+ */
+static void amdgpu_dm_dump_links_and_sinks(struct amdgpu_device *adev)
+{
+       struct dc *dc = adev->dm.dc;
+       struct drm_device *dev = adev_to_drm(adev);
+       int li;
+
+       if (!dc)
+               return;
+
+       for (li = 0; li < dc->link_count; li++) {
+               struct dc_link *l = dc->links[li];
+               const char *name = NULL;
+               int rs;
+
+               if (!l)
+                       continue;
+               if (l->local_sink && l->local_sink->edid_caps.display_name[0])
+                       name = l->local_sink->edid_caps.display_name;
+               else
+                       name = "n/a";
+
+               drm_dbg_kms(dev,
+                       "LINK_DUMP[%d]: local_sink=%p type=%d sink_signal=%d 
sink_count=%u edid_name=%s mst_capable=%d mst_alloc_streams=%d\n",
+                       li,
+                       l->local_sink,
+                       l->type,
+                       l->local_sink ? l->local_sink->sink_signal : 
SIGNAL_TYPE_NONE,
+                       l->sink_count,
+                       name,
+                       l->dpcd_caps.is_mst_capable,
+                       l->mst_stream_alloc_table.stream_count);
+
+               /* Dump remote (MST) sinks if any */
+               for (rs = 0; rs < l->sink_count; rs++) {
+                       struct dc_sink *rsink = l->remote_sinks[rs];
+                       const char *rname = NULL;
+
+                       if (!rsink)
+                               continue;
+                       if (rsink->edid_caps.display_name[0])
+                               rname = rsink->edid_caps.display_name;
+                       else
+                               rname = "n/a";
+                       drm_dbg_kms(dev,
+                               "  REMOTE_SINK[%d:%d]: sink=%p signal=%d 
edid_name=%s\n",
+                               li, rs,
+                               rsink,
+                               rsink->sink_signal,
+                               rname);
+               }
+       }
+}
+
 static int dm_resume(struct amdgpu_ip_block *ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
@@ -3579,6 +3640,12 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
        }
        drm_connector_list_iter_end(&iter);
 
+       /* Debug dump: list all DC links and their associated sinks after 
detection
+        * is complete for all connectors. This provides a comprehensive view 
of the
+        * final state without repeating the dump for each connector.
+        */
+       amdgpu_dm_dump_links_and_sinks(adev);
+
        amdgpu_dm_irq_resume_late(adev);
 
        amdgpu_dm_smu_write_watermarks_table(adev);
@@ -5389,6 +5456,12 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
                amdgpu_set_panel_orientation(&aconnector->base);
        }
 
+       /* Debug dump: list all DC links and their associated sinks after 
detection
+        * is complete for all connectors. This provides a comprehensive view 
of the
+        * final state without repeating the dump for each connector.
+        */
+       amdgpu_dm_dump_links_and_sinks(adev);
+
        /* Software is initialized. Now we can register interrupt handlers. */
        switch (adev->asic_type) {
 #if defined(CONFIG_DRM_AMD_DC_SI)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index ccaf37d3e7e4..096fbb8ad24c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -879,9 +879,11 @@ void dc_stream_log(const struct dc *dc, const struct 
dc_stream_state *stream)
                        stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
 
                        DC_LOG_DC(
-                                       "\tdispname: %s signal: %x\n",
+                                       "\tsignal: %x dispname: %s 
manufacturer_id: 0x%x product_id: 0x%x\n",
+                                       stream->signal,
                                        stream->sink->edid_caps.display_name,
-                                       stream->signal);
+                                       stream->sink->edid_caps.manufacturer_id,
+                                       stream->sink->edid_caps.product_id);
                }
        }
 }
-- 
2.51.0

Reply via email to