[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.li@xxxxxxx> Acked-by: Tom Chung <chiahsuan.chung@xxxxxxx> Signed-off-by: Tom Chung <chiahsuan.chung@xxxxxxx> --- .../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