aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3442-drm-amd-display-Enable-MPO-with-pre-blend-color-proc.patch
blob: 496b6adc02c2f661c37aaa3095ef89b039f81c88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
From b3a26e04b16a28610b08eb914b7e1b8980a28760 Mon Sep 17 00:00:00 2001
From: Michael Strauss <michael.strauss@amd.com>
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 <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>
---
 .../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