[Why & How]
User can get the panel replay capability and state for debug.

sudo cat /sys/kernel/debug/dri/0/eDP-1/replay_capability
"Sink support: no" - if panel doesn't support Replay
"Sink support: yes" - if panel supports Replay
"Driver support: no\n" - if driver doesn't support Replay
"Driver support: yes\n" - if driver supports Replay

sudo cat /sys/kernel/debug/dri/0/eDP-1/replay_state
It will return current panel replay state

Reviewed-by: Sun peng Li <sunpeng...@amd.com>
Acked-by: Tom Chung <chiahsuan.ch...@amd.com>
Signed-off-by: Tom Chung <chiahsuan.ch...@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 74 +++++++++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_replay.c  | 12 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_replay.h  |  2 +-
 3 files changed, 84 insertions(+), 4 deletions(-)

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 4d7a5d470b1e..7d97fdd9da92 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
@@ -30,6 +30,7 @@
 #include "amdgpu.h"
 #include "amdgpu_dm.h"
 #include "amdgpu_dm_debugfs.h"
+#include "amdgpu_dm_replay.h"
 #include "dm_helpers.h"
 #include "dmub/dmub_srv.h"
 #include "resource.h"
@@ -960,6 +961,57 @@ static int dmub_fw_state_show(struct seq_file *m, void 
*data)
        return seq_write(m, state_base, state_size);
 }
 
+/* replay_capability_show() - show eDP panel replay capability
+ *
+ * The read function: replay_capability_show
+ * Shows if sink and driver has Replay capability or not.
+ *
+ *     cat /sys/kernel/debug/dri/0/eDP-X/replay_capability
+ *
+ * Expected output:
+ * "Sink support: no\n" - if panel doesn't support Replay
+ * "Sink support: yes\n" - if panel supports Replay
+ * "Driver support: no\n" - if driver doesn't support Replay
+ * "Driver support: yes\n" - if driver supports Replay
+ */
+static int replay_capability_show(struct seq_file *m, void *data)
+{
+       struct drm_connector *connector = m->private;
+       struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+       struct dc_link *link = aconnector->dc_link;
+       bool sink_support_replay = false;
+       bool driver_support_replay = false;
+
+       if (!link)
+               return -ENODEV;
+
+       if (link->type == dc_connection_none)
+               return -ENODEV;
+
+       if (!(link->connector_signal & SIGNAL_TYPE_EDP))
+               return -ENODEV;
+
+       /* If Replay is already set to support, skip the checks */
+       if (link->replay_settings.config.replay_supported) {
+               sink_support_replay = true;
+               driver_support_replay = true;
+       } else if ((amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) {
+               sink_support_replay = amdgpu_dm_link_supports_replay(link, 
aconnector);
+       } else {
+               struct dc *dc = link->ctx->dc;
+
+               sink_support_replay = amdgpu_dm_link_supports_replay(link, 
aconnector);
+               if (dc->ctx->dmub_srv && dc->ctx->dmub_srv->dmub)
+                       driver_support_replay =
+                               
(bool)dc->ctx->dmub_srv->dmub->feature_caps.replay_supported;
+       }
+
+       seq_printf(m, "Sink support: %s\n", str_yes_no(sink_support_replay));
+       seq_printf(m, "Driver support: %s\n", 
str_yes_no(driver_support_replay));
+
+       return 0;
+}
+
 /* psr_capability_show() - show eDP panel PSR capability
  *
  * The read function: sink_psr_capability_show
@@ -2768,6 +2820,7 @@ DEFINE_SHOW_ATTRIBUTE(dp_lttpr_status);
 DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
 DEFINE_SHOW_ATTRIBUTE(internal_display);
 DEFINE_SHOW_ATTRIBUTE(odm_combine_segments);
+DEFINE_SHOW_ATTRIBUTE(replay_capability);
 DEFINE_SHOW_ATTRIBUTE(psr_capability);
 DEFINE_SHOW_ATTRIBUTE(dp_is_mst_connector);
 DEFINE_SHOW_ATTRIBUTE(dp_mst_progress_status);
@@ -2937,6 +2990,22 @@ static int force_yuv420_output_get(void *data, u64 *val)
 DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
                         force_yuv420_output_set, "%llu\n");
 
+/*
+ *  Read Replay state
+ */
+static int replay_get_state(void *data, u64 *val)
+{
+       struct amdgpu_dm_connector *connector = data;
+       struct dc_link *link = connector->dc_link;
+       uint64_t state = REPLAY_STATE_INVALID;
+
+       dc_link_get_replay_state(link, &state);
+
+       *val = state;
+
+       return 0;
+}
+
 /*
  *  Read PSR state
  */
@@ -3155,6 +3224,8 @@ static int dmcub_trace_event_state_get(void *data, u64 
*val)
 DEFINE_DEBUGFS_ATTRIBUTE(dmcub_trace_event_state_fops, 
dmcub_trace_event_state_get,
                         dmcub_trace_event_state_set, "%llu\n");
 
+DEFINE_DEBUGFS_ATTRIBUTE(replay_state_fops, replay_get_state, NULL, "%llu\n");
+
 DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
 DEFINE_DEBUGFS_ATTRIBUTE(psr_residency_fops, psr_read_residency, NULL,
                         "%llu\n");
@@ -3328,6 +3399,9 @@ void connector_debugfs_init(struct amdgpu_dm_connector 
*connector)
                }
        }
        if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
