Subversion Repositories Kolibri OS

Rev

Rev 6937 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6937 Rev 7144
Line 65... Line 65...
65
				struct drm_plane *plane)
65
				struct drm_plane *plane)
66
{
66
{
67
	struct drm_crtc_state *crtc_state;
67
	struct drm_crtc_state *crtc_state;
Line 68... Line 68...
68
 
68
 
69
	if (plane->state->crtc) {
69
	if (plane->state->crtc) {
-
 
70
		crtc_state = drm_atomic_get_existing_crtc_state(state,
Line 70... Line 71...
70
		crtc_state = state->crtc_states[drm_crtc_index(plane->state->crtc)];
71
								plane->state->crtc);
71
 
72
 
Line 72... Line 73...
72
		if (WARN_ON(!crtc_state))
73
		if (WARN_ON(!crtc_state))
73
			return;
74
			return;
Line 74... Line 75...
74
 
75
 
75
		crtc_state->planes_changed = true;
76
		crtc_state->planes_changed = true;
76
	}
77
	}
Line 77... Line 78...
77
 
78
 
78
	if (plane_state->crtc) {
79
	if (plane_state->crtc) {
Line 79... Line 80...
79
		crtc_state =
80
		crtc_state = drm_atomic_get_existing_crtc_state(state,
80
			state->crtc_states[drm_crtc_index(plane_state->crtc)];
81
								plane_state->crtc);
81
 
82
 
Line 82... Line -...
82
		if (WARN_ON(!crtc_state))
-
 
83
			return;
83
		if (WARN_ON(!crtc_state))
84
 
84
			return;
85
		crtc_state->planes_changed = true;
85
 
86
	}
-
 
87
}
86
		crtc_state->planes_changed = true;
-
 
87
	}
-
 
88
}
-
 
89
 
88
 
90
static int handle_conflicting_encoders(struct drm_atomic_state *state,
Line -... Line 91...
-
 
91
				       bool disable_conflicting_encoders)
-
 
92
{
-
 
93
	struct drm_connector_state *conn_state;
-
 
94
	struct drm_connector *connector;
-
 
95
	struct drm_encoder *encoder;
89
static bool
96
	unsigned encoder_mask = 0;
-
 
97
	int i, ret;
90
check_pending_encoder_assignment(struct drm_atomic_state *state,
98
 
-
 
99
	/*
-
 
100
	 * First loop, find all newly assigned encoders from the connectors
91
				 struct drm_encoder *new_encoder)
101
	 * part of the state. If the same encoder is assigned to multiple
Line -... Line 102...
-
 
102
	 * connectors bail out.
92
{
103
	 */
-
 
104
	for_each_connector_in_state(state, connector, conn_state, i) {
-
 
105
		const struct drm_connector_helper_funcs *funcs = connector->helper_private;
-
 
106
		struct drm_encoder *new_encoder;
-
 
107
 
93
	struct drm_connector *connector;
108
		if (!conn_state->crtc)
-
 
109
			continue;
-
 
110
 
-
 
111
		if (funcs->atomic_best_encoder)
-
 
112
			new_encoder = funcs->atomic_best_encoder(connector, conn_state);
94
	struct drm_connector_state *conn_state;
113
		else
95
	int i;
114
			new_encoder = funcs->best_encoder(connector);
Line -... Line 115...
-
 
115
 
96
 
116
		if (new_encoder) {
97
	for_each_connector_in_state(state, connector, conn_state, i) {
117
			if (encoder_mask & (1 << drm_encoder_index(new_encoder))) {
Line -... Line 118...
-
 
118
				DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] on [CONNECTOR:%d:%s] already assigned\n",
-
 
119
					new_encoder->base.id, new_encoder->name,
-
 
120
					connector->base.id, connector->name);
-
 
121
 
-
 
122
				return -EINVAL;
-
 
123
			}
-
 
124
 
-
 
125
			encoder_mask |= 1 << drm_encoder_index(new_encoder);
-
 
126
		}
-
 
127
	}
-
 
128
 
-
 
129
	if (!encoder_mask)
-
 
130
		return 0;
-
 
131
 
-
 
132
	/*
98
		if (conn_state->best_encoder != new_encoder)
133
	 * Second loop, iterate over all connectors not part of the state.
-
 
134
	 *
-
 
135
	 * If a conflicting encoder is found and disable_conflicting_encoders
-
 
136
	 * is not set, an error is returned. Userspace can provide a solution
-
 
137
	 * through the atomic ioctl.
-
 
138
	 *
-
 
139
	 * If the flag is set conflicting connectors are removed from the crtc
-
 
140
	 * and the crtc is disabled if no encoder is left. This preserves
-
 
141
	 * compatibility with the legacy set_config behavior.
-
 
142
	 */
-
 
143
	drm_for_each_connector(connector, state->dev) {
-
 
144
		struct drm_crtc_state *crtc_state;
-
 
145
 
-
 
146
		if (drm_atomic_get_existing_connector_state(state, connector))
-
 
147
			continue;
-
 
148
 
-
 
149
		encoder = connector->state->best_encoder;
-
 
150
		if (!encoder || !(encoder_mask & (1 << drm_encoder_index(encoder))))
-
 
151
			continue;
-
 
152
 
-
 
153
		if (!disable_conflicting_encoders) {
-
 
154
			DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s] by [CONNECTOR:%d:%s]\n",
-
 
155
					 encoder->base.id, encoder->name,
-
 
156
					 connector->state->crtc->base.id,
-
 
157
					 connector->state->crtc->name,
-
 
158
					 connector->base.id, connector->name);
-
 
159
			return -EINVAL;
-
 
160
		}
