aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0256-drm-amd-display-Adding-FastUpdate-functionality.patch
blob: c900ce994fbf4b07cf6bd2a34393a605bb957d9a (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
From 4b3665f8dab4688fde9102041c2d66ff776b183b Mon Sep 17 00:00:00 2001
From: Leon Elazar <leon.elazar@amd.com>
Date: Wed, 1 Mar 2017 12:30:11 -0500
Subject: [PATCH 0256/4131] drm/amd/display: Adding FastUpdate functionality

Exposing DC Api dc_check_update_surfaces_for_stream
validation will return the answer which type of update is required,
so upper layers can is it safe to call the update API fro high IRQ yes/no.

Signed-off-by: Leon Elazar <leon.elazar@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 149 ++++++++++++++++++++++++++-----
 drivers/gpu/drm/amd/display/dc/dc.h      |  12 +++
 2 files changed, 140 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index c34232c..27e31bd 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1110,42 +1110,149 @@ static bool is_surface_in_context(
 	return false;
 }
 
-enum surface_update_type {
-	UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */
-	UPDATE_TYPE_MED,  /* a lot of programming needed.  may need to alloc */
-	UPDATE_TYPE_FULL, /* may need to shuffle resources */
-};
+static unsigned int pixel_format_to_bpp(enum surface_pixel_format format)
+{
+	switch (format) {
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
+	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
+		return 16;
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
+	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
+	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
+		return 32;
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
+	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
+		return 64;
+	default:
+		ASSERT_CRITICAL(false);
+		return -1;
+	}
+}
+
+static enum surface_update_type get_plane_info_update_type(
+		const struct dc_surface_update *u)
+{
+	struct dc_plane_info temp_plane_info = { { { { 0 } } } };
+
+	if (!u->plane_info)
+		return UPDATE_TYPE_FAST;
+
+	/* Copy all parameters that will cause a full update
+	 * from current surface, the rest of the parameters
+	 * from provided plane configuration.
+	 * Perform memory compare and special validation
+	 * for those that can cause fast/medium updates
+	 */
+
+	/* Full update parameters */
+	temp_plane_info.color_space = u->surface->color_space;
+	temp_plane_info.dcc = u->surface->dcc;
+	temp_plane_info.horizontal_mirror = u->surface->horizontal_mirror;
+	temp_plane_info.plane_size = u->surface->plane_size;
+	temp_plane_info.rotation = u->surface->rotation;
+	temp_plane_info.stereo_format = u->surface->stereo_format;
+	temp_plane_info.tiling_info = u->surface->tiling_info;
+	temp_plane_info.visible = u->surface->visible;
+
+	/* Special Validation parameters */
+	temp_plane_info.format = u->plane_info->format;
+
+	if (memcmp(u->plane_info, &temp_plane_info,
+			sizeof(struct dc_plane_info)) != 0)
+		return UPDATE_TYPE_FULL;
+
+	if (pixel_format_to_bpp(u->plane_info->format) !=
+			pixel_format_to_bpp(u->surface->format)) {
+		return UPDATE_TYPE_FULL;
+	} else {
+		return UPDATE_TYPE_MED;
+	}
+}
+
+static enum surface_update_type  get_scaling_info_update_type(
+		const struct dc_surface_update *u)
+{
+	struct dc_scaling_info temp_scaling_info = { { 0 } };
+
+	if (!u->scaling_info)
+		return UPDATE_TYPE_FAST;
+
+	/* Copy all parameters that will cause a full update
+	 * from current surface, the rest of the parameters
+	 * from provided plane configuration.
+	 * Perform memory compare and special validation
+	 * for those that can cause fast/medium updates
+	 */
+
+	/* Full Update Parameters */
+	temp_scaling_info.dst_rect = u->surface->dst_rect;
+	temp_scaling_info.src_rect = u->surface->src_rect;
+	temp_scaling_info.scaling_quality = u->surface->scaling_quality;
+
+	/* Special validation required */
+	temp_scaling_info.clip_rect = u->scaling_info->clip_rect;
+
+	if (memcmp(u->scaling_info, &temp_scaling_info,
+			sizeof(struct dc_scaling_info)) != 0)
+		return UPDATE_TYPE_FULL;
+
+	/* Check Clip rectangles if not equal
+	 * difference is in offsets == > UPDATE_TYPE_FAST
+	 * difference is in dimensions == > UPDATE_TYPE_FULL
+	 */
+	if (memcmp(&u->scaling_info->clip_rect,
+			&u->surface->clip_rect, sizeof(struct rect)) != 0) {
+		if ((u->scaling_info->clip_rect.height ==
+			u->surface->clip_rect.height) &&
+			(u->scaling_info->clip_rect.width ==
+			u->surface->clip_rect.width)) {
+			return UPDATE_TYPE_FAST;
+		} else {
+			return UPDATE_TYPE_FULL;
+		}
+	}
+
+	return UPDATE_TYPE_FAST;
+}
 
 static enum surface_update_type det_surface_update(
 		const struct core_dc *dc,
 		const struct dc_surface_update *u)
 {
 	const struct validate_context *context = dc->current_context;
-
-	if (u->scaling_info || u->plane_info)
-		/* todo: not all scale and plane_info update need full update
-		 * ie. check if following is the same
-		 * scale ratio, view port, surface bpp etc
-		 */
-		return UPDATE_TYPE_FULL; /* may need bandwidth update */
+	enum surface_update_type type = UPDATE_TYPE_FAST;
+	enum surface_update_type overall_type = UPDATE_TYPE_FAST;
 
 	if (!is_surface_in_context(context, u->surface))
 		return UPDATE_TYPE_FULL;
 
+	type = get_plane_info_update_type(u);
+	if (overall_type < type)
+		overall_type = type;
+
+	type = get_scaling_info_update_type(u);
+	if (overall_type < type)
+		overall_type = type;
+
 	if (u->in_transfer_func ||
 		u->out_transfer_func ||
-		u->hdr_static_metadata)
-		return UPDATE_TYPE_MED;
+		u->hdr_static_metadata) {
+		if (overall_type < UPDATE_TYPE_MED)
+			overall_type = UPDATE_TYPE_MED;
+	}
 
-	return UPDATE_TYPE_FAST;
+	return overall_type;
 }
 
