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
