]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: panel inst for monitors
authorPeichen Huang <PeiChen.Huang@amd.com>
Wed, 24 Dec 2025 06:39:52 +0000 (14:39 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 20 Jan 2026 22:19:16 +0000 (17:19 -0500)
[WHY]
To find proper panel replay panel inst for external monitors.

[HOW]
Use otg index as panel replay panel inst.
Both Replay features use the same logic to get panel inst.
Correct the bug that would overwrite panel inst in cmd

Reviewed-by: Robin Chen <robin.chen@amd.com>
Signed-off-by: Peichen Huang <PeiChen.Huang@amd.com>
Signed-off-by: Matthew Stewart <matthew.stewart2@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c

index be441851d8764158fd96fd2abef74da4c1b25600..bbd6f93f5c9818c6b288845d1f9efba07c529296 100644 (file)
@@ -156,13 +156,23 @@ bool dp_pr_get_panel_inst(const struct dc *dc,
                const struct dc_link *link,
                unsigned int *inst_out)
 {
-       if (dc_is_embedded_signal(link->connector_signal)) {
-               /* TODO: just get edp link panel inst for now, fix it */
-               return dc_get_edp_link_panel_inst(dc, link, inst_out);
-       } else if (dc_is_dp_sst_signal(link->connector_signal)) {
-               /* TODO: just set to 1 for now, fix it */
-               *inst_out = 1;
-               return true;
+       if (!dc || !link || !inst_out)
+               return false;
+
+       if (!dc_is_dp_sst_signal(link->connector_signal)) /* only supoprt DP sst (eDP included) for now */
+               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 == link) {
+                       /* *inst_out is equal to otg number */
+                       if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg)
+                               *inst_out = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg->inst;
+                       else
+                               *inst_out = 0;
+
+                       return true;
+               }
        }
 
        return false;
@@ -280,13 +290,13 @@ bool dp_pr_update_state(struct dc_link *link, struct dmub_cmd_pr_update_state_da
                return false;
 
        memset(&cmd, 0, sizeof(cmd));
+       memcpy(&cmd.pr_update_state.data, update_state_data, sizeof(struct dmub_cmd_pr_update_state_data));
+
        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;
 }
@@ -301,13 +311,13 @@ bool dp_pr_set_general_cmd(struct dc_link *link, struct dmub_cmd_pr_general_cmd_
                return false;
 
        memset(&cmd, 0, sizeof(cmd));
+       memcpy(&cmd.pr_general_cmd.data, general_cmd_data, sizeof(struct dmub_cmd_pr_general_cmd_data));
+
        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;
 }
index cb4129c0937a908f523522ca57d080e0e764a622..aa02b38e183aa76bd4f871bb1cb688a3a5878d94 100644 (file)
@@ -39,6 +39,7 @@
 #include "dce/dmub_replay.h"
 #include "abm.h"
 #include "resource.h"
+#include "link_dp_panel_replay.h"
 #define DC_LOGGER \
        link->ctx->logger
 #define DC_LOGGER_INIT(logger)
@@ -942,7 +943,7 @@ bool edp_set_replay_allow_active(struct dc_link *link, const bool *allow_active,
        if (replay == NULL && force_static)
                return false;
 
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+       if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
                return false;
 
        /* Set power optimization flag */
@@ -973,7 +974,7 @@ bool edp_get_replay_state(const struct dc_link *link, uint64_t *state)
        unsigned int panel_inst;
        enum replay_state pr_state = REPLAY_STATE_0;
 
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+       if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
                return false;
 
        if (replay != NULL && link->replay_settings.replay_feature_enabled)
@@ -1020,7 +1021,7 @@ bool edp_setup_freesync_replay(struct dc_link *link, const struct dc_stream_stat
        if (!replay)
                return false;
 
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+       if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
                return false;
 
        replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel;
@@ -1099,7 +1100,7 @@ bool edp_send_replay_cmd(struct dc_link *link,
 
        DC_LOGGER_INIT(link->ctx->logger);
 
-       if (dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+       if (dp_pr_get_panel_inst(dc, link, &panel_inst))
                cmd_data->panel_inst = panel_inst;
        else {
                DC_LOG_DC("%s(): get edp panel inst fail ", __func__);
@@ -1120,7 +1121,7 @@ bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal, uin
        if (!replay)
                return false;
 
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+       if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
                return false;
 
        if (coasting_vtotal && (link->replay_settings.coasting_vtotal != coasting_vtotal ||
@@ -1140,7 +1141,7 @@ bool edp_replay_residency(const struct dc_link *link,
        struct dmub_replay *replay = dc->res_pool->replay;
        unsigned int panel_inst;
 
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+       if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
                return false;
 
        if (!residency)
@@ -1161,7 +1162,7 @@ bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link,
        struct dmub_replay *replay = dc->res_pool->replay;
        unsigned int panel_inst;
 
-       if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+       if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
                return false;
 
        /* Only both power and coasting vtotal changed, this func could return true */