aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/2507-drm-amd-display-Acquire-DSC-HW-resource-only-if-requ.patch
blob: 04e36856d8d73bed9c8f4a206165bd638f42baed (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
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
From 213ec3d169fc76eb4bc5804e43a4d3dd642a7cdf Mon Sep 17 00:00:00 2001
From: Nikola Cornij <nikola.cornij@amd.com>
Date: Tue, 2 Apr 2019 12:40:22 -0400
Subject: [PATCH 2507/2940] drm/amd/display: Acquire DSC HW resource only if
 required by stream

[why]
There are ASICs that have fewer DSC engines than pipes, which makes
DSC a resource that should be used only if required.

[how]
Acquire DSC HW resource if required by stream and release when not
required anymore.

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Acked-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  19 +--
 .../drm/amd/display/dc/dcn20/dcn20_resource.c | 139 ++++++++++--------
 .../drm/amd/display/dc/dcn20/dcn20_resource.h |   2 +
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  10 ++
 4 files changed, 97 insertions(+), 73 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 5b26c76b906b..bcf736416ee3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1748,19 +1748,14 @@ static void commit_planes_do_stream_update(struct dc *dc,
 
 #if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT)
 			if (stream_update->dsc_config && dc->hwss.pipe_control_lock_global) {
-				if (stream_update->dsc_config->num_slices_h &&
-						stream_update->dsc_config->num_slices_v) {
-					/* dsc enable */
-					dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true);
-					dp_set_dsc_enable(pipe_ctx, true);
-					dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false);
-				} else {
-					/* dsc disable */
-					dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true);
-					dp_set_dsc_enable(pipe_ctx, false);
-					dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false);
-				}
+				bool enable_dsc = (stream_update->dsc_config->num_slices_h && stream_update->dsc_config->num_slices_v);
+
+				dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true);
+				dp_set_dsc_enable(pipe_ctx, enable_dsc);
+				dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false);
 
+				if (!stream->is_dsc_enabled)
+					dc->res_pool->funcs->remove_dsc_from_stream_resource(dc, context, stream);
 			}
 #endif
 			/* Full fe update*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index d2642cc52c85..2d6f9c4de893 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -1230,94 +1230,79 @@ enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state
 
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 
-static struct display_stream_compressor *acquire_dsc(struct resource_context *res_ctx,
-						const struct resource_pool *pool)
+static void acquire_dsc(struct resource_context *res_ctx,
+			const struct resource_pool *pool,
+			struct display_stream_compressor **dsc)
 {
 	int i;
-	struct display_stream_compressor *dsc = NULL;
+
+	ASSERT(*dsc == NULL);
+	*dsc = NULL;
 
 	/* Find first free DSC */
 	for (i = 0; i < pool->res_cap->num_dsc; i++)
 		if (!res_ctx->is_dsc_acquired[i]) {
-			dsc = pool->dscs[i];
+			*dsc = pool->dscs[i];
 			res_ctx->is_dsc_acquired[i] = true;
 			break;
 		}
-
-	return dsc;
 }
 
 static void release_dsc(struct resource_context *res_ctx,
 			const struct resource_pool *pool,
-			const struct display_stream_compressor *dsc)
+			struct display_stream_compressor **dsc)
 {
 	int i;
 
 	for (i = 0; i < pool->res_cap->num_dsc; i++)
-		if (pool->dscs[i] == dsc) {
+		if (pool->dscs[i] == *dsc) {
 			res_ctx->is_dsc_acquired[i] = false;
+			*dsc = NULL;
 			break;
 		}
 }
 
 #endif
 
-enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
-{
-	enum dc_status result = DC_ERROR_UNEXPECTED;
-
-	result = resource_map_pool_resources(dc, new_ctx, dc_stream);
-
-	if (result == DC_OK)
-		result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
 
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-	/* Get a DSC if required and available */
-	if (result == DC_OK) {
-		int i;
-		const struct resource_pool *pool = dc->res_pool;
-		bool is_add_dsc = true;
+enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc,
+		struct dc_state *dc_ctx,
+		struct dc_stream_state *dc_stream)
+{
+	enum dc_status result = DC_OK;
+	int i;
+	const struct resource_pool *pool = dc->res_pool;
 
-		for (i = 0; i < dc->res_pool->pipe_count; i++) {
-			struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i];
+	/* Get a DSC if required and available */
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		struct pipe_ctx *pipe_ctx = &dc_ctx->res_ctx.pipe_ctx[i];
 
-			if (pipe_ctx->stream != dc_stream)
-				continue;
+		if (pipe_ctx->stream != dc_stream)
+			continue;
 
-			if (IS_DIAG_DC(dc->ctx->dce_environment) ||
-				dc->res_pool->res_cap->num_dsc == 1) {
-				// Diags build can also run on platforms that have fewer DSCs than pipes.
-				// In that case, add DSC only if needed by timing.
-				is_add_dsc = (dc_stream->timing.flags.DSC == 1);
-			}
-			if (is_add_dsc) {
-				pipe_ctx->stream_res.dsc = acquire_dsc(&new_ctx->res_ctx, pool);
-
-				/* The number of DSCs can be less than the number of pipes */
-				if (!pipe_ctx->stream_res.dsc) {
-					dm_output_to_console("No DSCs available\n");
-					result = DC_NO_DSC_RESOURCE;
-				}
-			}
+		acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc);
 
-			break;
+		/* The number of DSCs can be less than the number of pipes */
+		if (!pipe_ctx->stream_res.dsc) {
+			dm_output_to_console("No DSCs available\n");
+			result = DC_NO_DSC_RESOURCE;
 		}
-	}
-#endif
 
-	if (result == DC_OK)
-		result = dcn20_build_mapped_resource(dc, new_ctx, dc_stream);
+		break;
+	}
 
 	return result;
 }
 
 
-enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
+enum dc_status dcn20_remove_dsc_from_stream_resource(struct dc *dc,
+		struct dc_state *new_ctx,
+		struct dc_stream_state *dc_stream)
 {
 	struct pipe_ctx *pipe_ctx = NULL;
 	int i;
 
-	/* Remove DSC */
 	for (i = 0; i < MAX_PIPES; i++) {
 		if (new_ctx->res_ctx.pipe_ctx[i].stream == dc_stream && !new_ctx->res_ctx.pipe_ctx[i].top_pipe) {
 			pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i];
@@ -1328,21 +1313,51 @@ enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_
 	if (!pipe_ctx)
 		return DC_ERROR_UNEXPECTED;
 
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 	if (pipe_ctx->stream_res.dsc) {
 		struct pipe_ctx *odm_pipe = dc_res_get_odm_bottom_pipe(pipe_ctx);
 
-		release_dsc(&new_ctx->res_ctx, dc->res_pool, pipe_ctx->stream_res.dsc);
-		pipe_ctx->stream_res.dsc = NULL;
-		if (odm_pipe) {
-			release_dsc(&new_ctx->res_ctx, dc->res_pool, odm_pipe->stream_res.dsc);
-			odm_pipe->stream_res.dsc = NULL;
-		}
+		release_dsc(&new_ctx->res_ctx, dc->res_pool, &pipe_ctx->stream_res.dsc);
+		if (odm_pipe)
+			release_dsc(&new_ctx->res_ctx, dc->res_pool, &odm_pipe->stream_res.dsc);
 	}
-#endif
 
 	return DC_OK;
 }
+#endif
+
+
+enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
+{
+	enum dc_status result = DC_ERROR_UNEXPECTED;
+
+	result = resource_map_pool_resources(dc, new_ctx, dc_stream);
+
+	if (result == DC_OK)
+		result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
+
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	/* Get a DSC if required and available */
+	if (result == DC_OK && dc_stream->timing.flags.DSC)
+		result = dcn20_add_dsc_to_stream_resource(dc, new_ctx, dc_stream);
+#endif
+
+	if (result == DC_OK)
+		result = dcn20_build_mapped_resource(dc, new_ctx, dc_stream);
+
+	return result;
+}
+
+
+enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
+{
+	enum dc_status result = DC_OK;
+
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	result = dcn20_remove_dsc_from_stream_resource(dc, new_ctx, dc_stream);
+#endif
+
+	return result;
+}
 
 
 static void swizzle_to_dml_params(
@@ -1439,8 +1454,6 @@ static bool dcn20_split_stream_for_combine(
 	secondary_pipe->top_pipe = primary_pipe;
 
 	if (is_odm_combine) {
-		bool is_add_dsc = true;
-
 		if (primary_pipe->plane_state) {
 			/* HACTIVE halved for odm combine */
 			sd->h_active /= 2;
@@ -1477,8 +1490,8 @@ static bool dcn20_split_stream_for_combine(
 		}
 		secondary_pipe->stream_res.opp = pool->opps[secondary_pipe->pipe_idx];
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-		if (is_add_dsc) {
-			secondary_pipe->stream_res.dsc = acquire_dsc(res_ctx, pool);
+		if (secondary_pipe->stream->timing.flags.DSC == 1) {
+			acquire_dsc(res_ctx, pool, &secondary_pipe->stream_res.dsc);
 			ASSERT(secondary_pipe->stream_res.dsc);
 			if (secondary_pipe->stream_res.dsc == NULL)
 				return false;
@@ -1952,7 +1965,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
 		hsplit_pipe->bottom_pipe = NULL;
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 		if (hsplit_pipe->stream_res.dsc && hsplit_pipe->stream_res.dsc != pipe->stream_res.dsc)
-			release_dsc(&context->res_ctx, dc->res_pool, hsplit_pipe->stream_res.dsc);
+			release_dsc(&context->res_ctx, dc->res_pool, &hsplit_pipe->stream_res.dsc);
 #endif
 		/* Clear plane_res and stream_res */
 		memset(&hsplit_pipe->plane_res, 0, sizeof(hsplit_pipe->plane_res));
@@ -2364,7 +2377,11 @@ static struct resource_funcs dcn20_res_pool_funcs = {
 	.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
 	.populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
 	.get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
-	.set_mcif_arb_params = dcn20_set_mcif_arb_params
+	.set_mcif_arb_params = dcn20_set_mcif_arb_params,
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	.add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
+	.remove_dsc_from_stream_resource = dcn20_remove_dsc_from_stream_resource
+#endif
 };
 
 struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
index b5a75289f444..018224518011 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
@@ -121,6 +121,8 @@ enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state
 enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream);
 enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream);
 enum dc_status dcn20_get_default_swizzle_mode(struct dc_plane_state *plane_state);
+enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc, struct dc_state *dc_ctx, struct dc_stream_state *dc_stream);
+enum dc_status dcn20_remove_dsc_from_stream_resource(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream);
 
 void dcn20_patch_bounding_box(
 		struct dc *dc,
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 e94f3c180144..61c04bd39ac6 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -142,6 +142,16 @@ struct resource_funcs {
 			display_e2e_pipe_params_st *pipes,
 			int pipe_cnt);
 #endif
+
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+enum dc_status (*add_dsc_to_stream_resource)(struct dc *dc,
+			struct dc_state *dc_ctx,
+			struct dc_stream_state *dc_stream);
+
+enum dc_status (*remove_dsc_from_stream_resource)(struct dc *dc,
+			struct dc_state *new_ctx,
+			struct dc_stream_state *dc_stream);
+#endif
 };
 
 struct audio_support{
-- 
2.17.1