From: Peichen Huang <[email protected]>

[WHY]
Panel Replay is not an eDP-specific function.

[HOW]
Create new Panel Replay source files and move the Panel Replay
functions from the eDP files to the new files. Additionally, create
a new link_service construct function to assign the related
function pointers.

Reviewed-by: Robin Chen <[email protected]>
Signed-off-by: Peichen Huang <[email protected]>
Signed-off-by: Matthew Stewart <[email protected]>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_replay.c  |   2 +-
 .../drm/amd/display/dc/core/dc_link_exports.c |   9 +-
 .../gpu/drm/amd/display/dc/inc/link_service.h |  10 +-
 drivers/gpu/drm/amd/display/dc/link/Makefile  |   2 +-
 .../drm/amd/display/dc/link/link_factory.c    |  18 +-
 .../dc/link/protocols/link_dp_irq_handler.c   |   1 +
 .../dc/link/protocols/link_dp_panel_replay.c  | 308 ++++++++++++++++++
 .../dc/link/protocols/link_dp_panel_replay.h  |  38 +++
 .../link/protocols/link_edp_panel_control.c   | 271 +--------------
 .../link/protocols/link_edp_panel_control.h   |   8 +-
 10 files changed, 373 insertions(+), 294 deletions(-)
 create mode 100644 
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c
 create mode 100644 
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.h

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 da94e3544b65..fb619a3336b7 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
@@ -161,7 +161,7 @@ bool amdgpu_dm_replay_enable(struct dc_stream_state 
*stream, bool wait)
        link = stream->link;
 
        if (link) {
-               link->dc->link_srv->edp_setup_replay(link, stream);
+               link->dc->link_srv->dp_setup_replay(link, stream);
                link->dc->link_srv->edp_set_coasting_vtotal(link, 
stream->timing.v_total, 0);
                DRM_DEBUG_DRIVER("Enabling replay...\n");
                link->dc->link_srv->edp_set_replay_allow_active(link, 
&replay_active, wait, false, NULL);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
index a8d7228907c2..7bb4504889be 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
@@ -493,24 +493,24 @@ bool dc_link_get_replay_state(const struct dc_link *link, 
uint64_t *state)
 
 bool dc_link_set_pr_enable(struct dc_link *link, bool enable)
 {
-       return link->dc->link_srv->edp_pr_enable(link, enable);
+       return link->dc->link_srv->dp_pr_enable(link, enable);
 }
 
 bool dc_link_update_pr_state(struct dc_link *link,
                struct dmub_cmd_pr_update_state_data *update_state_data)
 {
-       return link->dc->link_srv->edp_pr_update_state(link, update_state_data);
+       return link->dc->link_srv->dp_pr_update_state(link, update_state_data);
 }
 
 bool dc_link_set_pr_general_cmd(struct dc_link *link,
                struct dmub_cmd_pr_general_cmd_data *general_cmd_data)
 {
-       return link->dc->link_srv->edp_pr_set_general_cmd(link, 
general_cmd_data);
+       return link->dc->link_srv->dp_pr_set_general_cmd(link, 
general_cmd_data);
 }
 
 bool dc_link_get_pr_state(const struct dc_link *link, uint64_t *state)
 {
-       return link->dc->link_srv->edp_pr_get_state(link, state);
+       return link->dc->link_srv->dp_pr_get_state(link, state);
 }
 
 bool dc_link_wait_for_t12(struct dc_link *link)
@@ -549,4 +549,3 @@ void dc_link_get_alpm_support(struct dc_link *link,
 {
        link->dc->link_srv->edp_get_alpm_support(link, auxless_support, 
auxwake_support);
 }
-
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_service.h 
b/drivers/gpu/drm/amd/display/dc/inc/link_service.h
index 4b092a9ee4c6..5885b4abdf38 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_service.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_service.h
@@ -283,7 +283,7 @@ struct link_service {
        bool (*edp_set_replay_allow_active)(struct dc_link *dc_link,
                        const bool *enable, bool wait, bool force_static,
                        const unsigned int *power_opts);
-       bool (*edp_setup_replay)(struct dc_link *link,
+       bool (*dp_setup_replay)(struct dc_link *link,
                        const struct dc_stream_state *stream);
        bool (*edp_send_replay_cmd)(struct dc_link *link,
                        enum replay_FW_Message_type msg,
@@ -304,10 +304,10 @@ struct link_service {
        bool (*edp_receiver_ready_T9)(struct dc_link *link);
        bool (*edp_receiver_ready_T7)(struct dc_link *link);
        bool (*edp_power_alpm_dpcd_enable)(struct dc_link *link, bool enable);
-       bool (*edp_pr_enable)(struct dc_link *link, bool enable);
-       bool (*edp_pr_update_state)(struct dc_link *link, struct 
dmub_cmd_pr_update_state_data *update_state_data);
-       bool (*edp_pr_set_general_cmd)(struct dc_link *link, struct 
dmub_cmd_pr_general_cmd_data *general_cmd_data);
-       bool (*edp_pr_get_state)(const struct dc_link *link, uint64_t *state);
+       bool (*dp_pr_enable)(struct dc_link *link, bool enable);
+       bool (*dp_pr_update_state)(struct dc_link *link, struct 
dmub_cmd_pr_update_state_data *update_state_data);
+       bool (*dp_pr_set_general_cmd)(struct dc_link *link, struct 
dmub_cmd_pr_general_cmd_data *general_cmd_data);
+       bool (*dp_pr_get_state)(const struct dc_link *link, uint64_t *state);
        void (*edp_set_panel_power)(struct dc_link *link, bool powerOn);
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/link/Makefile 
b/drivers/gpu/drm/amd/display/dc/link/Makefile
index 84c7af5fa589..84dace27daf7 100644
--- a/drivers/gpu/drm/amd/display/dc/link/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/link/Makefile
@@ -56,7 +56,7 @@ LINK_PROTOCOLS = link_hpd.o link_ddc.o link_dpcd.o 
link_dp_dpia.o \
 link_dp_training.o link_dp_training_8b_10b.o link_dp_training_128b_132b.o \
 link_dp_training_dpia.o link_dp_training_auxless.o \
 link_dp_training_fixed_vs_pe_retimer.o link_dp_phy.o link_dp_capability.o \
-link_edp_panel_control.o link_dp_irq_handler.o link_dp_dpia_bw.o
+link_edp_panel_control.o link_dp_panel_replay.o link_dp_irq_handler.o 
link_dp_dpia_bw.o
 
 AMD_DAL_LINK_PROTOCOLS = $(addprefix $(AMDDALPATH)/dc/link/protocols/, \
 $(LINK_PROTOCOLS))
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c 
b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
index 923517715651..e185f2caad0c 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
@@ -41,6 +41,7 @@
 #include "protocols/link_dp_phy.h"
 #include "protocols/link_dp_training.h"
 #include "protocols/link_edp_panel_control.h"
+#include "protocols/link_dp_panel_replay.h"
 #include "protocols/link_hpd.h"
 #include "gpio_service_interface.h"
 #include "atomfirmware.h"
@@ -214,7 +215,6 @@ static void construct_link_service_edp_panel_control(struct 
link_service *link_s
 
        link_srv->edp_get_replay_state = edp_get_replay_state;
        link_srv->edp_set_replay_allow_active = edp_set_replay_allow_active;
-       link_srv->edp_setup_replay = edp_setup_replay;
        link_srv->edp_send_replay_cmd = edp_send_replay_cmd;
        link_srv->edp_set_coasting_vtotal = edp_set_coasting_vtotal;
        link_srv->edp_replay_residency = edp_replay_residency;
@@ -228,13 +228,20 @@ static void 
construct_link_service_edp_panel_control(struct link_service *link_s
        link_srv->edp_receiver_ready_T9 = edp_receiver_ready_T9;
        link_srv->edp_receiver_ready_T7 = edp_receiver_ready_T7;
        link_srv->edp_power_alpm_dpcd_enable = edp_power_alpm_dpcd_enable;
-       link_srv->edp_pr_enable = edp_pr_enable;
-       link_srv->edp_pr_update_state = edp_pr_update_state;
-       link_srv->edp_pr_set_general_cmd = edp_pr_set_general_cmd;
-       link_srv->edp_pr_get_state = edp_pr_get_state;
        link_srv->edp_set_panel_power = edp_set_panel_power;
 }
 
+/* link dp panel replay implements DP panel replay functionality.
+ */
+static void construct_link_service_dp_panel_replay(struct link_service 
*link_srv)
+{
+       link_srv->dp_setup_replay = dp_setup_replay;
+       link_srv->dp_pr_enable = dp_pr_enable;
+       link_srv->dp_pr_update_state = dp_pr_update_state;
+       link_srv->dp_pr_set_general_cmd = dp_pr_set_general_cmd;
+       link_srv->dp_pr_get_state = dp_pr_get_state;
+}
+
 /* link dp cts implements dp compliance test automation protocols and manual
  * testing interfaces for debugging and certification purpose.
  */
@@ -287,6 +294,7 @@ static void construct_link_service(struct link_service 
*link_srv)
        construct_link_service_dp_phy_or_dpia(link_srv);
        construct_link_service_dp_irq_handler(link_srv);
        construct_link_service_edp_panel_control(link_srv);
+       construct_link_service_dp_panel_replay(link_srv);
        construct_link_service_dp_cts(link_srv);
        construct_link_service_dp_trace(link_srv);
 }
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c
index 4b01ab0a5a7f..47abd3ec69b3 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c
@@ -38,6 +38,7 @@
 #include "link/link_dpms.h"
 #include "dm_helpers.h"
 #include "link_dp_dpia_bw.h"
+#include "link_dp_panel_replay.h"
 
 #define DC_LOGGER \
        link->ctx->logger
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c
new file mode 100644
index 000000000000..3168c42d662c
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2025 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "link_dp_panel_replay.h"
+#include "link_edp_panel_control.h"
+#include "link_dpcd.h"
+#include "dm_helpers.h"
+#include "dc/dc_dmub_srv.h"
+#include "dce/dmub_replay.h"
+
+#define DC_LOGGER \
+       link->ctx->logger
+
+#define DP_SINK_PR_ENABLE_AND_CONFIGURATION            0x37B
+
+static bool dp_setup_panel_replay(struct dc_link *link, const struct 
dc_stream_state *stream)
+{
+       /* To-do: Setup Replay */
+       struct dc *dc;
+       struct dmub_replay *replay;
+       int i;
+       unsigned int panel_inst;
+       struct replay_context replay_context = { 0 };
+       unsigned int lineTimeInNs = 0;
+
+       union panel_replay_enable_and_configuration_1 pr_config_1 = { 0 };
+       union panel_replay_enable_and_configuration_2 pr_config_2 = { 0 };
+
+       union dpcd_alpm_configuration alpm_config;
+
+       replay_context.controllerId = CONTROLLER_ID_UNDEFINED;
+
+       if (!link)
+               return false;
+
+       //Clear Panel Replay enable & config
+       dm_helpers_dp_write_dpcd(link->ctx, link,
+               DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_1,
+               (uint8_t *)&(pr_config_1.raw), sizeof(uint8_t));
+
+       dm_helpers_dp_write_dpcd(link->ctx, link,
+               DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_2,
+               (uint8_t *)&(pr_config_2.raw), sizeof(uint8_t));
+
+       if (!(link->replay_settings.config.replay_supported))
+               return false;
+
+       dc = link->ctx->dc;
+
+       //not sure should keep or not
+       replay = dc->res_pool->replay;
+
+       if (!replay)
+               return false;
+
+       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+               return false;
+
+       replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel;
+       replay_context.digbe_inst = link->link_enc->transmitter;
+       replay_context.digfe_inst = link->link_enc->preferred_engine;
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (dc->current_state->res_ctx.pipe_ctx[i].stream
+                               == stream) {
+                       /* dmcu -1 for all controller id values,
+                        * therefore +1 here
+                        */
+                       replay_context.controllerId =
+                               
dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg->inst + 1;
+                       break;
+               }
+       }
+
+       lineTimeInNs =
+               ((stream->timing.h_total * 1000000) /
+                       (stream->timing.pix_clk_100hz / 10)) + 1;
+
+       replay_context.line_time_in_ns = lineTimeInNs;
+
+       link->replay_settings.replay_feature_enabled = 
dp_pr_copy_settings(link, &replay_context);
+
+       if (link->replay_settings.replay_feature_enabled) {
+               pr_config_1.bits.PANEL_REPLAY_ENABLE = 1;
+               pr_config_1.bits.PANEL_REPLAY_CRC_ENABLE = 1;
+               pr_config_1.bits.IRQ_HPD_ASSDP_MISSING = 1;
+               pr_config_1.bits.IRQ_HPD_VSCSDP_UNCORRECTABLE_ERROR = 1;
+               pr_config_1.bits.IRQ_HPD_RFB_ERROR = 1;
+               pr_config_1.bits.IRQ_HPD_ACTIVE_FRAME_CRC_ERROR = 1;
+               pr_config_1.bits.PANEL_REPLAY_SELECTIVE_UPDATE_ENABLE = 1;
+               pr_config_1.bits.PANEL_REPLAY_EARLY_TRANSPORT_ENABLE = 1;
+
+               pr_config_2.bits.SINK_REFRESH_RATE_UNLOCK_GRANTED = 0;
+               pr_config_2.bits.SU_Y_GRANULARITY_EXT_VALUE_ENABLED = 0;
+               pr_config_2.bits.SU_REGION_SCAN_LINE_CAPTURE_INDICATION = 0;
+
+               dm_helpers_dp_write_dpcd(link->ctx, link,
+                       DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_1,
+                       (uint8_t *)&(pr_config_1.raw), sizeof(uint8_t));
+
+               dm_helpers_dp_write_dpcd(link->ctx, link,
+                       DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_2,
+                       (uint8_t *)&(pr_config_2.raw), sizeof(uint8_t));
+
+               //ALPM Setup
+               memset(&alpm_config, 0, sizeof(alpm_config));
+               alpm_config.bits.ENABLE = 
link->replay_settings.config.alpm_mode != DC_ALPM_UNSUPPORTED ? 1 : 0;
+
+               if (link->replay_settings.config.alpm_mode == DC_ALPM_AUXLESS) {
+                       alpm_config.bits.ALPM_MODE_SEL = 1;
+                       alpm_config.bits.ACDS_PERIOD_DURATION = 1;
+               }
+
+               dm_helpers_dp_write_dpcd(
+                       link->ctx,
+                       link,
+                       DP_RECEIVER_ALPM_CONFIG,
+                       &alpm_config.raw,
+                       sizeof(alpm_config.raw));
+       }
+
+       return true;
+}
+
+bool dp_setup_replay(struct dc_link *link, const struct dc_stream_state 
*stream)
+{
+       if (!link)
+               return false;
+       if (link->replay_settings.config.replay_version == DC_VESA_PANEL_REPLAY)
+               return dp_setup_panel_replay(link, stream);
+       else if (link->replay_settings.config.replay_version == 
DC_FREESYNC_REPLAY)
+               return edp_setup_freesync_replay(link, stream);
+       else
+               return false;
+}
+
+bool dp_pr_enable(struct dc_link *link, bool enable)
+{
+       struct dc *dc = link->ctx->dc;
+       unsigned int panel_inst = 0;
+       union dmub_rb_cmd cmd;
+
+       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+               return false;
+
+       if (link->replay_settings.replay_allow_active != enable) {
+               //for sending PR enable commands to DMUB
+               memset(&cmd, 0, sizeof(cmd));
+
+               cmd.pr_enable.header.type = DMUB_CMD__PR;
+               cmd.pr_enable.header.sub_type = DMUB_CMD__PR_ENABLE;
+               cmd.pr_enable.header.payload_bytes = sizeof(struct 
dmub_cmd_pr_enable_data);
+               cmd.pr_enable.data.panel_inst = panel_inst;
+               cmd.pr_enable.data.enable = enable ? 1 : 0;
+
+               dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, 
DM_DMUB_WAIT_TYPE_WAIT);
+
+               link->replay_settings.replay_allow_active = enable;
+       }
+       return true;
+}
+
+bool dp_pr_copy_settings(struct dc_link *link, struct replay_context 
*replay_context)
+{
+       struct dc *dc = link->ctx->dc;
+       unsigned int panel_inst = 0;
+       union dmub_rb_cmd cmd;
+       struct pipe_ctx *pipe_ctx = NULL;
+
+       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+               return false;
+
+       for (unsigned int i = 0; i < MAX_PIPES; i++) {
+               if (dc->current_state->res_ctx.pipe_ctx[i].stream &&
+                       dc->current_state->res_ctx.pipe_ctx[i].stream->link &&
+                       dc->current_state->res_ctx.pipe_ctx[i].stream->link == 
link &&
+                       
dc->current_state->res_ctx.pipe_ctx[i].stream->link->connector_signal == 
SIGNAL_TYPE_EDP) {
+                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+                       //TODO: refactor for multi edp support
+                       break;
+               }
+       }
+
+       if (!pipe_ctx)
+               return false;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.pr_copy_settings.header.type = DMUB_CMD__PR;
+       cmd.pr_copy_settings.header.sub_type = DMUB_CMD__PR_COPY_SETTINGS;
+       cmd.pr_copy_settings.header.payload_bytes = sizeof(struct 
dmub_cmd_pr_copy_settings_data);
+       cmd.pr_copy_settings.data.panel_inst = panel_inst;
+       // HW inst
+       cmd.pr_copy_settings.data.aux_inst = replay_context->aux_inst;
+       cmd.pr_copy_settings.data.digbe_inst = replay_context->digbe_inst;
+       cmd.pr_copy_settings.data.digfe_inst = replay_context->digfe_inst;
+       if (pipe_ctx->plane_res.dpp)
+               cmd.pr_copy_settings.data.dpp_inst = 
pipe_ctx->plane_res.dpp->inst;
+       else
+               cmd.pr_copy_settings.data.dpp_inst = 0;
+       if (pipe_ctx->stream_res.tg)
+               cmd.pr_copy_settings.data.otg_inst = 
pipe_ctx->stream_res.tg->inst;
+       else
+               cmd.pr_copy_settings.data.otg_inst = 0;
+
+       cmd.pr_copy_settings.data.dpphy_inst = link->link_enc->transmitter;
+
+       cmd.pr_copy_settings.data.line_time_in_ns = 
replay_context->line_time_in_ns;
+       cmd.pr_copy_settings.data.flags.bitfields.fec_enable_status = 
(link->fec_state == dc_link_fec_enabled);
+       cmd.pr_copy_settings.data.flags.bitfields.dsc_enable_status = 
(pipe_ctx->stream->timing.flags.DSC == 1);
+       cmd.pr_copy_settings.data.debug.u32All = 
link->replay_settings.config.debug_flags;
+
+       dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+}
+
+bool dp_pr_update_state(struct dc_link *link, struct 
dmub_cmd_pr_update_state_data *update_state_data)
+{
+       struct dc *dc = link->ctx->dc;
+       unsigned int panel_inst = 0;
+       union dmub_rb_cmd cmd;
+
+       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+               return false;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.pr_update_state.header.type = DMUB_CMD__PR;
+       cmd.pr_update_state.header.sub_type = DMUB_CMD__PR_UPDATE_STATE;
+       cmd.pr_update_state.header.payload_bytes = sizeof(struct 
dmub_cmd_pr_update_state_data);
+       cmd.pr_update_state.data.panel_inst = panel_inst;
+
+       memcpy(&cmd.pr_update_state.data, update_state_data, sizeof(struct 
dmub_cmd_pr_update_state_data));
+
+       dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+}
+
+bool dp_pr_set_general_cmd(struct dc_link *link, struct 
dmub_cmd_pr_general_cmd_data *general_cmd_data)
+{
+       struct dc *dc = link->ctx->dc;
+       unsigned int panel_inst = 0;
+       union dmub_rb_cmd cmd;
+
+       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+               return false;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.pr_general_cmd.header.type = DMUB_CMD__PR;
+       cmd.pr_general_cmd.header.sub_type = DMUB_CMD__PR_GENERAL_CMD;
+       cmd.pr_general_cmd.header.payload_bytes = sizeof(struct 
dmub_cmd_pr_general_cmd_data);
+       cmd.pr_general_cmd.data.panel_inst = panel_inst;
+
+       memcpy(&cmd.pr_general_cmd.data, general_cmd_data, sizeof(struct 
dmub_cmd_pr_general_cmd_data));
+
+       dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+}
+
+bool dp_pr_get_state(const struct dc_link *link, uint64_t *state)
+{
+       const struct dc *dc = link->ctx->dc;
+       unsigned int panel_inst = 0;
+       uint32_t retry_count = 0;
+       uint32_t replay_state = 0;
+
+       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+               return false;
+
+       do {
+               // Send gpint command and wait for ack
+               if (!dc_wake_and_execute_gpint(dc->ctx, 
DMUB_GPINT__GET_REPLAY_STATE, panel_inst,
+                                              &replay_state, 
DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) {
+                       // Return invalid state when GPINT times out
+                       replay_state = PR_STATE_INVALID;
+               }
+               /* Copy 32-bit result into 64-bit output */
+               *state = replay_state;
+       } while (++retry_count <= 1000 && *state == PR_STATE_INVALID);
+
+       // Assert if max retry hit
+       if (retry_count >= 1000 && *state == PR_STATE_INVALID) {
+               ASSERT(0);
+               /* To-do: Add retry fail log */
+       }
+
+       return true;
+}
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.h 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.h
new file mode 100644
index 000000000000..b936092edb85
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2025 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __DC_LINK_DP_PANEL_REPLAY_H__
+#define __DC_LINK_DP_PANEL_REPLAY_H__
+
+#include "link_service.h"
+
+bool dp_setup_replay(struct dc_link *link,
+               const struct dc_stream_state *stream);
+bool dp_pr_enable(struct dc_link *link, bool enable);
+bool dp_pr_copy_settings(struct dc_link *link, struct replay_context 
*replay_context);
+bool dp_pr_update_state(struct dc_link *link, struct 
dmub_cmd_pr_update_state_data *update_state_data);
+bool dp_pr_set_general_cmd(struct dc_link *link, struct 
dmub_cmd_pr_general_cmd_data *general_cmd_data);
+bool dp_pr_get_state(const struct dc_link *link, uint64_t *state);
+
+#endif /* __DC_LINK_DP_PANEL_REPLAY_H__ */
\ No newline at end of file
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
index d6e91da72ef8..ab047ff556a1 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
@@ -1003,116 +1003,8 @@ bool edp_get_replay_state(const struct dc_link *link, 
uint64_t *state)
        return true;
 }
 
-static bool edp_setup_panel_replay(struct dc_link *link, const struct 
dc_stream_state *stream)
-{
-       /* To-do: Setup Replay */
-       struct dc *dc;
-       struct dmub_replay *replay;
-       int i;
-       unsigned int panel_inst;
-       struct replay_context replay_context = { 0 };
-       unsigned int lineTimeInNs = 0;
-
-       union panel_replay_enable_and_configuration_1 pr_config_1 = { 0 };
-       union panel_replay_enable_and_configuration_2 pr_config_2 = { 0 };
-
-       union dpcd_alpm_configuration alpm_config;
 
-       replay_context.controllerId = CONTROLLER_ID_UNDEFINED;
-
-       if (!link)
-               return false;
-
-       //Clear Panel Replay enable & config
-       dm_helpers_dp_write_dpcd(link->ctx, link,
-               DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_1,
-               (uint8_t *)&(pr_config_1.raw), sizeof(uint8_t));
-
-       dm_helpers_dp_write_dpcd(link->ctx, link,
-               DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_2,
-               (uint8_t *)&(pr_config_2.raw), sizeof(uint8_t));
-
-       if (!(link->replay_settings.config.replay_supported))
-               return false;
-
-       dc = link->ctx->dc;
-
-       //not sure should keep or not
-       replay = dc->res_pool->replay;
-
-       if (!replay)
-               return false;
-
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
-               return false;
-
-       replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel;
-       replay_context.digbe_inst = link->link_enc->transmitter;
-       replay_context.digfe_inst = link->link_enc->preferred_engine;
-
-       for (i = 0; i < MAX_PIPES; i++) {
-               if (dc->current_state->res_ctx.pipe_ctx[i].stream
-                               == stream) {
-                       /* dmcu -1 for all controller id values,
-                        * therefore +1 here
-                        */
-                       replay_context.controllerId =
-                               
dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg->inst + 1;
-                       break;
-               }
-       }
-
-       lineTimeInNs =
-               ((stream->timing.h_total * 1000000) /
-                       (stream->timing.pix_clk_100hz / 10)) + 1;
-
-       replay_context.line_time_in_ns = lineTimeInNs;
-
-       link->replay_settings.replay_feature_enabled = 
edp_pr_copy_settings(link, &replay_context);
-
-       if (link->replay_settings.replay_feature_enabled) {
-               pr_config_1.bits.PANEL_REPLAY_ENABLE = 1;
-               pr_config_1.bits.PANEL_REPLAY_CRC_ENABLE = 1;
-               pr_config_1.bits.IRQ_HPD_ASSDP_MISSING = 1;
-               pr_config_1.bits.IRQ_HPD_VSCSDP_UNCORRECTABLE_ERROR = 1;
-               pr_config_1.bits.IRQ_HPD_RFB_ERROR = 1;
-               pr_config_1.bits.IRQ_HPD_ACTIVE_FRAME_CRC_ERROR = 1;
-               pr_config_1.bits.PANEL_REPLAY_SELECTIVE_UPDATE_ENABLE = 1;
-               pr_config_1.bits.PANEL_REPLAY_EARLY_TRANSPORT_ENABLE = 1;
-
-               pr_config_2.bits.SINK_REFRESH_RATE_UNLOCK_GRANTED = 0;
-               pr_config_2.bits.SU_Y_GRANULARITY_EXT_VALUE_ENABLED = 0;
-               pr_config_2.bits.SU_REGION_SCAN_LINE_CAPTURE_INDICATION = 0;
-
-               dm_helpers_dp_write_dpcd(link->ctx, link,
-                       DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_1,
-                       (uint8_t *)&(pr_config_1.raw), sizeof(uint8_t));
-
-               dm_helpers_dp_write_dpcd(link->ctx, link,
-                       DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_2,
-                       (uint8_t *)&(pr_config_2.raw), sizeof(uint8_t));
-
-               //ALPM Setup
-               memset(&alpm_config, 0, sizeof(alpm_config));
-               alpm_config.bits.ENABLE = 
link->replay_settings.config.alpm_mode != DC_ALPM_UNSUPPORTED ? 1 : 0;
-
-               if (link->replay_settings.config.alpm_mode == DC_ALPM_AUXLESS) {
-                       alpm_config.bits.ALPM_MODE_SEL = 1;
-                       alpm_config.bits.ACDS_PERIOD_DURATION = 1;
-               }
-
-               dm_helpers_dp_write_dpcd(
-                       link->ctx,
-                       link,
-                       DP_RECEIVER_ALPM_CONFIG,
-                       &alpm_config.raw,
-                       sizeof(alpm_config.raw));
-       }
-
-       return true;
-}
-
-static bool edp_setup_freesync_replay(struct dc_link *link, const struct 
dc_stream_state *stream)
+bool edp_setup_freesync_replay(struct dc_link *link, const struct 
dc_stream_state *stream)
 {
        /* To-do: Setup Replay */
        struct dc *dc;
@@ -1208,17 +1100,6 @@ static bool edp_setup_freesync_replay(struct dc_link 
*link, const struct dc_stre
        return true;
 }
 
-bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state 
*stream)
-{
-       if (!link)
-               return false;
-       if (link->replay_settings.config.replay_version == DC_VESA_PANEL_REPLAY)
-               return edp_setup_panel_replay(link, stream);
-       else if (link->replay_settings.config.replay_version == 
DC_FREESYNC_REPLAY)
-               return edp_setup_freesync_replay(link, stream);
-       else
-               return false;
-}
 
 /*
  * This is general Interface for Replay to set an 32 bit variable to dmub
@@ -1323,156 +1204,6 @@ bool 
edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link,
        return true;
 }
 
-bool edp_pr_enable(struct dc_link *link, bool enable)
-{
-       struct dc  *dc = link->ctx->dc;
-       unsigned int panel_inst = 0;
-       union dmub_rb_cmd cmd;
-
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
-               return false;
-
-       if (link->replay_settings.replay_allow_active != enable) {
-               //for sending PR enable commands to DMUB
-               memset(&cmd, 0, sizeof(cmd));
-
-               cmd.pr_enable.header.type = DMUB_CMD__PR;
-               cmd.pr_enable.header.sub_type = DMUB_CMD__PR_ENABLE;
-               cmd.pr_enable.header.payload_bytes = sizeof(struct 
dmub_cmd_pr_enable_data);
-               cmd.pr_enable.data.panel_inst = panel_inst;
-               cmd.pr_enable.data.enable = enable ? 1 : 0;
-
-               dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, 
DM_DMUB_WAIT_TYPE_WAIT);
-
-               link->replay_settings.replay_allow_active = enable;
-       }
-       return true;
-}
-
-bool edp_pr_copy_settings(struct dc_link *link, struct replay_context 
*replay_context)
-{
-       struct dc  *dc = link->ctx->dc;
-       unsigned int panel_inst = 0;
-       union dmub_rb_cmd cmd;
-       struct pipe_ctx *pipe_ctx = NULL;
-
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
-               return false;
-
-       for (unsigned int i = 0; i < MAX_PIPES; i++) {
-               if (dc->current_state->res_ctx.pipe_ctx[i].stream &&
-                       dc->current_state->res_ctx.pipe_ctx[i].stream->link &&
-                       dc->current_state->res_ctx.pipe_ctx[i].stream->link == 
link &&
-                       
dc->current_state->res_ctx.pipe_ctx[i].stream->link->connector_signal == 
SIGNAL_TYPE_EDP) {
-                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
-                       //TODO: refactor for multi edp support
-                       break;
-               }
-       }
-
-       if (!pipe_ctx)
-               return false;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.pr_copy_settings.header.type = DMUB_CMD__PR;
-       cmd.pr_copy_settings.header.sub_type = DMUB_CMD__PR_COPY_SETTINGS;
-       cmd.pr_copy_settings.header.payload_bytes = sizeof(struct 
dmub_cmd_pr_copy_settings_data);
-       cmd.pr_copy_settings.data.panel_inst = panel_inst;
-       // HW inst
-       cmd.pr_copy_settings.data.aux_inst = replay_context->aux_inst;
-       cmd.pr_copy_settings.data.digbe_inst = replay_context->digbe_inst;
-       cmd.pr_copy_settings.data.digfe_inst = replay_context->digfe_inst;
-       if (pipe_ctx->plane_res.dpp)
-               cmd.pr_copy_settings.data.dpp_inst = 
pipe_ctx->plane_res.dpp->inst;
-       else
-               cmd.pr_copy_settings.data.dpp_inst = 0;
-       if (pipe_ctx->stream_res.tg)
-               cmd.pr_copy_settings.data.otg_inst = 
pipe_ctx->stream_res.tg->inst;
-       else
-               cmd.pr_copy_settings.data.otg_inst = 0;
-
-       cmd.pr_copy_settings.data.dpphy_inst = link->link_enc->transmitter;
-
-       cmd.pr_copy_settings.data.line_time_in_ns = 
replay_context->line_time_in_ns;
-       cmd.pr_copy_settings.data.flags.bitfields.fec_enable_status = 
(link->fec_state == dc_link_fec_enabled);
-       cmd.pr_copy_settings.data.flags.bitfields.dsc_enable_status = 
(pipe_ctx->stream->timing.flags.DSC == 1);
-       cmd.pr_copy_settings.data.debug.u32All = 
link->replay_settings.config.debug_flags;
-
-       dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-       return true;
-}
-
-bool edp_pr_update_state(struct dc_link *link, struct 
dmub_cmd_pr_update_state_data *update_state_data)
-{
-       struct dc  *dc = link->ctx->dc;
-       unsigned int panel_inst = 0;
-       union dmub_rb_cmd cmd;
-
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
-               return false;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.pr_update_state.header.type = DMUB_CMD__PR;
-       cmd.pr_update_state.header.sub_type = DMUB_CMD__PR_UPDATE_STATE;
-       cmd.pr_update_state.header.payload_bytes = sizeof(struct 
dmub_cmd_pr_update_state_data);
-       cmd.pr_update_state.data.panel_inst = panel_inst;
-
-       memcpy(&cmd.pr_update_state.data, update_state_data, sizeof(struct 
dmub_cmd_pr_update_state_data));
-
-       dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-       return true;
-}
-
-bool edp_pr_set_general_cmd(struct dc_link *link, struct 
dmub_cmd_pr_general_cmd_data *general_cmd_data)
-{
-       struct dc  *dc = link->ctx->dc;
-       unsigned int panel_inst = 0;
-       union dmub_rb_cmd cmd;
-
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
-               return false;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.pr_general_cmd.header.type = DMUB_CMD__PR;
-       cmd.pr_general_cmd.header.sub_type = DMUB_CMD__PR_GENERAL_CMD;
-       cmd.pr_general_cmd.header.payload_bytes = sizeof(struct 
dmub_cmd_pr_general_cmd_data);
-       cmd.pr_general_cmd.data.panel_inst = panel_inst;
-
-       memcpy(&cmd.pr_general_cmd.data, general_cmd_data, sizeof(struct 
dmub_cmd_pr_general_cmd_data));
-
-       dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
-       return true;
-}
-
-bool edp_pr_get_state(const struct dc_link *link, uint64_t *state)
-{
-       const struct dc  *dc = link->ctx->dc;
-       unsigned int panel_inst = 0;
-       uint32_t retry_count = 0;
-       uint32_t replay_state = 0;
-
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
-               return false;
-
-       do {
-               // Send gpint command and wait for ack
-               if (!dc_wake_and_execute_gpint(dc->ctx, 
DMUB_GPINT__GET_REPLAY_STATE, panel_inst,
-                                              &replay_state, 
DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) {
-                       // Return invalid state when GPINT times out
-                       replay_state = PR_STATE_INVALID;
-               }
-               /* Copy 32-bit result into 64-bit output */
-               *state = replay_state;
-       } while (++retry_count <= 1000 && *state == PR_STATE_INVALID);
-
-       // Assert if max retry hit
-       if (retry_count >= 1000 && *state == PR_STATE_INVALID) {
-               ASSERT(0);
-               /* To-do: Add retry fail log */
-       }
-
-       return true;
-}
 
 static struct abm *get_abm_from_stream_res(const struct dc_link *link)
 {
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
index fd63b5d0f948..8780bbc4e8c5 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
@@ -54,8 +54,6 @@ bool edp_set_sink_vtotal_in_psr_active(const struct dc_link 
*link,
 void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency, 
enum psr_residency_mode mode);
 bool edp_set_replay_allow_active(struct dc_link *dc_link, const bool *enable,
        bool wait, bool force_static, const unsigned int *power_opts);
-bool edp_setup_replay(struct dc_link *link,
-               const struct dc_stream_state *stream);
 bool edp_send_replay_cmd(struct dc_link *link,
                        enum replay_FW_Message_type msg,
                        union dmub_replay_cmd_set *cmd_data);
@@ -75,11 +73,7 @@ void edp_add_delay_for_T9(struct dc_link *link);
 bool edp_receiver_ready_T9(struct dc_link *link);
 bool edp_receiver_ready_T7(struct dc_link *link);
 bool edp_power_alpm_dpcd_enable(struct dc_link *link, bool enable);
-bool edp_pr_enable(struct dc_link *link, bool enable);
-bool edp_pr_copy_settings(struct dc_link *link, struct replay_context 
*replay_context);
-bool edp_pr_update_state(struct dc_link *link, struct 
dmub_cmd_pr_update_state_data *update_state_data);
-bool edp_pr_set_general_cmd(struct dc_link *link, struct 
dmub_cmd_pr_general_cmd_data *general_cmd_data);
-bool edp_pr_get_state(const struct dc_link *link, uint64_t *state);
+bool edp_setup_freesync_replay(struct dc_link *link, const struct 
dc_stream_state *stream);
 void edp_set_panel_power(struct dc_link *link, bool powerOn);
 void edp_set_panel_assr(struct dc_link *link, struct pipe_ctx *pipe_ctx,
                enum dp_panel_mode *panel_mode, bool enable);
-- 
2.52.0

Reply via email to