drm/amd/display: Fix Mismatch between pipe and stream
authorGabe Teeger <gabe.teeger@amd.com>
Fri, 15 Dec 2023 01:56:58 +0000 (20:56 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 3 Jan 2024 15:47:42 +0000 (10:47 -0500)
[Why]
Failing mode validation during dc_commit, leading to blackscreen with an
8k DP2 display during mode change.

[What]
Fix mixmatch between pipe and stream, which prevented us from
recognizing the link as DP2.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Dmytro Laktyushkin <dmytro.laktyushkin@amd.com>
Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: Gabe Teeger <gabe.teeger@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c

index bc2959fda5be3b42a1c3250452a37f70bd1e7c57..fa6a93dd9629558120304beae4da239a60268c0d 100644 (file)
@@ -1049,9 +1049,10 @@ static void dml2_populate_pipe_to_plane_index_mapping(struct dml2_context *dml2,
 
 void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_state *context, struct dml_display_cfg_st *dml_dispcfg)
 {
-       int i = 0, j = 0;
+       int i = 0, j = 0, k = 0;
        int disp_cfg_stream_location, disp_cfg_plane_location;
        enum mall_stream_type stream_mall_type;
+       struct pipe_ctx *current_pipe_context;
 
        for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
                dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id_valid[i] = false;
@@ -1071,6 +1072,15 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
        dml2_populate_pipe_to_plane_index_mapping(dml2, context);
 
        for (i = 0; i < context->stream_count; i++) {
+               current_pipe_context = NULL;
+               for (k = 0; k < MAX_PIPES; k++) {
+                       /* find one pipe allocated to this stream for the purpose of getting
+                       info about the link later */
+                       if (context->streams[i] == context->res_ctx.pipe_ctx[k].stream) {
+                               current_pipe_context = &context->res_ctx.pipe_ctx[k];
+                               break;
+                       }
+               }
                disp_cfg_stream_location = map_stream_to_dml_display_cfg(dml2, context->streams[i], dml_dispcfg);
                stream_mall_type = dc_state_get_stream_subvp_type(context, context->streams[i]);
 
@@ -1080,7 +1090,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
                ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);
 
                populate_dml_timing_cfg_from_stream_state(&dml_dispcfg->timing, disp_cfg_stream_location, context->streams[i]);
-               populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_stream_location, context->streams[i], &context->res_ctx.pipe_ctx[i]);
+               populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_stream_location, context->streams[i], current_pipe_context);
                switch (context->streams[i]->debug.force_odm_combine_segments) {
                case 2:
                        dml2->v20.dml_core_ctx.policy.ODMUse[disp_cfg_stream_location] = dml_odm_use_policy_combine_2to1;
@@ -1137,7 +1147,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
 
                                if (j >= 1) {
                                        populate_dml_timing_cfg_from_stream_state(&dml_dispcfg->timing, disp_cfg_plane_location, context->streams[i]);
-                                       populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_plane_location, context->streams[i], &context->res_ctx.pipe_ctx[i]);
+                                       populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_plane_location, context->streams[i], current_pipe_context);
                                        switch (context->streams[i]->debug.force_odm_combine_segments) {
                                        case 2:
                                                dml2->v20.dml_core_ctx.policy.ODMUse[disp_cfg_plane_location] = dml_odm_use_policy_combine_2to1;
index 8c0794af5adee8c3bc3e5ffa4ebcbece5a843ee7..1068b962d1c12bf5145a7c64ae7ddfa991d0b198 100644 (file)
@@ -155,12 +155,12 @@ unsigned int dml2_util_get_maximum_odm_combine_for_output(bool force_odm_4to1, e
 
 bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx)
 {
+       if (pipe_ctx == NULL || pipe_ctx->stream == NULL)
+               return false;
+
        /* If this assert is hit then we have a link encoder dynamic management issue */
        ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true);
 
-       if (pipe_ctx->stream == NULL)
-               return false;
-
        /* Count MST hubs once by treating only 1st remote sink in topology as an encoder */
        if (pipe_ctx->stream->link && pipe_ctx->stream->link->remote_sinks[0]) {
                return (pipe_ctx->stream_res.hpo_dp_stream_enc &&