-static enum surface_update_type check_update_surfaces_for_stream(
-		struct core_dc *dc,
+enum surface_update_type dc_check_update_surfaces_for_stream(
+		struct dc *dc,
 		struct dc_surface_update *updates,
 		int surface_count,
 		const struct dc_stream_status *stream_status)
 {
+	struct core_dc *core_dc = DC_TO_CORE(dc);
 	int i;
 	enum surface_update_type overall_type = UPDATE_TYPE_FAST;
 
@@ -1154,7 +1261,7 @@ static enum surface_update_type check_update_surfaces_for_stream(
 
 	for (i = 0 ; i < surface_count; i++) {
 		enum surface_update_type type =
-				det_surface_update(dc, &updates[i]);
+				det_surface_update(core_dc, &updates[i]);
 
 		if (type == UPDATE_TYPE_FULL)
 			return type;
@@ -1184,8 +1291,8 @@ void dc_update_surfaces_for_stream(struct dc *dc,
 	if (!stream_status)
 		return; /* Cannot commit surface to stream that is not committed */
 
-	update_type = check_update_surfaces_for_stream(
-			core_dc, updates, surface_count, stream_status);
+	update_type = dc_check_update_surfaces_for_stream(
+			dc, updates, surface_count, stream_status);
 
 	if (update_type >= update_surface_trace_level)
 		update_surface_trace(dc, updates, surface_count);
@@ -1321,7 +1428,7 @@ void dc_update_surfaces_for_stream(struct dc *dc,
 			if (pipe_ctx->surface != surface)
 				continue;
 
-			if (update_type == UPDATE_TYPE_FULL) {
+			if (update_type >= UPDATE_TYPE_MED) {
 				/* only apply for top pipe */
 				if (!pipe_ctx->top_pipe) {
 					core_dc->hwss.apply_ctx_for_surface(core_dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 2d84b18..69ae94b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -379,6 +379,12 @@ bool dc_post_update_surfaces_to_stream(
 void dc_update_surfaces_for_stream(struct dc *dc, struct dc_surface_update *updates,
 		int surface_count, const struct dc_stream *stream);
 
+enum surface_update_type {
+	UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */
+	UPDATE_TYPE_MED,  /* a lot of programming needed.  may need to alloc */
+	UPDATE_TYPE_FULL, /* may need to shuffle resources */
+};
+
 /*******************************************************************************
  * Stream Interfaces
  ******************************************************************************/
@@ -498,6 +504,12 @@ struct dc_stream_status {
 const struct dc_stream_status *dc_stream_get_status(
 	const struct dc_stream *dc_stream);
 
+enum surface_update_type dc_check_update_surfaces_for_stream(
+		struct dc *dc,
+		struct dc_surface_update *updates,
+		int surface_count,
+		const struct dc_stream_status *stream_status);
+
 /*******************************************************************************
  * Link Interfaces
  ******************************************************************************/
-- 
2.7.4