From: Harry Wentland <[email protected]>

We were previously modifying the global dc->config.enable_4to1MPC
dynamically. These variables are meant as global configs, not to
by dynamically modified. Modifying them dynamically prevents us
from enabling/disabling functionality for debug purposes and can
easily lead to bad things since we're not operating on the current
state but on DC-wide variables.

Instead we should look at the existing split4mpc decision in
dcn20_validate_apply_split_flags and make the decision there,
if the global config.enable_4to1MPC is set to true for the
DCN version we're running.

This fixes corruption that is observed when running a new IGT
kms_colorop test for color-space-conversion that uses a
YUV plane and outputs to a writeback connector.

Assisted-by: Claude Sonnet 4.5.
Reviewed-by: Nicholas Kazlauskas <[email protected]>
Signed-off-by: Harry Wentland <[email protected]>
Signed-off-by: Chuanyu Tseng <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/dc.h              |  2 +-
 .../drm/amd/display/dc/dml/dcn314/dcn314_fpu.c   |  6 +-----
 .../gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c |  7 +------
 .../drm/amd/display/dc/dml/dcn351/dcn351_fpu.c   |  7 +------
 .../display/dc/resource/dcn20/dcn20_resource.c   | 16 ++++++++++++++--
 .../display/dc/resource/dcn31/dcn31_resource.c   | 10 +++++-----
 .../display/dc/resource/dcn314/dcn314_resource.c |  3 +++
 .../display/dc/resource/dcn315/dcn315_resource.c |  5 +++--
 .../display/dc/resource/dcn316/dcn316_resource.c |  6 ++++--
 .../display/dc/resource/dcn35/dcn35_resource.c   |  3 +++
 .../display/dc/resource/dcn351/dcn351_resource.c |  3 +++
 11 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 80e217c5a23d..41b5dedb6eff 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -521,7 +521,7 @@ struct dc_config {
        union allow_lttpr_non_transparent_mode allow_lttpr_non_transparent_mode;
        bool multi_mon_pp_mclk_switch;
        bool disable_dmcu;
-       bool enable_4to1MPC;
+       bool allow_4to1MPC;
        bool enable_windowed_mpo_odm;
        bool forceHBR2CP2520; // Used for switching between test patterns TPS4 
and CP2520
        uint32_t allow_edp_hotplug_detection;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
index df9d50b9b57c..ab016c294ba7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
@@ -391,13 +391,9 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc 
*dc, struct dc_state *c
        }
        context->bw_ctx.dml.ip.det_buffer_size_kbytes = 
DCN3_14_DEFAULT_DET_SIZE;
 
