[PATCH 48/49] drm/amd/display: Enable MPO with pre-blend color processing (RGB)
sunpeng.li at amd.com
sunpeng.li at amd.com
Fri Aug 9 21:37:41 UTC 2019
From: Michael Strauss <michael.strauss at amd.com>
[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 at amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo at amd.com>
Acked-by: Leo Li <sunpeng.li at amd.com>
Acked-by: Nicholas Kazlauskas <Nicholas.Kazlauskas at amd.com>
---
.../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 2f933f89aaef..911fe78b47c1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3077,6 +3077,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)
@@ -3142,6 +3144,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 7408df05d3e5..0b624db17e63 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1689,6 +1689,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 87be02a8a958..3ef269f82478 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -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 {
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 0045b698fb68..9fe2fff67dc5 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
@@ -1904,6 +1904,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,
@@ -1911,8 +1941,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.22.0
More information about the amd-gfx
mailing list