+               debugfs_create_file("replay_capability", 0444, dir, connector,
+                                       &replay_capability_fops);
+               debugfs_create_file("replay_state", 0444, dir, connector, 
&replay_state_fops);
                debugfs_create_file_unsafe("psr_capability", 0444, dir, 
connector, &psr_capability_fops);
                debugfs_create_file_unsafe("psr_state", 0444, dir, connector, 
&psr_fops);
                debugfs_create_file_unsafe("psr_residency", 0444, dir,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.c
index 738a58eebba7..41f07f13a7b5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.c
@@ -24,6 +24,7 @@
  */
 
 #include "amdgpu_dm_replay.h"
+#include "dc_dmub_srv.h"
 #include "dc.h"
 #include "dm_helpers.h"
 #include "amdgpu_dm.h"
@@ -32,12 +33,12 @@
 #include "dc/inc/link.h"
 
 /*
- * link_supports_replay() - check if the link supports replay
+ * amdgpu_dm_link_supports_replay() - check if the link supports replay
  * @link: link
  * @aconnector: aconnector
  *
  */
-static bool link_supports_replay(struct dc_link *link, struct 
amdgpu_dm_connector *aconnector)
+bool amdgpu_dm_link_supports_replay(struct dc_link *link, struct 
amdgpu_dm_connector *aconnector)
 {
        struct dm_connector_state *state = 
to_dm_connector_state(aconnector->base.state);
        struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
@@ -78,6 +79,7 @@ bool amdgpu_dm_set_replay_caps(struct dc_link *link, struct 
amdgpu_dm_connector
 {
        struct replay_config pr_config = { 0 };
        union replay_debug_flags *debug_flags = NULL;
+       struct dc *dc = link->ctx->dc;
 
        // If Replay is already set to support, return true to skip checks
        if (link->replay_settings.config.replay_supported)
@@ -89,7 +91,11 @@ bool amdgpu_dm_set_replay_caps(struct dc_link *link, struct 
amdgpu_dm_connector
        if (link->panel_config.psr.disallow_replay)
                return false;
 
-       if (!link_supports_replay(link, aconnector))
+       if (!amdgpu_dm_link_supports_replay(link, aconnector))
+               return false;
+
+       if (!dc->ctx->dmub_srv || !dc->ctx->dmub_srv->dmub ||
+               !dc->ctx->dmub_srv->dmub->feature_caps.replay_supported)
                return false;
 
        // Mark Replay is supported in pr_config
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.h
index f0d30eb47312..8126bdb1eb6b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_replay.h
@@ -38,7 +38,7 @@ enum replay_enable_option {
        pr_enable_option_full_screen_video_coasting = 0x40000,
 };
 
-
+bool amdgpu_dm_link_supports_replay(struct dc_link *link, struct 
amdgpu_dm_connector *aconnector);
 bool amdgpu_dm_replay_enable(struct dc_stream_state *stream, bool enable);
 bool amdgpu_dm_set_replay_caps(struct dc_link *link, struct 
amdgpu_dm_connector *aconnector);
 bool amdgpu_dm_link_setup_replay(struct dc_link *link, struct 
amdgpu_dm_connector *aconnector);
-- 
2.34.1

Reply via email to