aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/2482-drm-amd-display-fix-dsc-validation.patch
blob: 45c6a47a1387dfb4ec4b8c55dab245c894338180 (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
From 5967fb618b74c114fe3b162b947ad8e3db8b1c76 Mon Sep 17 00:00:00 2001
From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Date: Tue, 26 Mar 2019 13:26:37 -0400
Subject: [PATCH 2482/2940] drm/amd/display: fix dsc validation

Currently dsc is validated not taking the image width limitation into
mind.

This change addresses that, but due to previous design being limited
to non odm dsc validation additional sequence changes are made.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c  |  5 +
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h  |  2 +
 .../drm/amd/display/dc/dcn20/dcn20_resource.c | 91 +++++++++++--------
 .../drm/amd/display/dc/dcn20/dcn20_resource.h |  1 -
 .../amd/display/dc/dml/display_mode_enums.h   |  1 +
 5 files changed, 60 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
index 4865cc341dec..be49fc7f4abe 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
@@ -91,6 +91,8 @@ void dsc2_construct(struct dcn20_dsc *dsc,
 	dsc->dsc_regs = dsc_regs;
 	dsc->dsc_shift = dsc_shift;
 	dsc->dsc_mask = dsc_mask;
+
+	dsc->max_image_width = 5184;
 }
 
 
@@ -161,6 +163,9 @@ static bool dsc2_validate_stream(struct display_stream_compressor *dsc, const st
 {
 	struct dsc_optc_config dsc_optc_cfg;
 
+	if (dsc_cfg->pic_width > TO_DCN20_DSC(dsc)->max_image_width)
+		return false;
+
 	return dsc_prepare_config(dsc, dsc_cfg, &dsc_optc_cfg);
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h
index 5cbb9df8272f..168865a16288 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h
@@ -558,6 +558,8 @@ struct dcn20_dsc {
 	const struct dcn20_dsc_mask *dsc_mask;
 
 	struct dsc_reg_values reg_vals;
+
+	int max_image_width;
 };
 
 
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 7aa2859b35fc..33f1a1d972a9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -1869,6 +1869,38 @@ void dcn20_set_mcif_arb_params(
 	}
 }
 
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
+{
+	int i;
+
+	/* Validate DSC config, dsc count validation is already done */
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i];
+		struct dc_stream_state *stream = pipe_ctx->stream;
+		struct dsc_config dsc_cfg;
+
+		/* Only need to validate top pipe */
+		if (pipe_ctx->top_pipe || !stream || !stream->timing.flags.DSC)
+			continue;
+
+		dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left
+				+ stream->timing.h_border_right;
+		dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top
+				+ stream->timing.v_border_bottom;
+		if (dc_res_get_odm_bottom_pipe(pipe_ctx))
+			dsc_cfg.pic_width /= 2;
+		dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
+		dsc_cfg.color_depth = stream->timing.display_color_depth;
+		dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+
+		if (!pipe_ctx->stream_res.dsc->funcs->dsc_validate_stream(pipe_ctx->stream_res.dsc, &dsc_cfg))
+			return false;
+	}
+	return true;
+}
+#endif
+
 bool dcn20_validate_bandwidth(struct dc *dc,
 			      struct dc_state *context,
 			      bool fast_validate)
@@ -1877,6 +1909,9 @@ bool dcn20_validate_bandwidth(struct dc *dc,
 	int pipe_split_from[MAX_PIPES];
 	bool odm_capable = context->bw_ctx.dml.ip.odm_capable;
 	bool force_split = false;
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	bool failed_non_odm_dsc = false;
+#endif
 	int split_threshold = dc->res_pool->pipe_count / 2;
 	bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
 	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
@@ -1920,6 +1955,15 @@ bool dcn20_validate_bandwidth(struct dc *dc,
 	vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
 	context->bw_ctx.dml.ip.odm_capable = odm_capable;
 
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	/* 1 dsc per stream dsc validation */
+	if (vlevel <= context->bw_ctx.dml.soc.num_states)
+		if (!dcn20_validate_dsc(dc, context)) {
+			failed_non_odm_dsc = true;
+			vlevel = context->bw_ctx.dml.soc.num_states + 1;
+		}
+#endif
+
 	if (vlevel > context->bw_ctx.dml.soc.num_states && odm_capable)
 		vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
 
@@ -2052,6 +2096,14 @@ bool dcn20_validate_bandwidth(struct dc *dc,
 			ASSERT(0);
 		}
 	}
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	/* Actual dsc count per stream dsc validation*/
+	if (failed_non_odm_dsc && !dcn20_validate_dsc(dc, context)) {
+		context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states] =
+				DML_FAIL_DSC_VALIDATION_FAILURE;
+		goto validate_fail;
+	}
+#endif
 
 	for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
 		if (!context->res_ctx.pipe_ctx[i].stream)
@@ -2190,44 +2242,6 @@ bool dcn20_validate_bandwidth(struct dc *dc,
 	return false;
 }
 
-enum dc_status dcn20_validate_global(struct dc *dc,	struct dc_state *new_ctx)
-{
-	enum dc_status result = DC_OK;
-	int i, j;
-
-	/* Validate DSC */
-	for (i = 0; i < new_ctx->stream_count; i++) {
-		struct dc_stream_state *stream = new_ctx->streams[i];
-
-		for (j = 0; j < dc->res_pool->pipe_count; j++) {
-			struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[j];
-
-			if (pipe_ctx->stream != stream)
-				continue;
-
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-			if (stream->timing.flags.DSC) {
-				if (pipe_ctx->stream_res.dsc != NULL) {
-					struct dsc_config dsc_cfg;
-
-					dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
-					dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
-					dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
-					dsc_cfg.color_depth = stream->timing.display_color_depth;
-					dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
-
-					if (!pipe_ctx->stream_res.dsc->funcs->dsc_validate_stream(pipe_ctx->stream_res.dsc, &dsc_cfg))
-						result = DC_FAIL_DSC_VALIDATE;
-				} else
-					result = DC_FAIL_DSC_VALIDATE; // DSC enabled for this stream, but no free DSCs available
-			}
-#endif
-		}
-	}
-
-	return result;
-}
-
 struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer(
 		struct dc_state *state,
 		const struct resource_pool *pool,
@@ -2302,7 +2316,6 @@ static struct resource_funcs dcn20_res_pool_funcs = {
 	.destroy = dcn20_destroy_resource_pool,
 	.link_enc_create = dcn20_link_encoder_create,
 	.validate_bandwidth = dcn20_validate_bandwidth,
-	.validate_global = dcn20_validate_global,
 	.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
 	.add_stream_to_ctx = dcn20_add_stream_to_ctx,
 	.remove_stream_from_ctx = dcn20_remove_stream_from_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 c5f176fb654a..b5a75289f444 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
@@ -118,7 +118,6 @@ void dcn20_set_mcif_arb_params(
 bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate);
 
 enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream);
-enum dc_status dcn20_validate_global(struct dc *dc,	struct dc_state *new_ctx);
 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);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
index 174c414e0982..e8da21f04454 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
@@ -130,6 +130,7 @@ enum dm_validation_status {
 	DML_FAIL_DIO_SUPPORT,
 	DML_FAIL_NOT_ENOUGH_DSC,
 	DML_FAIL_DSC_CLK_REQUIRED,
+	DML_FAIL_DSC_VALIDATION_FAILURE,
 	DML_FAIL_URGENT_LATENCY,
 	DML_FAIL_REORDERING_BUFFER,
 	DML_FAIL_DISPCLK_DPPCLK,
-- 
2.17.1