-
 
161
 
-
 
162
		conn_state = drm_atomic_get_connector_state(state, connector);
-
 
163
		if (IS_ERR(conn_state))
-
 
164
			return PTR_ERR(conn_state);
-
 
165
 
-
 
166
		DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
-
 
167
				 encoder->base.id, encoder->name,
-
 
168
				 conn_state->crtc->base.id, conn_state->crtc->name,
-
 
169
				 connector->base.id, connector->name);
-
 
170
 
-
 
171
		crtc_state = drm_atomic_get_existing_crtc_state(state, conn_state->crtc);
-
 
172
 
-
 
173
		ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
-
 
174
		if (ret)
-
 
175
			return ret;
-
 
176
 
-
 
177
		if (!crtc_state->connector_mask) {
-
 
178
			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
-
 
179
								NULL);
99
			continue;
180
			if (ret < 0)
-
 
181
				return ret;
100
 
182
 
101
		/* encoder already assigned and we're trying to re-steal it! */
183
			crtc_state->active = false;
102
		if (connector->state->best_encoder != conn_state->best_encoder)
184
		}
103
			return false;
185
	}
Line -... Line 186...
-
 
186
 
-
 
187
	return 0;
104
	}
188
}
Line -... Line 189...
-
 
189
 
-
 
190
static void
105
 
191
set_best_encoder(struct drm_atomic_state *state,
-
 
192
		 struct drm_connector_state *conn_state,
106
	return true;
193
		 struct drm_encoder *encoder)
-
 
194
{
-
 
195
	struct drm_crtc_state *crtc_state;
107
}
196
	struct drm_crtc *crtc;
-
 
197
 
-
 
