aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0070-drm-amd-display-Refactor-output-transfer-function-to.patch
blob: 65e44b580518bfb5f4dfdb95a561730c653982df (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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
From 3c028814f813567158147857a73875adc4c0e711 Mon Sep 17 00:00:00 2001
From: Anthony Koo <Anthony.Koo@amd.com>
Date: Thu, 15 Dec 2016 12:09:46 -0500
Subject: [PATCH 0070/4131] drm/amd/display: Refactor output transfer function
 to stream

Refactor part 3 - Moving output transfer function from surface to stream

Split HWSS to program degamma and regamma separately.
Degamma should be dependent on input transfer function.
And Regamma should depend on the desired output transfer function.

Signed-off-by: Anthony Koo <anthony.koo@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c    | 11 ++++
 drivers/gpu/drm/amd/display/dc/core/dc.c           | 23 +++++---
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c    |  3 +
 drivers/gpu/drm/amd/display/dc/core/dc_surface.c   |  3 -
 drivers/gpu/drm/amd/display/dc/dc.h                |  7 ++-
 .../amd/display/dc/dce110/dce110_hw_sequencer.c    | 65 ++++++++++++++++++----
 drivers/gpu/drm/amd/display/dc/inc/core_types.h    |  3 +
 drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h  |  7 ++-
 8 files changed, 95 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
index 0311090..6aede70 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
@@ -512,6 +512,7 @@ static void fill_gamma_from_crtc(
 {
 	int i;
 	struct dc_gamma *gamma;
+	struct dc_transfer_func *input_tf;
 	uint16_t *red, *green, *blue;
 	int end = (crtc->gamma_size > NUM_OF_RAW_GAMMA_RAMP_RGB_256) ?
 			NUM_OF_RAW_GAMMA_RAMP_RGB_256 : crtc->gamma_size;
@@ -539,6 +540,16 @@ static void fill_gamma_from_crtc(
 	gamma->size = sizeof(gamma->gamma_ramp_rgb256x3x16);
 
 	dc_surface->gamma_correction = gamma;
+
+	input_tf = dc_create_transfer_func(adev->dm.dc);
+
+	if (input_tf == NULL)
+		return;
+
+	input_tf->type = TF_TYPE_PREDEFINED;
+	input_tf->tf = TRANSFER_FUNCTION_SRGB;
+
+	dc_surface->in_transfer_func = input_tf;
 }
 
 static void fill_plane_attributes(
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index f20701a..df1bae8 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1394,6 +1394,7 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda
 
 		for (j = 0; j < context->res_ctx.pool->pipe_count; j++) {
 			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
+			struct core_stream *stream = pipe_ctx->stream;
 
 			if (pipe_ctx->surface != surface)
 				continue;
@@ -1472,15 +1473,14 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda
 
 			if (updates[i].out_transfer_func &&
 					updates[i].out_transfer_func !=
-					surface->public.out_transfer_func) {
-				if (surface->public.out_transfer_func != NULL)
+					stream->public.out_transfer_func) {
+				if (stream->public.out_transfer_func != NULL)
 					dc_transfer_func_release(
-							surface->public.
+							stream->public.
 							out_transfer_func);
-
 				dc_transfer_func_retain(
 						updates[i].out_transfer_func);
-				surface->public.out_transfer_func =
+				stream->public.out_transfer_func =
 						updates[i].out_transfer_func;
 			}
 		}
@@ -1517,11 +1517,18 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda
 			}
 
 			if (is_new_pipe_surface[j] ||
+					updates[i].in_transfer_func)
+				core_dc->hwss.set_input_transfer_func(
+						pipe_ctx, pipe_ctx->surface);
+
+			if (is_new_pipe_surface[j] ||
 					updates[i].gamma ||
-					updates[i].in_transfer_func ||
 					updates[i].out_transfer_func)
-				core_dc->hwss.set_gamma_correction(
-						pipe_ctx, pipe_ctx->surface);
+				core_dc->hwss.set_output_transfer_func(
+						pipe_ctx,
+						pipe_ctx->surface,
+						pipe_ctx->stream);
+
 		}
 		if (apply_ctx) {
 			core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 8d6aa60..237436e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -89,6 +89,9 @@ static bool construct(struct core_stream *stream,
 static void destruct(struct core_stream *stream)
 {
 	dc_sink_release(&stream->sink->public);
+	if (stream->public.out_transfer_func != NULL)
+		dc_transfer_func_release(
+				stream->public.out_transfer_func);
 }
 
 void dc_stream_retain(const struct dc_stream *dc_stream)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index 26f2f76..1ca40a2 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -76,9 +76,6 @@ static void destruct(struct surface *surface)
 	if (surface->protected.public.in_transfer_func != NULL)
 		dc_transfer_func_release(
 				surface->protected.public.in_transfer_func);
-	if (surface->protected.public.out_transfer_func != NULL)
-		dc_transfer_func_release(
-				surface->protected.public.out_transfer_func);
 }
 
 /*******************************************************************************
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index c7905b3..3f30afc 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -254,6 +254,7 @@ struct dc_transfer_func_distributed_points {
 enum dc_transfer_func_predefined {
 	TRANSFER_FUNCTION_SRGB,
 	TRANSFER_FUNCTION_BT709,
+	TRANSFER_FUNCTION_PQ,
 	TRANSFER_FUNCTION_LINEAR,
 };
 
@@ -287,7 +288,6 @@ struct dc_surface {
 	const struct dc_gamma *gamma_correction;
 
 	const struct dc_transfer_func *in_transfer_func;
-	const struct dc_transfer_func *out_transfer_func;
 };
 
 struct dc_plane_info {
@@ -527,10 +527,11 @@ struct dc_stream {
 
 	struct freesync_context freesync_ctx;
 
-	/* TODO: dithering */
-	/* TODO: transfer function (CSC/regamma/gamut remap) */
+	const struct dc_transfer_func *out_transfer_func;
 	struct colorspace_transform gamut_remap_matrix;
 	struct csc_transform csc_color_matrix;
+
+	/* TODO: dithering */
 	/* TODO: custom INFO packets */
 	/* TODO: ABM info (DMCU) */
 	/* TODO: PSR info */
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index f6984e9..72017d5 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -231,11 +231,61 @@ static void build_prescale_params(struct ipp_prescale_params *prescale_params,
 	}
 }
 
-static bool dce110_set_gamma_correction(
+static bool dce110_set_degamma(
 	struct pipe_ctx *pipe_ctx,
 	const struct core_surface *surface)
 {
 	struct input_pixel_processor *ipp = pipe_ctx->ipp;
+	const struct core_transfer_func *tf = NULL;
+	struct ipp_prescale_params prescale_params = { 0 };
+	bool result = true;
+
+	if (ipp == NULL)
+		return false;
+
+	if (surface->public.in_transfer_func)
+		tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func);
+
+	build_prescale_params(&prescale_params, surface);
+	ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
+
+	if (tf == NULL) {
+		/* Default case if no input transfer function specified */
+		ipp->funcs->ipp_set_degamma(ipp,
+				IPP_DEGAMMA_MODE_BYPASS);
+	} else if (tf->public.type == TF_TYPE_PREDEFINED) {
+		switch (tf->public.tf) {
+		case TRANSFER_FUNCTION_SRGB:
+			ipp->funcs->ipp_set_degamma(ipp,
+					IPP_DEGAMMA_MODE_HW_sRGB);
+			break;
+		case TRANSFER_FUNCTION_BT709:
+			ipp->funcs->ipp_set_degamma(ipp,
+					IPP_DEGAMMA_MODE_HW_xvYCC);
+			break;
+		case TRANSFER_FUNCTION_LINEAR:
+			ipp->funcs->ipp_set_degamma(ipp,
+					IPP_DEGAMMA_MODE_BYPASS);
+			break;
+		case TRANSFER_FUNCTION_PQ:
+			result = false;
+			break;
+		default:
+			result = false;
+		}
+	} else {
+		/*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/
+		result = false;
+	}
+
+	return result;
+}
+
+static bool dce110_set_output_transfer_func(
+	struct pipe_ctx *pipe_ctx,
+	const struct core_surface *surface, /* Surface - To be removed */
+	const struct core_stream *stream)
+{
 	struct output_pixel_processor *opp = pipe_ctx->opp;
 	const struct core_gamma *ramp = NULL;
 	struct ipp_prescale_params prescale_params = { 0 };
@@ -253,20 +303,10 @@ static bool dce110_set_gamma_correction(
 
 	opp->funcs->opp_power_on_regamma_lut(opp, true);
 
-	if (ipp) {
-		build_prescale_params(&prescale_params, surface);
-		ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
-	}
-
 	if (ramp && calculate_regamma_params(regamma_params, ramp, surface)) {
-
 		opp->funcs->opp_program_regamma_pwl(opp, regamma_params);
-		if (ipp)
-			ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB);
 		opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER);
 	} else {
-		if (ipp)
-			ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
 		opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_BYPASS);
 	}
 
@@ -1904,7 +1944,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
 	.set_plane_config = set_plane_config,
 	.update_plane_addr = update_plane_addr,
 	.update_pending_status = dce110_update_pending_status,
-	.set_gamma_correction = dce110_set_gamma_correction,
+	.set_input_transfer_func = dce110_set_degamma,
+	.set_output_transfer_func = dce110_set_output_transfer_func,
 	.power_down = dce110_power_down,
 	.enable_accelerated_mode = dce110_enable_accelerated_mode,
 	.enable_timing_synchronization = dce110_enable_timing_synchronization,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index a67d675..c2d35c2 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -55,6 +55,9 @@ struct core_target {
 #define DC_GAMMA_TO_CORE(dc_gamma) \
 	container_of(dc_gamma, struct core_gamma, public)
 
+#define DC_TRANSFER_FUNC_TO_CORE(dc_transfer_func) \
+	container_of(dc_transfer_func, struct core_transfer_func, public)
+
 struct core_surface {
 	struct dc_surface public;
 	struct dc_surface_status status;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index 89a0834..0e803ca 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -77,10 +77,15 @@ struct hw_sequencer_funcs {
 	void (*update_pending_status)(
 			struct pipe_ctx *pipe_ctx);
 
-	bool (*set_gamma_correction)(
+	bool (*set_input_transfer_func)(
 				struct pipe_ctx *pipe_ctx,
 				const struct core_surface *surface);
 
+	bool (*set_output_transfer_func)(
+				struct pipe_ctx *pipe_ctx,
+				const struct core_surface *surface,
+				const struct core_stream *stream);
+
 	void (*power_down)(struct core_dc *dc);
 
 	void (*enable_accelerated_mode)(struct core_dc *dc);
-- 
2.7.4