drm/amd/display: Enable MPO with pre-blend color processing (RGB)
authorMichael Strauss <michael.strauss@amd.com>
Fri, 26 Jul 2019 16:04:12 +0000 (12:04 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 15 Aug 2019 15:57:36 +0000 (10:57 -0500)
[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 <michael.strauss@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Acked-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c

index 722c70d40d3b911e8a5ccd837e37cd771a64d718..34b032360c5d0038fb2e26972bacde47480446ce 100644 (file)
@@ -3006,6 +3006,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)
@@ -3071,6 +3073,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
index e79ee114ab57e7f42a13fbc84fb04e87b797658d..4a2c7e9c56c0607a12a988ba741d5df3b57b392b 100644 (file)
@@ -1692,6 +1692,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 &&
index 87be02a8a958b60c8c383d453dbe45b26d010834..3ef269f824782c17e97c6d5d97d0351426933f70 100644 (file)
@@ -750,6 +750,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 */
@@ -779,6 +780,7 @@ struct dc_plane_info {
        bool global_alpha;
        int  global_alpha_value;
        bool input_csc_enabled;
+       int layer_index;
 };
 
 struct dc_scaling_info {
index 8ed25f21316df2c133d8d862efdbeaea41bbd784..2d50cfc66e9287a0cd1f76310596d4a8a9196b52 100644 (file)
@@ -1905,6 +1905,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,
@@ -1912,8 +1942,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);