198
	if (conn_state->best_encoder) {
-
 
199
		/* Unset the encoder_mask in the old crtc state. */
-
 
200
		crtc = conn_state->connector->state->crtc;
-
 
201
 
-
 
202
		/* A NULL crtc is an error here because we should have
Line -... Line 203...
-
 
203
		 *  duplicated a NULL best_encoder when crtc was NULL.
108
 
204
		 * As an exception restoring duplicated atomic state
-
 
205
		 * during resume is allowed, so don't warn when
-
 
206
		 * best_encoder is equal to encoder we intend to set.
-
 
207
		 */
-
 
208
		WARN_ON(!crtc && encoder != conn_state->best_encoder);
-
 
209
		if (crtc) {
-
 
210
			crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
-
 
211
 
109
static struct drm_crtc *
212
			crtc_state->encoder_mask &=
Line 110... Line 213...
110
get_current_crtc_for_encoder(struct drm_device *dev,
213
				~(1 << drm_encoder_index(conn_state->best_encoder));
111
			     struct drm_encoder *encoder)
214
		}
Line 112... Line 215...
112
{
215
	}
113
	struct drm_mode_config *config = &dev->mode_config;
216
 
114
	struct drm_connector *connector;
217
	if (encoder) {
115
 
-
 
116
	WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
218
		crtc = conn_state->crtc;
117
 
-
 
118
	drm_for_each_connector(connector, dev) {
219
		WARN_ON(!crtc);
119
		if (connector->state->best_encoder != encoder)
220
		if (crtc) {
120
			continue;
221
			crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
121
 
222
 
Line -... Line 223...
-
 
223
			crtc_state->encoder_mask |=
-
 
224
				1 << drm_encoder_index(encoder);
122
		return connector->state->crtc;
225
		}
123
	}
226
	}
124
 
227
 
125
	return NULL;
228
	conn_state->best_encoder = encoder;
126
}
229
}
Line 127... Line 230...
127
 
230
 
128
static int
231
static void
129
steal_encoder(struct drm_atomic_state *state,
232
steal_encoder(struct drm_atomic_state *state,
Line 130... Line 233...
130
	      struct drm_encoder *encoder,
233
	      struct drm_encoder *encoder)
131
	      struct drm_crtc *encoder_crtc)
-
 
132
{
-
 
Line -... Line 234...
-
 
234
{
133
	struct drm_mode_config *config = &state->dev->mode_config;
235
	struct drm_crtc_state *crtc_state;
Line 134... Line -...
134
	struct drm_crtc_state *crtc_state;
-
 
135
	struct drm_connector *connector;
-
 
136
	struct drm_connector_state *connector_state;
-
 
137
	int ret;
-
 
138
 
-
 
139
	/*
-
 
140
	 * We can only steal an encoder coming from a connector, which means we
-
 
141
	 * must already hold the connection_mutex.
-
 
142
	 */
-
 
143
	WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
-
 
144
 
-
 
145
	DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
-
 
146
			 encoder->base.id, encoder->name,
-
 
147
			 encoder_crtc->base.id, encoder_crtc->name);
-
 
148
 
-
 
149
	crtc_state = drm_atomic_get_crtc_state(state, encoder_crtc);
236
	struct drm_connector *connector;
150
	if (IS_ERR(crtc_state))
-
 
151
		return PTR_ERR(crtc_state);
237
	struct drm_connector_state *connector_state;
152
 
-
 
153
	crtc_state->connectors_changed = true;
-
 
154
 
238
	int i;
Line 155... Line 239...
155
	list_for_each_entry(connector, &config->connector_list, head) {
239
 
156
		if (connector->state->best_encoder != encoder)
240
	for_each_connector_in_state(state, connector, connector_state, i) {
-
 
241
		struct drm_crtc *encoder_crtc;
-
 
242
 
157
			continue;
243
		if (connector_state->best_encoder != encoder)
158
 
244
			continue;
159
		DRM_DEBUG_ATOMIC("Stealing encoder from [CONNECTOR:%d:%s]\n",
245
 
160
				 connector->base.id,
-
 
161
				 connector->name);
-
 
162
 
-
 
163
		connector_state = drm_atomic_get_connector_state(state,
246
		encoder_crtc = connector->state->crtc;
164
								 connector);
-
 
165
		if (IS_ERR(connector_state))
-
 
166
			return PTR_ERR(connector_state);
-
 
167
 
-
 
168
		ret = drm_atomic_set_crtc_for_connector(connector_state, NULL);
-
 
169
		if (ret)
-
 
170
			return ret;
-
 
Line 171... Line 247...
171
		connector_state->best_encoder = NULL;
247
 
172
	}
248
		DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
173
 
249
				 encoder->base.id, encoder->name,
Line 174... Line 250...
174
	return 0;
250
				 encoder_crtc->base.id, encoder_crtc->name);
175
}
251
 
