From b3a26e04b16a28610b08eb914b7e1b8980a28760 Mon Sep 17 00:00:00 2001 From: Michael Strauss Date: Fri, 26 Jul 2019 12:04:12 -0400 Subject: [PATCH 3442/4256] drm/amd/display: Enable MPO with pre-blend color processing (RGB) [Why] DCN10 performs color processing before MPC combination, causes color shift in RGB colorspaces when positive brightness offset is applied However, YCbCr is still unfixed and remains disabled [How] Add layerIndex to dc_plane_state and dc_plane_info structs Re-enable MPO when brightness is adjusted and colorspace is not YCbCr Set rear plane's brightness offset to 0 when front plane visible Signed-off-by: Michael Strauss Reviewed-by: Anthony Koo Acked-by: Leo Li Acked-by: Nicholas Kazlauskas --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++ drivers/gpu/drm/amd/display/dc/core/dc.c | 2 + drivers/gpu/drm/amd/display/dc/dc.h | 2 + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 51 ++++++++++++++++++- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index a1ee74584913..474eb6849dc7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3089,6 +3089,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, plane_info->visible = true; plane_info->stereo_format = PLANE_STEREO_FORMAT_NONE; + plane_info->layer_index = 0; + ret = fill_plane_color_attributes(plane_state, plane_info->format, &plane_info->color_space); if (ret) @@ -3154,6 +3156,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, dc_plane_state->global_alpha = plane_info.global_alpha; dc_plane_state->global_alpha_value = plane_info.global_alpha_value; dc_plane_state->dcc = plane_info.dcc; + dc_plane_state->layer_index = plane_info.layer_index; // Always returns 0 /* * Always set input transfer function, since plane state is refreshed diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 90c860d8e449..541c94fba481 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1701,6 +1701,8 @@ static void copy_surface_update_to_plane( srf_update->plane_info->dcc; surface->sdr_white_level = srf_update->plane_info->sdr_white_level; + surface->layer_index = + srf_update->plane_info->layer_index; } if (srf_update->gamma && diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 4ce260aea985..85863dcf8456 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -764,6 +764,7 @@ struct dc_plane_state { bool visible; bool flip_immediate; bool horizontal_mirror; + int layer_index; union surface_update_flags update_flags; /* private to DC core */ @@ -793,6 +794,7 @@ struct dc_plane_info { bool global_alpha; int global_alpha_value; bool input_csc_enabled; + int layer_index; }; struct dc_scaling_info { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 2846017a544d..1835157b9fad 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1903,6 +1903,36 @@ static void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx) pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust); } + +static bool dcn10_is_rear_mpo_fix_required(struct pipe_ctx *pipe_ctx, enum dc_color_space colorspace) +{ + if (pipe_ctx->plane_state && pipe_ctx->plane_state->layer_index > 0 && is_rgb_cspace(colorspace)) { + if (pipe_ctx->top_pipe) { + struct pipe_ctx *top = pipe_ctx->top_pipe; + + while (top->top_pipe) + top = top->top_pipe; // Traverse to top pipe_ctx + if (top->plane_state && top->plane_state->layer_index == 0) + return true; // Front MPO plane not hidden + } + } + return false; +} + +static void dcn10_set_csc_adjustment_rgb_mpo_fix(struct pipe_ctx *pipe_ctx, uint16_t *matrix) +{ + // Override rear plane RGB bias to fix MPO brightness + uint16_t rgb_bias = matrix[3]; + + matrix[3] = 0; + matrix[7] = 0; + matrix[11] = 0; + pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix); + matrix[3] = rgb_bias; + matrix[7] = rgb_bias; + matrix[11] = rgb_bias; +} + static void dcn10_program_output_csc(struct dc *dc, struct pipe_ctx *pipe_ctx, enum dc_color_space colorspace, @@ -1910,8 +1940,25 @@ static void dcn10_program_output_csc(struct dc *dc, int opp_id) { if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { - if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) - pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix); + if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) { + + /* MPO is broken with RGB colorspaces when OCSC matrix + * brightness offset >= 0 on DCN1 due to OCSC before MPC + * Blending adds offsets from front + rear to rear plane + * + * Fix is to set RGB bias to 0 on rear plane, top plane + * black value pixels add offset instead of rear + front + */ + + int16_t rgb_bias = matrix[3]; + // matrix[3/7/11] are all the same offset value + + if (rgb_bias > 0 && dcn10_is_rear_mpo_fix_required(pipe_ctx, colorspace)) { + dcn10_set_csc_adjustment_rgb_mpo_fix(pipe_ctx, matrix); + } else { + pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix); + } + } } else { if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL) pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace); -- 2.17.1