aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0579-drm-amd-display-Commit-validation-set-from-state.patch
blob: 913193792075eec2aa1d270c9d67d666332f866a (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
From 597a1c3327738758cd3c19491d3928212de2cc26 Mon Sep 17 00:00:00 2001
From: Harry Wentland <harry.wentland@amd.com>
Date: Mon, 6 Mar 2017 09:43:30 -0500
Subject: [PATCH 0579/4131] drm/amd/display: Commit validation set from state

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@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    |  34 +++---
 drivers/gpu/drm/amd/display/dc/core/dc.c           | 118 +++++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/dc.h                |  16 +++
 3 files changed, 152 insertions(+), 16 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 716b440..ee07b8c 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
@@ -2662,20 +2662,22 @@ void amdgpu_dm_atomic_commit_tail(
 	struct drm_device *dev = state->dev;
 	struct amdgpu_device *adev = dev->dev_private;
 	struct amdgpu_display_manager *dm = &adev->dm;
+	struct dm_atomic_state *dm_state;
 	uint32_t i, j;
-	uint32_t commit_streams_count = 0;
 	uint32_t new_crtcs_count = 0;
 	struct drm_crtc *crtc, *pcrtc;
 	struct drm_crtc_state *old_crtc_state;
-	const struct dc_stream *commit_streams[MAX_STREAMS];
 	struct amdgpu_crtc *new_crtcs[MAX_STREAMS];
-	const struct dc_stream *new_stream;
+	const struct dc_stream *new_stream = NULL;
 	unsigned long flags;
 	bool wait_for_vblank = true;
 	struct drm_connector *connector;
 	struct drm_connector_state *old_conn_state;
 
 	drm_atomic_helper_update_legacy_modeset_state(dev, state);
+
+	dm_state = to_dm_atomic_state(state);
+
 	/* update changed items */
 	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
 		struct amdgpu_crtc *acrtc;
@@ -2706,16 +2708,16 @@ void amdgpu_dm_atomic_commit_tail(
 		 */
 
 		if (modeset_required(new_state)) {
-			struct dm_connector_state *dm_state = NULL;
+			struct dm_connector_state *dm_conn_state = NULL;
 			new_stream = NULL;
 
 			if (aconnector)
-				dm_state = to_dm_connector_state(aconnector->base.state);
+				dm_conn_state = to_dm_connector_state(aconnector->base.state);
 
 			new_stream = create_stream_for_sink(
 					aconnector,
 					&crtc->state->mode,
-					dm_state);
+					dm_conn_state);
 
 			DRM_INFO("Atomic commit: SET crtc id %d: [%p]\n", acrtc->crtc_id, acrtc);
 
@@ -2743,6 +2745,13 @@ void amdgpu_dm_atomic_commit_tail(
 			if (acrtc->stream)
 				remove_stream(adev, acrtc);
 
+			/* TODO clean this stupid hack */
+			for (j = 0; j < dm_state->set_count; j++)
+				if (dm_state->set[j].stream->priv == acrtc) {
+					ASSERT(acrtc->stream == NULL);
+					new_stream = dm_state->set[j].stream;
+					break;
+				}
 			/*
 			 * this loop saves set mode crtcs
 			 * we needed to enable vblanks once all
@@ -2801,15 +2810,6 @@ void amdgpu_dm_atomic_commit_tail(
 			dm_error("%s: Failed to update stream scaling!\n", __func__);
 	}
 
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-
-		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
-
-		if (acrtc->stream) {
-			commit_streams[commit_streams_count] = acrtc->stream;
-			++commit_streams_count;
-		}
-	}
 
 	/*
 	 * Add streams after required streams from new and replaced streams
@@ -2838,7 +2838,8 @@ void amdgpu_dm_atomic_commit_tail(
 	}
 
 	/* DC is optimized not to do anything if 'streams' didn't change. */
-	WARN_ON(!dc_commit_streams(dm->dc, commit_streams, commit_streams_count));
+	WARN_ON(!dc_commit_validation_set(dm->dc, dm_state->set,
+					  dm_state->set_count));
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
@@ -3196,6 +3197,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
 			}
 
 			new_stream = create_stream_for_sink(aconnector, &crtc_state->mode, dm_conn_state);
+			new_stream->priv = acrtc;
 
 			/*
 			 * we can have no stream on ACTION_SET if a display
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 1d2e421e..b50fc0d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -841,6 +841,24 @@ static void program_timing_sync(
 	}
 }
 
+static bool set_changed(
+		struct core_dc *dc,
+		const struct dc_validation_set set[],
+		uint8_t set_count)
+{
+	uint8_t i;
+
+	if (set_count != dc->current_context->stream_count)
+		return true;
+
+	for (i = 0; i < dc->current_context->stream_count; i++) {
+		if (&dc->current_context->streams[i]->public != set[i].stream)
+			return true;
+	}
+
+	return false;
+}
+
 static bool streams_changed(
 		struct core_dc *dc,
 		const struct dc_stream *streams[],
@@ -896,6 +914,106 @@ bool dc_enable_stereo(
 	return ret;
 }
 
+/* TODO operate on validation set (or something like it) */
+bool dc_commit_validation_set(
+	const struct dc *dc,
+	const struct dc_validation_set set[],
+	uint8_t set_count)
+{
+	struct core_dc *core_dc = DC_TO_CORE(dc);
+	struct dc_bios *dcb = core_dc->ctx->dc_bios;
+	enum dc_status result = DC_ERROR_UNEXPECTED;
+	struct validate_context *context;
+	struct pipe_ctx *pipe;
+	int i, j, k, l;
+
+	/* TODO check validation set changed */
+	if (false == set_changed(core_dc, set, set_count))
+		return DC_OK;
+
+	dm_logger_write(core_dc->ctx->logger, LOG_DC, "%s: %d streams\n",
+				__func__, set_count);
+
+	for (i = 0; i < set_count; i++)
+		dc_stream_log(set[i].stream,
+			      core_dc->ctx->logger,
+			      LOG_DC);
+
+	context = dm_alloc(sizeof(struct validate_context));
+	if (context == NULL)
+		goto context_alloc_fail;
+
+	/* TODO no need for validation. just rebuild context */
+	/* TODO check context is created deterministically */
+	result = core_dc->res_pool->funcs->validate_with_context(core_dc, set,
+								 set_count,
+								 context,
+								 core_dc->current_context);
+	if (result != DC_OK) {
+		dm_logger_write(core_dc->ctx->logger, LOG_ERROR,
+					"%s: Context validation failed! dc_status:%d\n",
+					__func__,
+					result);
+		BREAK_TO_DEBUGGER();
+		dc_resource_validate_ctx_destruct(context);
+		goto fail;
+	}
+
+	if (!dcb->funcs->is_accelerated_mode(dcb))
+		core_dc->hwss.enable_accelerated_mode(core_dc);
+
+	if (result == DC_OK)
+		result = core_dc->hwss.apply_ctx_to_hw(core_dc, context);
+
+	program_timing_sync(core_dc, context);
+
+	for (i = 0; i < context->stream_count; i++) {
+		const struct core_sink *sink = context->streams[i]->sink;
+
+		for (j = 0; j < context->stream_status[i].surface_count; j++) {
+			struct core_surface *surface =
+					DC_SURFACE_TO_CORE(context->stream_status[i].surfaces[j]);
+
+			core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context);
+
+			/*
+			 * enable stereo
+			 * TODO rework dc_enable_stereo call to work with validation sets?
+			 */
+			for (k = 0; k < MAX_PIPES; k++) {
+				pipe = &context->res_ctx.pipe_ctx[k];
+
+				for (l = 0 ; pipe && l < context->stream_count; l++)  {
+					if (context->streams[l] &&
+					    context->streams[l] == pipe->stream &&
+					    core_dc->hwss.setup_stereo)
+						core_dc->hwss.setup_stereo(pipe, core_dc);
+				}
+			}
+		}
+
+		CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
+				context->streams[i]->public.timing.h_addressable,
+				context->streams[i]->public.timing.v_addressable,
+				context->streams[i]->public.timing.h_total,
+				context->streams[i]->public.timing.v_total,
+				context->streams[i]->public.timing.pix_clk_khz);
+	}
+
+	dc_resource_validate_ctx_destruct(core_dc->current_context);
+	dm_free(core_dc->current_context);
+
+	core_dc->current_context = context;
+
+	return (result == DC_OK);
+
+fail:
+	dm_free(context);
+
+context_alloc_fail:
+	return (result == DC_OK);
+}
+
 bool dc_commit_streams(
 	struct dc *dc,
 	const struct dc_stream *streams[],
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 93aff82..5487fb1 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -481,6 +481,8 @@ struct dc_stream {
 	/* TODO: ABM info (DMCU) */
 	/* TODO: PSR info */
 	/* TODO: CEA VIC */
+
+	void *priv;
 };
 
 struct dc_stream_update {
@@ -580,6 +582,20 @@ void dc_resource_validate_ctx_copy_construct(
 void dc_resource_validate_ctx_destruct(struct validate_context *context);
 
 /*
+ * TODO update to make it about validation sets
+ * Set up streams and links associated to drive sinks
+ * The streams parameter is an absolute set of all active streams.
+ *
+ * After this call:
+ *   Phy, Encoder, Timing Generator are programmed and enabled.
+ *   New streams are enabled with blank stream; no memory read.
+ */
+bool dc_commit_validation_set(
+		const struct dc *dc,
+		const struct dc_validation_set set[],
+		uint8_t set_count);
+
+/*
  * Set up streams and links associated to drive sinks
  * The streams parameter is an absolute set of all active streams.
  *
-- 
2.7.4