176
 
252
		set_best_encoder(state, connector_state, NULL);
177
static int
-
 
178
update_connector_routing(struct drm_atomic_state *state, int conn_idx)
-
 
179
{
253
 
180
	const struct drm_connector_helper_funcs *funcs;
254
		crtc_state = drm_atomic_get_existing_crtc_state(state, encoder_crtc);
Line 181... Line 255...
181
	struct drm_encoder *new_encoder;
255
		crtc_state->connectors_changed = true;
182
	struct drm_crtc *encoder_crtc;
256
 
183
	struct drm_connector *connector;
-
 
184
	struct drm_connector_state *connector_state;
-
 
185
	struct drm_crtc_state *crtc_state;
257
		return;
186
	int idx, ret;
258
	}
187
 
259
}
Line 188... Line 260...
188
	connector = state->connectors[conn_idx];
260
 
189
	connector_state = state->connector_states[conn_idx];
261
static int
190
 
262
update_connector_routing(struct drm_atomic_state *state,
191
	if (!connector)
263
			 struct drm_connector *connector,
Line 192... Line 264...
192
		return 0;
264
			 struct drm_connector_state *connector_state)
Line 193... Line 265...
193
 
265
{
194
	DRM_DEBUG_ATOMIC("Updating routing for [CONNECTOR:%d:%s]\n",
266
	const struct drm_connector_helper_funcs *funcs;
Line 195... Line 267...
195
			 connector->base.id,
267
	struct drm_encoder *new_encoder;
Line 243... Line 315...
243
				 connector_state->crtc->base.id);
315
				 connector_state->crtc->base.id);
244
		return -EINVAL;
316
		return -EINVAL;
245
	}
317
	}
Line 246... Line 318...
246
 
318
 
-
 
319
	if (new_encoder == connector_state->best_encoder) {
-
 
320
		set_best_encoder(state, connector_state, new_encoder);
247
	if (new_encoder == connector_state->best_encoder) {
321
 
248
		DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
322
		DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
249
				 connector->base.id,
323
				 connector->base.id,
250
				 connector->name,
324
				 connector->name,
251
				 new_encoder->base.id,
325
				 new_encoder->base.id,
Line 254... Line 328...
254
				 connector_state->crtc->name);
328
				 connector_state->crtc->name);
Line 255... Line 329...
255
 
329
 
256
		return 0;
330
		return 0;
Line 257... Line 331...
257
	}
331
	}
258
 
-
 
259
	if (!check_pending_encoder_assignment(state, new_encoder)) {
-
 
260
		DRM_DEBUG_ATOMIC("Encoder for [CONNECTOR:%d:%s] already assigned\n",
-
 
261
				 connector->base.id,
-
 
262
				 connector->name);
-
 
263
		return -EINVAL;
-
 
264
	}
-
 
265
 
-
 
Line 266... Line -...
266
	encoder_crtc = get_current_crtc_for_encoder(state->dev,
-
 
267
						    new_encoder);
332
 
268
 
-
 
269
	if (encoder_crtc) {
-
 
270
		ret = steal_encoder(state, new_encoder, encoder_crtc);
-
 
271
		if (ret) {
-
 
272
			DRM_DEBUG_ATOMIC("Encoder stealing failed for [CONNECTOR:%d:%s]\n",
-
 
273
					 connector->base.id,
-
 
274
					 connector->name);
-
 
Line 275... Line -...
275
			return ret;
-
 
276
		}
-
 
277
	}
-
 
278
 
-
 
279
	if (WARN_ON(!connector_state->crtc))
333
	steal_encoder(state, new_encoder);
280
		return -EINVAL;
-
 
281
 
-
 
282
	connector_state->best_encoder = new_encoder;
334
 
Line 283... Line 335...
283
	idx = drm_crtc_index(connector_state->crtc);
335
	set_best_encoder(state, connector_state, new_encoder);
284
 
336
 
