xref: /openbsd-src/sys/dev/pci/drm/drm_crtc.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*
2  * Copyright (c) 2006-2008 Intel Corporation
3  * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
4  * Copyright (c) 2008 Red Hat Inc.
5  *
6  * DRM core CRTC related functions
7  *
8  * Permission to use, copy, modify, distribute, and sell this software and its
9  * documentation for any purpose is hereby granted without fee, provided that
10  * the above copyright notice appear in all copies and that both that copyright
11  * notice and this permission notice appear in supporting documentation, and
12  * that the name of the copyright holders not be used in advertising or
13  * publicity pertaining to distribution of the software without specific,
14  * written prior permission.  The copyright holders make no representations
15  * about the suitability of this software for any purpose.  It is provided "as
16  * is" without express or implied warranty.
17  *
18  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24  * OF THIS SOFTWARE.
25  *
26  * Authors:
27  *      Keith Packard
28  *	Eric Anholt <eric@anholt.net>
29  *      Dave Airlie <airlied@linux.ie>
30  *      Jesse Barnes <jesse.barnes@intel.com>
31  */
32 #include <linux/ctype.h>
33 #include <linux/list.h>
34 #include <linux/slab.h>
35 #include <linux/export.h>
36 #include <linux/dma-fence.h>
37 #include <drm/drmP.h>
38 #include <drm/drm_crtc.h>
39 #include <drm/drm_edid.h>
40 #include <drm/drm_fourcc.h>
41 #include <drm/drm_modeset_lock.h>
42 #include <drm/drm_atomic.h>
43 #ifdef notyet
44 #include <drm/drm_auth.h>
45 #endif
46 #include <drm/drm_debugfs_crc.h>
47 
48 #include "drm_crtc_internal.h"
49 #include "drm_internal.h"
50 
51 /**
52  * DOC: overview
53  *
54  * A CRTC represents the overall display pipeline. It receives pixel data from
55  * &drm_plane and blends them together. The &drm_display_mode is also attached
56  * to the CRTC, specifying display timings. On the output side the data is fed
57  * to one or more &drm_encoder, which are then each connected to one
58  * &drm_connector.
59  *
60  * To create a CRTC, a KMS drivers allocates and zeroes an instances of
61  * &struct drm_crtc (possibly as part of a larger structure) and registers it
62  * with a call to drm_crtc_init_with_planes().
63  *
64  * The CRTC is also the entry point for legacy modeset operations, see
65  * &drm_crtc_funcs.set_config, legacy plane operations, see
66  * &drm_crtc_funcs.page_flip and &drm_crtc_funcs.cursor_set2, and other legacy
67  * operations like &drm_crtc_funcs.gamma_set. For atomic drivers all these
68  * features are controlled through &drm_property and
69  * &drm_mode_config_funcs.atomic_check and &drm_mode_config_funcs.atomic_check.
70  */
71 
72 /**
73  * drm_crtc_from_index - find the registered CRTC at an index
74  * @dev: DRM device
75  * @idx: index of registered CRTC to find for
76  *
77  * Given a CRTC index, return the registered CRTC from DRM device's
78  * list of CRTCs with matching index. This is the inverse of drm_crtc_index().
79  * It's useful in the vblank callbacks (like &drm_driver.enable_vblank or
80  * &drm_driver.disable_vblank), since that still deals with indices instead
81  * of pointers to &struct drm_crtc."
82  */
83 struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx)
84 {
85 	struct drm_crtc *crtc;
86 
87 	drm_for_each_crtc(crtc, dev)
88 		if (idx == crtc->index)
89 			return crtc;
90 
91 	return NULL;
92 }
93 EXPORT_SYMBOL(drm_crtc_from_index);
94 
95 /**
96  * drm_crtc_force_disable - Forcibly turn off a CRTC
97  * @crtc: CRTC to turn off
98  *
99  * Note: This should only be used by non-atomic legacy drivers.
100  *
101  * Returns:
102  * Zero on success, error code on failure.
103  */
104 int drm_crtc_force_disable(struct drm_crtc *crtc)
105 {
106 	struct drm_mode_set set = {
107 		.crtc = crtc,
108 	};
109 
110 	WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
111 
112 	return drm_mode_set_config_internal(&set);
113 }
114 EXPORT_SYMBOL(drm_crtc_force_disable);
115 
116 /**
117  * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs
118  * @dev: DRM device whose CRTCs to turn off
119  *
120  * Drivers may want to call this on unload to ensure that all displays are
121  * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
122  *
123  * Note: This should only be used by non-atomic legacy drivers. For an atomic
124  * version look at drm_atomic_helper_shutdown().
125  *
126  * Returns:
127  * Zero on success, error code on failure.
128  */
129 int drm_crtc_force_disable_all(struct drm_device *dev)
130 {
131 	struct drm_crtc *crtc;
132 	int ret = 0;
133 
134 	drm_modeset_lock_all(dev);
135 	drm_for_each_crtc(crtc, dev)
136 		if (crtc->enabled) {
137 			ret = drm_crtc_force_disable(crtc);
138 			if (ret)
139 				goto out;
140 		}
141 out:
142 	drm_modeset_unlock_all(dev);
143 	return ret;
144 }
145 EXPORT_SYMBOL(drm_crtc_force_disable_all);
146 
147 static unsigned int drm_num_crtcs(struct drm_device *dev)
148 {
149 	unsigned int num = 0;
150 	struct drm_crtc *tmp;
151 
152 	drm_for_each_crtc(tmp, dev) {
153 		num++;
154 	}
155 
156 	return num;
157 }
158 
159 int drm_crtc_register_all(struct drm_device *dev)
160 {
161 	struct drm_crtc *crtc;
162 	int ret = 0;
163 
164 	drm_for_each_crtc(crtc, dev) {
165 		if (drm_debugfs_crtc_add(crtc))
166 			DRM_ERROR("Failed to initialize debugfs entry for CRTC '%s'.\n",
167 				  crtc->name);
168 
169 		if (crtc->funcs->late_register)
170 			ret = crtc->funcs->late_register(crtc);
171 		if (ret)
172 			return ret;
173 	}
174 
175 	return 0;
176 }
177 
178 void drm_crtc_unregister_all(struct drm_device *dev)
179 {
180 	struct drm_crtc *crtc;
181 
182 	drm_for_each_crtc(crtc, dev) {
183 		if (crtc->funcs->early_unregister)
184 			crtc->funcs->early_unregister(crtc);
185 		drm_debugfs_crtc_remove(crtc);
186 	}
187 }
188 
189 static int drm_crtc_crc_init(struct drm_crtc *crtc)
190 {
191 #ifdef CONFIG_DEBUG_FS
192 	spin_lock_init(&crtc->crc.lock);
193 	init_waitqueue_head(&crtc->crc.wq);
194 	crtc->crc.source = kstrdup("auto", GFP_KERNEL);
195 	if (!crtc->crc.source)
196 		return -ENOMEM;
197 #endif
198 	return 0;
199 }
200 
201 static void drm_crtc_crc_fini(struct drm_crtc *crtc)
202 {
203 #ifdef CONFIG_DEBUG_FS
204 	kfree(crtc->crc.source);
205 #endif
206 }
207 
208 static const struct dma_fence_ops drm_crtc_fence_ops;
209 
210 static struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
211 {
212 	BUG_ON(fence->ops != &drm_crtc_fence_ops);
213 	return container_of(fence->lock, struct drm_crtc, fence_lock);
214 }
215 
216 static const char *drm_crtc_fence_get_driver_name(struct dma_fence *fence)
217 {
218 	struct drm_crtc *crtc = fence_to_crtc(fence);
219 
220 	return crtc->dev->driver->name;
221 }
222 
223 static const char *drm_crtc_fence_get_timeline_name(struct dma_fence *fence)
224 {
225 	struct drm_crtc *crtc = fence_to_crtc(fence);
226 
227 	return crtc->timeline_name;
228 }
229 
230 static const struct dma_fence_ops drm_crtc_fence_ops = {
231 	.get_driver_name = drm_crtc_fence_get_driver_name,
232 	.get_timeline_name = drm_crtc_fence_get_timeline_name,
233 };
234 
235 struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
236 {
237 	struct dma_fence *fence;
238 
239 	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
240 	if (!fence)
241 		return NULL;
242 
243 	dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock,
244 		       crtc->fence_context, ++crtc->fence_seqno);
245 
246 	return fence;
247 }
248 
249 /**
250  * drm_crtc_init_with_planes - Initialise a new CRTC object with
251  *    specified primary and cursor planes.
252  * @dev: DRM device
253  * @crtc: CRTC object to init
254  * @primary: Primary plane for CRTC
255  * @cursor: Cursor plane for CRTC
256  * @funcs: callbacks for the new CRTC
257  * @name: printf style format string for the CRTC name, or NULL for default name
258  *
259  * Inits a new object created as base part of a driver crtc object. Drivers
260  * should use this function instead of drm_crtc_init(), which is only provided
261  * for backwards compatibility with drivers which do not yet support universal
262  * planes). For really simple hardware which has only 1 plane look at
263  * drm_simple_display_pipe_init() instead.
264  *
265  * Returns:
266  * Zero on success, error code on failure.
267  */
268 int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
269 			      struct drm_plane *primary,
270 			      struct drm_plane *cursor,
271 			      const struct drm_crtc_funcs *funcs,
272 			      const char *name, ...)
273 {
274 	struct drm_mode_config *config = &dev->mode_config;
275 	int ret;
276 
277 	WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
278 	WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
279 
280 	/* crtc index is used with 32bit bitmasks */
281 	if (WARN_ON(config->num_crtc >= 32))
282 		return -EINVAL;
283 
284 	WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
285 		(!funcs->atomic_destroy_state ||
286 		 !funcs->atomic_duplicate_state));
287 
288 	crtc->dev = dev;
289 	crtc->funcs = funcs;
290 
291 	INIT_LIST_HEAD(&crtc->commit_list);
292 	mtx_init(&crtc->commit_lock, IPL_NONE);
293 
294 	drm_modeset_lock_init(&crtc->mutex);
295 	ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
296 	if (ret)
297 		return ret;
298 
299 	if (name) {
300 		va_list ap;
301 
302 		va_start(ap, name);
303 		crtc->name = kvasprintf(GFP_KERNEL, name, ap);
304 		va_end(ap);
305 	} else {
306 		crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
307 				       drm_num_crtcs(dev));
308 	}
309 	if (!crtc->name) {
310 		drm_mode_object_unregister(dev, &crtc->base);
311 		return -ENOMEM;
312 	}
313 
314 	crtc->fence_context = dma_fence_context_alloc(1);
315 	mtx_init(&crtc->fence_lock, IPL_NONE);
316 	snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),
317 		 "CRTC:%d-%s", crtc->base.id, crtc->name);
318 
319 	crtc->base.properties = &crtc->properties;
320 
321 	list_add_tail(&crtc->head, &config->crtc_list);
322 	crtc->index = config->num_crtc++;
323 
324 	crtc->primary = primary;
325 	crtc->cursor = cursor;
326 	if (primary && !primary->possible_crtcs)
327 		primary->possible_crtcs = drm_crtc_mask(crtc);
328 	if (cursor && !cursor->possible_crtcs)
329 		cursor->possible_crtcs = drm_crtc_mask(crtc);
330 
331 	ret = drm_crtc_crc_init(crtc);
332 	if (ret) {
333 		drm_mode_object_unregister(dev, &crtc->base);
334 		return ret;
335 	}
336 
337 	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
338 		drm_object_attach_property(&crtc->base, config->prop_active, 0);
339 		drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
340 		drm_object_attach_property(&crtc->base,
341 					   config->prop_out_fence_ptr, 0);
342 	}
343 
344 	return 0;
345 }
346 EXPORT_SYMBOL(drm_crtc_init_with_planes);
347 
348 /**
349  * drm_crtc_cleanup - Clean up the core crtc usage
350  * @crtc: CRTC to cleanup
351  *
352  * This function cleans up @crtc and removes it from the DRM mode setting
353  * core. Note that the function does *not* free the crtc structure itself,
354  * this is the responsibility of the caller.
355  */
356 void drm_crtc_cleanup(struct drm_crtc *crtc)
357 {
358 	struct drm_device *dev = crtc->dev;
359 
360 	/* Note that the crtc_list is considered to be static; should we
361 	 * remove the drm_crtc at runtime we would have to decrement all
362 	 * the indices on the drm_crtc after us in the crtc_list.
363 	 */
364 
365 	drm_crtc_crc_fini(crtc);
366 
367 	kfree(crtc->gamma_store);
368 	crtc->gamma_store = NULL;
369 
370 	drm_modeset_lock_fini(&crtc->mutex);
371 
372 	drm_mode_object_unregister(dev, &crtc->base);
373 	list_del(&crtc->head);
374 	dev->mode_config.num_crtc--;
375 
376 	WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
377 	if (crtc->state && crtc->funcs->atomic_destroy_state)
378 		crtc->funcs->atomic_destroy_state(crtc, crtc->state);
379 
380 	kfree(crtc->name);
381 
382 	memset(crtc, 0, sizeof(*crtc));
383 }
384 EXPORT_SYMBOL(drm_crtc_cleanup);
385 
386 /**
387  * drm_mode_getcrtc - get CRTC configuration
388  * @dev: drm device for the ioctl
389  * @data: data pointer for the ioctl
390  * @file_priv: drm file for the ioctl call
391  *
392  * Construct a CRTC configuration structure to return to the user.
393  *
394  * Called by the user via ioctl.
395  *
396  * Returns:
397  * Zero on success, negative errno on failure.
398  */
399 int drm_mode_getcrtc(struct drm_device *dev,
400 		     void *data, struct drm_file *file_priv)
401 {
402 	struct drm_mode_crtc *crtc_resp = data;
403 	struct drm_crtc *crtc;
404 	struct drm_plane *plane;
405 
406 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
407 		return -EINVAL;
408 
409 	crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
410 	if (!crtc)
411 		return -ENOENT;
412 
413 	plane = crtc->primary;
414 
415 	crtc_resp->gamma_size = crtc->gamma_size;
416 
417 	drm_modeset_lock(&plane->mutex, NULL);
418 	if (plane->state && plane->state->fb)
419 		crtc_resp->fb_id = plane->state->fb->base.id;
420 	else if (!plane->state && plane->fb)
421 		crtc_resp->fb_id = plane->fb->base.id;
422 	else
423 		crtc_resp->fb_id = 0;
424 
425 	if (plane->state) {
426 		crtc_resp->x = plane->state->src_x >> 16;
427 		crtc_resp->y = plane->state->src_y >> 16;
428 	}
429 	drm_modeset_unlock(&plane->mutex);
430 
431 	drm_modeset_lock(&crtc->mutex, NULL);
432 	if (crtc->state) {
433 		if (crtc->state->enable) {
434 			drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
435 			crtc_resp->mode_valid = 1;
436 		} else {
437 			crtc_resp->mode_valid = 0;
438 		}
439 	} else {
440 		crtc_resp->x = crtc->x;
441 		crtc_resp->y = crtc->y;
442 
443 		if (crtc->enabled) {
444 			drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
445 			crtc_resp->mode_valid = 1;
446 
447 		} else {
448 			crtc_resp->mode_valid = 0;
449 		}
450 	}
451 	if (!file_priv->aspect_ratio_allowed)
452 		crtc_resp->mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
453 	drm_modeset_unlock(&crtc->mutex);
454 
455 	return 0;
456 }
457 
458 static int __drm_mode_set_config_internal(struct drm_mode_set *set,
459 					  struct drm_modeset_acquire_ctx *ctx)
460 {
461 	struct drm_crtc *crtc = set->crtc;
462 	struct drm_framebuffer *fb;
463 	struct drm_crtc *tmp;
464 	int ret;
465 
466 	WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
467 
468 	/*
469 	 * NOTE: ->set_config can also disable other crtcs (if we steal all
470 	 * connectors from it), hence we need to refcount the fbs across all
471 	 * crtcs. Atomic modeset will have saner semantics ...
472 	 */
473 	drm_for_each_crtc(tmp, crtc->dev) {
474 		struct drm_plane *plane = tmp->primary;
475 
476 		plane->old_fb = plane->fb;
477 	}
478 
479 	fb = set->fb;
480 
481 	ret = crtc->funcs->set_config(set, ctx);
482 	if (ret == 0) {
483 		struct drm_plane *plane = crtc->primary;
484 
485 		plane->crtc = fb ? crtc : NULL;
486 		plane->fb = fb;
487 	}
488 
489 	drm_for_each_crtc(tmp, crtc->dev) {
490 		struct drm_plane *plane = tmp->primary;
491 
492 		if (plane->fb)
493 			drm_framebuffer_get(plane->fb);
494 		if (plane->old_fb)
495 			drm_framebuffer_put(plane->old_fb);
496 		plane->old_fb = NULL;
497 	}
498 
499 	return ret;
500 }
501 
502 /**
503  * drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
504  * @set: modeset config to set
505  *
506  * This is a little helper to wrap internal calls to the
507  * &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
508  * correct refcounting dance.
509  *
510  * This should only be used by non-atomic legacy drivers.
511  *
512  * Returns:
513  * Zero on success, negative errno on failure.
514  */
515 int drm_mode_set_config_internal(struct drm_mode_set *set)
516 {
517 	WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev));
518 
519 	return __drm_mode_set_config_internal(set, NULL);
520 }
521 EXPORT_SYMBOL(drm_mode_set_config_internal);
522 
523 /**
524  * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
525  *     CRTC viewport
526  * @crtc: CRTC that framebuffer will be displayed on
527  * @x: x panning
528  * @y: y panning
529  * @mode: mode that framebuffer will be displayed under
530  * @fb: framebuffer to check size of
531  */
532 int drm_crtc_check_viewport(const struct drm_crtc *crtc,
533 			    int x, int y,
534 			    const struct drm_display_mode *mode,
535 			    const struct drm_framebuffer *fb)
536 
537 {
538 	int hdisplay, vdisplay;
539 
540 	drm_mode_get_hv_timing(mode, &hdisplay, &vdisplay);
541 
542 	if (crtc->state &&
543 	    drm_rotation_90_or_270(crtc->primary->state->rotation))
544 		swap(hdisplay, vdisplay);
545 
546 	return drm_framebuffer_check_src_coords(x << 16, y << 16,
547 						hdisplay << 16, vdisplay << 16,
548 						fb);
549 }
550 EXPORT_SYMBOL(drm_crtc_check_viewport);
551 
552 /**
553  * drm_mode_setcrtc - set CRTC configuration
554  * @dev: drm device for the ioctl
555  * @data: data pointer for the ioctl
556  * @file_priv: drm file for the ioctl call
557  *
558  * Build a new CRTC configuration based on user request.
559  *
560  * Called by the user via ioctl.
561  *
562  * Returns:
563  * Zero on success, negative errno on failure.
564  */
565 int drm_mode_setcrtc(struct drm_device *dev, void *data,
566 		     struct drm_file *file_priv)
567 {
568 	struct drm_mode_config *config = &dev->mode_config;
569 	struct drm_mode_crtc *crtc_req = data;
570 	struct drm_crtc *crtc;
571 	struct drm_plane *plane;
572 	struct drm_connector **connector_set, *connector;
573 	struct drm_framebuffer *fb;
574 	struct drm_display_mode *mode;
575 	struct drm_mode_set set;
576 	uint32_t __user *set_connectors_ptr;
577 	struct drm_modeset_acquire_ctx ctx;
578 	int ret;
579 	int i;
580 
581 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
582 		return -EINVAL;
583 
584 	/*
585 	 * Universal plane src offsets are only 16.16, prevent havoc for
586 	 * drivers using universal plane code internally.
587 	 */
588 	if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
589 		return -ERANGE;
590 
591 	crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
592 	if (!crtc) {
593 		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
594 		return -ENOENT;
595 	}
596 	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
597 
598 	plane = crtc->primary;
599 
600 	/* allow disabling with the primary plane leased */
601 	if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id))
602 		return -EACCES;
603 
604 	mutex_lock(&crtc->dev->mode_config.mutex);
605 	drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
606 retry:
607 	connector_set = NULL;
608 	fb = NULL;
609 	mode = NULL;
610 
611 	ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
612 	if (ret)
613 		goto out;
614 
615 	if (crtc_req->mode_valid) {
616 		/* If we have a mode we need a framebuffer. */
617 		/* If we pass -1, set the mode with the currently bound fb */
618 		if (crtc_req->fb_id == -1) {
619 			struct drm_framebuffer *old_fb;
620 
621 			if (plane->state)
622 				old_fb = plane->state->fb;
623 			else
624 				old_fb = plane->fb;
625 
626 			if (!old_fb) {
627 				DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
628 				ret = -EINVAL;
629 				goto out;
630 			}
631 
632 			fb = old_fb;
633 			/* Make refcounting symmetric with the lookup path. */
634 			drm_framebuffer_get(fb);
635 		} else {
636 			fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
637 			if (!fb) {
638 				DRM_DEBUG_KMS("Unknown FB ID%d\n",
639 						crtc_req->fb_id);
640 				ret = -ENOENT;
641 				goto out;
642 			}
643 		}
644 
645 		mode = drm_mode_create(dev);
646 		if (!mode) {
647 			ret = -ENOMEM;
648 			goto out;
649 		}
650 		if (!file_priv->aspect_ratio_allowed &&
651 		    (crtc_req->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK) != DRM_MODE_FLAG_PIC_AR_NONE) {
652 			DRM_DEBUG_KMS("Unexpected aspect-ratio flag bits\n");
653 			ret = -EINVAL;
654 			goto out;
655 		}
656 
657 
658 		ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode);
659 		if (ret) {
660 			DRM_DEBUG_KMS("Invalid mode (ret=%d, status=%s)\n",
661 				      ret, drm_get_mode_status_name(mode->status));
662 			drm_mode_debug_printmodeline(mode);
663 			goto out;
664 		}
665 
666 		/*
667 		 * Check whether the primary plane supports the fb pixel format.
668 		 * Drivers not implementing the universal planes API use a
669 		 * default formats list provided by the DRM core which doesn't
670 		 * match real hardware capabilities. Skip the check in that
671 		 * case.
672 		 */
673 		if (!plane->format_default) {
674 			ret = drm_plane_check_pixel_format(plane,
675 							   fb->format->format,
676 							   fb->modifier);
677 			if (ret) {
678 #ifdef DRMDEBUG
679 				struct drm_format_name_buf format_name;
680 #endif
681 				DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
682 					      drm_get_format_name(fb->format->format,
683 								  &format_name),
684 					      fb->modifier);
685 				goto out;
686 			}
687 		}
688 
689 		ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
690 					      mode, fb);
691 		if (ret)
692 			goto out;
693 
694 	}
695 
696 	if (crtc_req->count_connectors == 0 && mode) {
697 		DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
698 		ret = -EINVAL;
699 		goto out;
700 	}
701 
702 	if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
703 		DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
704 			  crtc_req->count_connectors);
705 		ret = -EINVAL;
706 		goto out;
707 	}
708 
709 	if (crtc_req->count_connectors > 0) {
710 		u32 out_id;
711 
712 		/* Avoid unbounded kernel memory allocation */
713 		if (crtc_req->count_connectors > config->num_connector) {
714 			ret = -EINVAL;
715 			goto out;
716 		}
717 
718 		connector_set = kmalloc_array(crtc_req->count_connectors,
719 					      sizeof(struct drm_connector *),
720 					      GFP_KERNEL);
721 		if (!connector_set) {
722 			ret = -ENOMEM;
723 			goto out;
724 		}
725 
726 		for (i = 0; i < crtc_req->count_connectors; i++) {
727 			connector_set[i] = NULL;
728 			set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
729 			if (get_user(out_id, &set_connectors_ptr[i])) {
730 				ret = -EFAULT;
731 				goto out;
732 			}
733 
734 			connector = drm_connector_lookup(dev, file_priv, out_id);
735 			if (!connector) {
736 				DRM_DEBUG_KMS("Connector id %d unknown\n",
737 						out_id);
738 				ret = -ENOENT;
739 				goto out;
740 			}
741 			DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
742 					connector->base.id,
743 					connector->name);
744 
745 			connector_set[i] = connector;
746 		}
747 	}
748 
749 	set.crtc = crtc;
750 	set.x = crtc_req->x;
751 	set.y = crtc_req->y;
752 	set.mode = mode;
753 	set.connectors = connector_set;
754 	set.num_connectors = crtc_req->count_connectors;
755 	set.fb = fb;
756 
757 	if (drm_drv_uses_atomic_modeset(dev))
758 		ret = crtc->funcs->set_config(&set, &ctx);
759 	else
760 		ret = __drm_mode_set_config_internal(&set, &ctx);
761 
762 out:
763 	if (fb)
764 		drm_framebuffer_put(fb);
765 
766 	if (connector_set) {
767 		for (i = 0; i < crtc_req->count_connectors; i++) {
768 			if (connector_set[i])
769 				drm_connector_put(connector_set[i]);
770 		}
771 	}
772 	kfree(connector_set);
773 	drm_mode_destroy(dev, mode);
774 	if (ret == -EDEADLK) {
775 		ret = drm_modeset_backoff(&ctx);
776 		if (!ret)
777 			goto retry;
778 	}
779 	drm_modeset_drop_locks(&ctx);
780 	drm_modeset_acquire_fini(&ctx);
781 	mutex_unlock(&crtc->dev->mode_config.mutex);
782 
783 	return ret;
784 }
785 
786 int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
787 			       struct drm_property *property,
788 			       uint64_t value)
789 {
790 	int ret = -EINVAL;
791 	struct drm_crtc *crtc = obj_to_crtc(obj);
792 
793 	if (crtc->funcs->set_property)
794 		ret = crtc->funcs->set_property(crtc, property, value);
795 	if (!ret)
796 		drm_object_property_set_value(obj, property, value);
797 
798 	return ret;
799 }
800