-       dc->config.enable_4to1MPC = false;
        if (pipe_cnt == 1 && pipe->plane_state
                && pipe->plane_state->rotation == ROTATION_ANGLE_0 && 
!dc->debug.disable_z9_mpc) {
-               if (is_dual_plane(pipe->plane_state->format)
-                               && pipe->plane_state->src_rect.width <= 1920 && 
pipe->plane_state->src_rect.height <= 1080) {
-                       dc->config.enable_4to1MPC = true;
-               } else if (!is_dual_plane(pipe->plane_state->format) && 
pipe->plane_state->src_rect.width <= 5120) {
+               if (!is_dual_plane(pipe->plane_state->format) && 
pipe->plane_state->src_rect.width <= 5120) {
                        /* Limit to 5k max to avoid forced pipe split when 
there is not enough detile for swath */
                        context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
                        pipes[0].pipe.src.unbounded_req_mode = true;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
index 8a177d5ae213..6713cd8ba86a 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
@@ -528,14 +528,9 @@ int dcn35_populate_dml_pipes_from_context_fpu(struct dc 
*dc,
        }
 
        context->bw_ctx.dml.ip.det_buffer_size_kbytes = 384;/*per guide*/
-       dc->config.enable_4to1MPC = false;
 
        if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
-               if (is_dual_plane(pipe->plane_state->format)
-                               && pipe->plane_state->src_rect.width <= 1920 &&
-                               pipe->plane_state->src_rect.height <= 1080) {
-                       dc->config.enable_4to1MPC = true;
-               } else if (!is_dual_plane(pipe->plane_state->format) &&
+               if (!is_dual_plane(pipe->plane_state->format) &&
                           pipe->plane_state->src_rect.width <= 5120) {
                        /*
                         * Limit to 5k max to avoid forced pipe split when there
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c
index 77023b619f1e..73c2aee57f28 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn351/dcn351_fpu.c
@@ -561,14 +561,9 @@ int dcn351_populate_dml_pipes_from_context_fpu(struct dc 
*dc,
        }
 
        context->bw_ctx.dml.ip.det_buffer_size_kbytes = 384;/*per guide*/
-       dc->config.enable_4to1MPC = false;
 
        if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
-               if (is_dual_plane(pipe->plane_state->format)
-                               && pipe->plane_state->src_rect.width <= 1920 &&
-                               pipe->plane_state->src_rect.height <= 1080) {
-                       dc->config.enable_4to1MPC = true;
-               } else if (!is_dual_plane(pipe->plane_state->format) &&
+               if (!is_dual_plane(pipe->plane_state->format) &&
                           pipe->plane_state->src_rect.width <= 5120) {
                        /*
                         * Limit to 5k max to avoid forced pipe split when there
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
index b28e877fb99d..7d49a6003f03 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
@@ -1814,6 +1814,11 @@ void dcn20_merge_pipes_for_validate(
        }
 }
 
+static bool is_dual_plane(enum surface_pixel_format format)
+{
+       return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == 
SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
+}
+
 int dcn20_validate_apply_pipe_split_flags(
                struct dc *dc,
                struct dc_state *context,
@@ -1898,8 +1903,15 @@ int dcn20_validate_apply_pipe_split_flags(
        for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
                struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
                int pipe_plane = v->pipe_plane[pipe_idx];
-               bool split4mpc = context->stream_count == 1 && plane_count == 1
-                               && dc->config.enable_4to1MPC && 
dc->res_pool->pipe_count >= 4;
+               bool split4mpc = false;
+
+               if (context->stream_count == 1 && plane_count == 1
+                   && dc->config.allow_4to1MPC && dc->res_pool->pipe_count >= 4
+                   && !dc->debug.disable_z9_mpc
+                   && pipe->plane_state && 
is_dual_plane(pipe->plane_state->format)
+                   && pipe->plane_state->src_rect.width <= 1920
+                   && pipe->plane_state->src_rect.height <= 1080)
+                               split4mpc = true;
 
                if (!context->res_ctx.pipe_ctx[i].stream)
                        continue;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
index 95c7ecdb3496..6d23d88e400c 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
@@ -1703,12 +1703,9 @@ int dcn31_populate_dml_pipes_from_context(
                pipe_cnt++;
        }
        context->bw_ctx.dml.ip.det_buffer_size_kbytes = DCN3_1_DEFAULT_DET_SIZE;
-       dc->config.enable_4to1MPC = false;
+
        if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
-               if (is_dual_plane(pipe->plane_state->format)
-                               && pipe->plane_state->src_rect.width <= 1920 && 
pipe->plane_state->src_rect.height <= 1080) {
-                       dc->config.enable_4to1MPC = true;
-               } else if (!is_dual_plane(pipe->plane_state->format) && 
pipe->plane_state->src_rect.width <= 5120) {
+               if (!is_dual_plane(pipe->plane_state->format) && 
pipe->plane_state->src_rect.width <= 5120) {
                        /* Limit to 5k max to avoid forced pipe split when 
there is not enough detile for swath */
                        context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
                        pipes[0].pipe.src.unbounded_req_mode = true;
@@ -1926,6 +1923,9 @@ static bool dcn31_resource_construct(
        dc->caps.is_apu = true;
        dc->caps.zstate_support = true;
 
+       /* Enable 4to1MPC by default */
+       dc->config.allow_4to1MPC = true;
+
        /* Color pipeline capabilities */
        dc->caps.color.dpp.dcn_arch = 1;
        dc->caps.color.dpp.input_lut_shared = 0;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
index 803b87986802..7b1f426652be 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
@@ -1834,6 +1834,9 @@ static bool dcn314_resource_construct(
        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
        pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
        pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
+
+       /* Enable 4to1MPC by default */
+       dc->config.allow_4to1MPC = true;
        dc->caps.max_downscale_ratio = 400;
        dc->caps.i2c_speed_in_khz = 100;
        dc->caps.i2c_speed_in_khz_hdcp = 100;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
index e488fa6f32e6..10feb64c0010 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
@@ -1789,11 +1789,9 @@ static int dcn315_populate_dml_pipes_from_context(
        if (context->bw_ctx.dml.ip.det_buffer_size_kbytes > 
DCN3_15_MAX_DET_SIZE)
                context->bw_ctx.dml.ip.det_buffer_size_kbytes = 
DCN3_15_MAX_DET_SIZE;
 
-       dc->config.enable_4to1MPC = false;
        if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
                if (is_dual_plane(pipe->plane_state->format)
                                && pipe->plane_state->src_rect.width <= 1920 && 
pipe->plane_state->src_rect.height <= 1080) {
-                       dc->config.enable_4to1MPC = true;
                        context->bw_ctx.dml.ip.det_buffer_size_kbytes =
                                        (max_usable_det / 
DCN3_15_CRB_SEGMENT_SIZE_KB / 4) * DCN3_15_CRB_SEGMENT_SIZE_KB;
                } else if (!is_dual_plane(pipe->plane_state->format)
@@ -1874,6 +1872,9 @@ static bool dcn315_resource_construct(
         *************************************************/
        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
        pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
+
+       /* Enable 4to1MPC by default */
+       dc->config.allow_4to1MPC = true;
        pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
        dc->caps.max_downscale_ratio = 600;
        dc->caps.i2c_speed_in_khz = 100;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
index fa51a9ae945f..835bedfd6074 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
@@ -1673,11 +1673,9 @@ static int dcn316_populate_dml_pipes_from_context(
        if (context->bw_ctx.dml.ip.det_buffer_size_kbytes > 
DCN3_16_MAX_DET_SIZE)
                context->bw_ctx.dml.ip.det_buffer_size_kbytes = 
DCN3_16_MAX_DET_SIZE;
        ASSERT(context->bw_ctx.dml.ip.det_buffer_size_kbytes >= 
DCN3_16_DEFAULT_DET_SIZE);
-       dc->config.enable_4to1MPC = false;
        if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
                if (is_dual_plane(pipe->plane_state->format)
                                && pipe->plane_state->src_rect.width <= 1920 && 
pipe->plane_state->src_rect.height <= 1080) {
-                       dc->config.enable_4to1MPC = true;
                        context->bw_ctx.dml.ip.det_buffer_size_kbytes =
                                        (max_usable_det / 
DCN3_16_CRB_SEGMENT_SIZE_KB / 4) * DCN3_16_CRB_SEGMENT_SIZE_KB;
                } else if (!is_dual_plane(pipe->plane_state->format)) {
@@ -1750,6 +1748,10 @@ static bool dcn316_resource_construct(
        pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
        pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
        pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
+
+       /* Enable 4to1MPC by default */
+       dc->config.allow_4to1MPC = true;
+
        dc->caps.max_downscale_ratio = 600;
        dc->caps.i2c_speed_in_khz = 100;
        dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.5 w/a applied by default*/
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
index f7e2e79bc0e1..154e00c32511 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
@@ -1830,6 +1830,9 @@ static bool dcn35_resource_construct(
        clk_src_regs_init(3, D),
        clk_src_regs_init(4, E);
 
+       /* Enable 4to1MPC by default */
+       dc->config.allow_4to1MPC = true;
+
 #undef REG_STRUCT
 #define REG_STRUCT abm_regs
        abm_regs_init(0),
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
index 5dffaf12a7c0..640650ed2184 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
@@ -1803,6 +1803,9 @@ static bool dcn351_resource_construct(
        clk_src_regs_init(3, D),
        clk_src_regs_init(4, E);
 
+       /* Enable 4to1MPC by default */
+       dc->config.allow_4to1MPC = true;
+
 #undef REG_STRUCT
 #define REG_STRUCT abm_regs
        abm_regs_init(0),
-- 
2.43.0

Reply via email to