285
	crtc_state = state->crtc_states[idx];
337
	crtc_state = drm_atomic_get_existing_crtc_state(state, connector_state->crtc);
Line 321... Line 373...
321
		WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc);
373
		WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc);
Line 322... Line 374...
322
 
374
 
323
		if (!conn_state->crtc || !conn_state->best_encoder)
375
		if (!conn_state->crtc || !conn_state->best_encoder)
Line 324... Line 376...
324
			continue;
376
			continue;
325
 
377
 
Line 326... Line 378...
326
		crtc_state =
378
		crtc_state = drm_atomic_get_existing_crtc_state(state,
327
			state->crtc_states[drm_crtc_index(conn_state->crtc)];
379
								conn_state->crtc);
328
 
380
 
329
		/*
381
		/*
Line 443... Line 495...
443
			crtc_state->mode_changed = true;
495
			crtc_state->mode_changed = true;
444
			crtc_state->connectors_changed = true;
496
			crtc_state->connectors_changed = true;
445
		}
497
		}
446
	}
498
	}
Line -... Line 499...
-
 
499
 
-
 
500
	ret = handle_conflicting_encoders(state, state->legacy_set_config);
-
 
501
	if (ret)
-
 
502
		return ret;
447
 
503
 
448
	for_each_connector_in_state(state, connector, connector_state, i) {
504
	for_each_connector_in_state(state, connector, connector_state, i) {
449
		/*
505
		/*
450
		 * This only sets crtc->mode_changed for routing changes,
506
		 * This only sets crtc->mode_changed for routing changes,
451
		 * drivers must set crtc->mode_changed themselves when connector
507
		 * drivers must set crtc->mode_changed themselves when connector
452
		 * properties need to be updated.
508
		 * properties need to be updated.
453
		 */
509
		 */
-
 
510
		ret = update_connector_routing(state, connector,
454
		ret = update_connector_routing(state, i);
511
					       connector_state);
455
		if (ret)
512
		if (ret)
456
			return ret;
513
			return ret;
Line 457... Line 514...
457
	}
514
	}
Line 615... Line 672...
615
	int i;
672
	int i;
Line 616... Line 673...
616
 
673
 
617
	for_each_connector_in_state(old_state, connector, old_conn_state, i) {
674
	for_each_connector_in_state(old_state, connector, old_conn_state, i) {
618
		const struct drm_encoder_helper_funcs *funcs;
675
		const struct drm_encoder_helper_funcs *funcs;
619
		struct drm_encoder *encoder;
-
 
Line 620... Line 676...
620
		struct drm_crtc_state *old_crtc_state;
676
		struct drm_encoder *encoder;
621
 
677
 
622
		/* Shut down everything that's in the changeset and currently
678
		/* Shut down everything that's in the changeset and currently
623
		 * still on. So need to check the old, saved state. */
679
		 * still on. So need to check the old, saved state. */
Line 624... Line 680...
624
		if (!old_conn_state->crtc)
680
		if (!old_conn_state->crtc)
-
 
681
			continue;
Line 625... Line 682...
625
			continue;
682
 
626
 
683
		old_crtc_state = drm_atomic_get_existing_crtc_state(old_state,
627
		old_crtc_state = old_state->crtc_states[drm_crtc_index(old_conn_state->crtc)];
684
								    old_conn_state->crtc);
Line 1717... Line 1774...
1717
	struct drm_device *dev = set->crtc->dev;
1774
	struct drm_device *dev = set->crtc->dev;
1718
	struct drm_crtc *crtc;
1775
	struct drm_crtc *crtc;
1719
	struct drm_crtc_state *crtc_state;
1776
	struct drm_crtc_state *crtc_state;
1720
	struct drm_connector *connector;
1777
	struct drm_connector *connector;
1721
	struct drm_connector_state *conn_state;
1778
	struct drm_connector_state *conn_state;
1722
	int ret, i, j;
1779
	int ret, i;
Line 1723... Line 1780...
1723
 
1780
 
1724
	ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1781
	ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1725
			       state->acquire_ctx);
1782
			       state->acquire_ctx);
1726
	if (ret)
1783
	if (ret)
Line 1727... Line 1784...
1727
		return ret;
1784
		return ret;
1728
 
-
 
1729
	/* First grab all affected connector/crtc states. */
-
 
1730
	for (i = 0; i < set->num_connectors; i++) {
-
 
1731
		conn_state = drm_atomic_get_connector_state(state,
-
 
1732
							    set->connectors[i]);
-
 
1733
		if (IS_ERR(conn_state))
-
 
1734
			return PTR_ERR(conn_state);
-
 
1735
	}
-
 
1736
 
1785
 
1737
	for_each_crtc_in_state(state, crtc, crtc_state, i) {
1786
	/* First disable all connectors on the target crtc. */
1738
		ret = drm_atomic_add_affected_connectors(state, crtc);
1787
	ret = drm_atomic_add_affected_connectors(state, set->crtc);
1739
		if (ret)
-
 
Line 1740... Line -...
1740
			return ret;
-
 
1741
	}
1788
	if (ret)
1742
 
1789
		return ret;
1743
	/* Then recompute connector->crtc links and crtc enabling state. */
1790
 
1744
	for_each_connector_in_state(state, connector, conn_state, i) {
1791
	for_each_connector_in_state(state, connector, conn_state, i) {
1745
		if (conn_state->crtc == set->crtc) {
1792
		if (conn_state->crtc == set->crtc) {
1746
			ret = drm_atomic_set_crtc_for_connector(conn_state,
1793
			ret = drm_atomic_set_crtc_for_connector(conn_state,
1747
								NULL);
1794
								NULL);
-
 
1795
			if (ret)
-
 
1796
				return ret;
-
 
1797
		}
-
 
1798
	}
-
 
1799
 
-
 
1800
	/* Then set all connectors from set->connectors on the target crtc */
-
 
1801
	for (i = 0; i < set->num_connectors; i++) {
-
 
1802
		conn_state = drm_atomic_get_connector_state(state,
Line 1748... Line -...
1748
			if (ret)
-
 
1749
				return ret;
-
 
1750
		}
1803
							    set->connectors[i]);
1751
 
1804
		if (IS_ERR(conn_state))
1752
		for (j = 0; j < set->num_connectors; j++) {
1805
			return PTR_ERR(conn_state);
1753
			if (set->connectors[j] == connector) {
1806
 
1754
				ret = drm_atomic_set_crtc_for_connector(conn_state,
-
 
1755
									set->crtc);
-
 
1756
				if (ret)
-
 
1757
					return ret;
1807
		ret = drm_atomic_set_crtc_for_connector(conn_state,
Line 1758... Line 1808...
1758
				break;
1808
							set->crtc);
1759
			}
1809
		if (ret)
1760
		}
1810
			return ret;
Line 1798... Line 1848...
1798
 
1848
 
1799
	state = drm_atomic_state_alloc(crtc->dev);
1849
	state = drm_atomic_state_alloc(crtc->dev);
1800
	if (!state)
1850
	if (!state)
Line -... Line 1851...
-
 
1851
		return -ENOMEM;
1801
		return -ENOMEM;
1852
 
1802
 
1853
	state->legacy_set_config = true;
1803
	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
1854
	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
1804
retry:
1855
retry:
1805
	ret = __drm_atomic_helper_set_config(set, state);
1856
	ret = __drm_atomic_helper_set_config(set, state);
Line 2444... Line 2495...
2444
 * Resets the atomic state for @crtc by freeing the state pointer (which might
2495
 * Resets the atomic state for @crtc by freeing the state pointer (which might
2445
 * be NULL, e.g. at driver load time) and allocating a new empty state object.
2496
 * be NULL, e.g. at driver load time) and allocating a new empty state object.
2446
 */
2497
 */
2447
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
2498
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
2448
{
2499
{
2449
	if (crtc->state)
2500
	if (crtc->state) {
2450
		drm_property_unreference_blob(crtc->state->mode_blob);
2501
		drm_property_unreference_blob(crtc->state->mode_blob);
-
 
2502
		drm_property_unreference_blob(crtc->state->degamma_lut);
-
 
2503
		drm_property_unreference_blob(crtc->state->ctm);
-
 
2504
		drm_property_unreference_blob(crtc->state->gamma_lut);
-
 
2505
	}
2451
	kfree(crtc->state);
2506
	kfree(crtc->state);
2452
	crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
2507
	crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
Line 2453... Line 2508...
2453
 
2508
 
2454
	if (crtc->state)
2509
	if (crtc->state)
Line 2469... Line 2524...
2469
{
2524
{
2470
	memcpy(state, crtc->state, sizeof(*state));
2525
	memcpy(state, crtc->state, sizeof(*state));
Line 2471... Line 2526...
2471
 
2526
 
2472
	if (state->mode_blob)
2527
	if (state->mode_blob)
-
 
2528
		drm_property_reference_blob(state->mode_blob);
-
 
2529
	if (state->degamma_lut)
-
 
2530
		drm_property_reference_blob(state->degamma_lut);
-
 
2531
	if (state->ctm)
-
 
2532
		drm_property_reference_blob(state->ctm);
-
 
2533
	if (state->gamma_lut)
2473
		drm_property_reference_blob(state->mode_blob);
2534
		drm_property_reference_blob(state->gamma_lut);
2474
	state->mode_changed = false;
2535
	state->mode_changed = false;
2475
	state->active_changed = false;
2536
	state->active_changed = false;
2476
	state->planes_changed = false;
2537
	state->planes_changed = false;
-
 
2538
	state->connectors_changed = false;
2477
	state->connectors_changed = false;
2539
	state->color_mgmt_changed = false;
2478
	state->event = NULL;
2540
	state->event = NULL;
2479
}
2541
}
Line 2480... Line 2542...
2480
EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
2542
EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
Line 2513... Line 2575...
2513
 */
2575
 */
2514
void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
2576
void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
2515
					    struct drm_crtc_state *state)
2577
					    struct drm_crtc_state *state)
2516
{
2578
{
2517
		drm_property_unreference_blob(state->mode_blob);
2579
	drm_property_unreference_blob(state->mode_blob);
-
 
2580
	drm_property_unreference_blob(state->degamma_lut);
-
 
2581
	drm_property_unreference_blob(state->ctm);
-
 
2582
	drm_property_unreference_blob(state->gamma_lut);
2518
}
2583
}
2519
EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
2584
EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
Line 2520... Line 2585...
2520
 
2585
 
2521
/**
2586
/**
Line 2547... Line 2612...
2547
		drm_framebuffer_unreference(plane->state->fb);
2612
		drm_framebuffer_unreference(plane->state->fb);
Line 2548... Line 2613...
2548
 
2613
 
2549
	kfree(plane->state);
2614
	kfree(plane->state);
Line 2550... Line 2615...
2550
	plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
2615
	plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
2551
 
2616
 
-
 
2617
	if (plane->state) {
-
 
2618
		plane->state->plane = plane;
2552
	if (plane->state)
2619
		plane->state->rotation = BIT(DRM_ROTATE_0);
2553
		plane->state->plane = plane;
2620
	}
Line 2554... Line 2621...
2554
}
2621
}
2555
EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
2622
EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
Line 2824... Line 2891...
2824
{
2891
{
2825
	__drm_atomic_helper_connector_destroy_state(connector, state);
2892
	__drm_atomic_helper_connector_destroy_state(connector, state);
2826
	kfree(state);
2893
	kfree(state);
2827
}
2894
}
2828
EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
2895
EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
-
 
2896
 
-
 
2897
/**
-
 
2898
 * drm_atomic_helper_legacy_gamma_set - set the legacy gamma correction table
-
 
2899
 * @crtc: CRTC object
-
 
2900
 * @red: red correction table
-
 
2901
 * @green: green correction table
-
 
2902
 * @blue: green correction table
-
 
2903
 * @start:
-
 
2904
 * @size: size of the tables
-
 
2905
 *
-
 
2906
 * Implements support for legacy gamma correction table for drivers
-
 
2907
 * that support color management through the DEGAMMA_LUT/GAMMA_LUT
-
 
2908
 * properties.
-
 
2909
 */
-
 
2910
void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
-
 
2911
					u16 *red, u16 *green, u16 *blue,
-
 
2912
					uint32_t start, uint32_t size)
-
 
2913
{
-
 
2914
	struct drm_device *dev = crtc->dev;
-
 
2915
	struct drm_mode_config *config = &dev->mode_config;
-
 
2916
	struct drm_atomic_state *state;
-
 
2917
	struct drm_crtc_state *crtc_state;
-
 
2918
	struct drm_property_blob *blob = NULL;
-
 
2919
	struct drm_color_lut *blob_data;
-
 
2920
	int i, ret = 0;
-
 
2921
 
-
 
2922
	state = drm_atomic_state_alloc(crtc->dev);
-
 
2923
	if (!state)
-
 
2924
		return;
-
 
2925
 
-
 
2926
	blob = drm_property_create_blob(dev,
-
 
2927
					sizeof(struct drm_color_lut) * size,
-
 
2928
					NULL);
-
 
2929
	if (IS_ERR(blob)) {
-
 
2930
		ret = PTR_ERR(blob);
-
 
2931
		blob = NULL;
-
 
2932
		goto fail;
-
 
2933
	}
-
 
2934
 
-
 
2935
	/* Prepare GAMMA_LUT with the legacy values. */
-
 
2936
	blob_data = (struct drm_color_lut *) blob->data;
-
 
2937
	for (i = 0; i < size; i++) {
-
 
2938
		blob_data[i].red = red[i];
-
 
2939
		blob_data[i].green = green[i];
-
 
2940
		blob_data[i].blue = blue[i];
-
 
2941
	}
-
 
2942
 
-
 
2943
	state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
-
 
2944
retry:
-
 
2945
	crtc_state = drm_atomic_get_crtc_state(state, crtc);
-
 
2946
	if (IS_ERR(crtc_state)) {
-
 
2947
		ret = PTR_ERR(crtc_state);
-
 
2948
		goto fail;
-
 
2949
	}
-
 
2950
 
-
 
2951
	/* Reset DEGAMMA_LUT and CTM properties. */
-
 
2952
	ret = drm_atomic_crtc_set_property(crtc, crtc_state,
-
 
2953
			config->degamma_lut_property, 0);
-
 
2954
	if (ret)
-
 
2955
		goto fail;
-
 
2956
 
-
 
2957
	ret = drm_atomic_crtc_set_property(crtc, crtc_state,
-
 
2958
			config->ctm_property, 0);
-
 
2959
	if (ret)
-
 
2960
		goto fail;
-
 
2961
 
-
 
2962
	ret = drm_atomic_crtc_set_property(crtc, crtc_state,
-
 
2963
			config->gamma_lut_property, blob->base.id);
-
 
2964
	if (ret)
-
 
2965
		goto fail;
-
 
2966
 
-
 
2967
	ret = drm_atomic_commit(state);
-
 
2968
	if (ret)
-
 
2969
		goto fail;
-
 
2970
 
-
 
2971
	/* Driver takes ownership of state on successful commit. */
-
 
2972
 
-
 
2973
	drm_property_unreference_blob(blob);
-
 
2974
 
-
 
2975
	return;
-
 
2976
fail:
-
 
2977
	if (ret == -EDEADLK)
-
 
2978
		goto backoff;
-
 
2979
 
-
 
2980
	drm_atomic_state_free(state);
-
 
2981
	drm_property_unreference_blob(blob);
-
 
2982
 
-
 
2983
	return;
-
 
2984
backoff:
-
 
2985
	drm_atomic_state_clear(state);
-
 
2986
	drm_atomic_legacy_backoff(state);
-
 
2987
 
-
 
2988
	goto retry;
-
 
2989
}
-
 
2990
EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);