]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/drm_crtc.c
cea7a7efa43c903769f08a2f198691cd11af1a5c
[karo-tx-linux.git] / drivers / gpu / drm / drm_crtc.c
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 #include <drm/drm_auth.h>
44 #include <drm/drm_debugfs_crc.h>
45
46 #include "drm_crtc_internal.h"
47 #include "drm_internal.h"
48
49 /**
50  * drm_crtc_from_index - find the registered CRTC at an index
51  * @dev: DRM device
52  * @idx: index of registered CRTC to find for
53  *
54  * Given a CRTC index, return the registered CRTC from DRM device's
55  * list of CRTCs with matching index. This is the inverse of drm_crtc_index().
56  * It's useful in the vblank callbacks (like &drm_driver.enable_vblank or
57  * &drm_driver.disable_vblank), since that still deals with indices instead
58  * of pointers to &struct drm_crtc."
59  */
60 struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx)
61 {
62         struct drm_crtc *crtc;
63
64         drm_for_each_crtc(crtc, dev)
65                 if (idx == crtc->index)
66                         return crtc;
67
68         return NULL;
69 }
70 EXPORT_SYMBOL(drm_crtc_from_index);
71
72 /**
73  * drm_crtc_force_disable - Forcibly turn off a CRTC
74  * @crtc: CRTC to turn off
75  *
76  * Returns:
77  * Zero on success, error code on failure.
78  */
79 int drm_crtc_force_disable(struct drm_crtc *crtc)
80 {
81         struct drm_mode_set set = {
82                 .crtc = crtc,
83         };
84
85         return drm_mode_set_config_internal(&set);
86 }
87 EXPORT_SYMBOL(drm_crtc_force_disable);
88
89 /**
90  * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs
91  * @dev: DRM device whose CRTCs to turn off
92  *
93  * Drivers may want to call this on unload to ensure that all displays are
94  * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
95  *
96  * Returns:
97  * Zero on success, error code on failure.
98  */
99 int drm_crtc_force_disable_all(struct drm_device *dev)
100 {
101         struct drm_crtc *crtc;
102         int ret = 0;
103
104         drm_modeset_lock_all(dev);
105         drm_for_each_crtc(crtc, dev)
106                 if (crtc->enabled) {
107                         ret = drm_crtc_force_disable(crtc);
108                         if (ret)
109                                 goto out;
110                 }
111 out:
112         drm_modeset_unlock_all(dev);
113         return ret;
114 }
115 EXPORT_SYMBOL(drm_crtc_force_disable_all);
116
117 static unsigned int drm_num_crtcs(struct drm_device *dev)
118 {
119         unsigned int num = 0;
120         struct drm_crtc *tmp;
121
122         drm_for_each_crtc(tmp, dev) {
123                 num++;
124         }
125
126         return num;
127 }
128
129 int drm_crtc_register_all(struct drm_device *dev)
130 {
131         struct drm_crtc *crtc;
132         int ret = 0;
133
134         drm_for_each_crtc(crtc, dev) {
135                 if (drm_debugfs_crtc_add(crtc))
136                         DRM_ERROR("Failed to initialize debugfs entry for CRTC '%s'.\n",
137                                   crtc->name);
138
139                 if (crtc->funcs->late_register)
140                         ret = crtc->funcs->late_register(crtc);
141                 if (ret)
142                         return ret;
143         }
144
145         return 0;
146 }
147
148 void drm_crtc_unregister_all(struct drm_device *dev)
149 {
150         struct drm_crtc *crtc;
151
152         drm_for_each_crtc(crtc, dev) {
153                 if (crtc->funcs->early_unregister)
154                         crtc->funcs->early_unregister(crtc);
155                 drm_debugfs_crtc_remove(crtc);
156         }
157 }
158
159 static int drm_crtc_crc_init(struct drm_crtc *crtc)
160 {
161 #ifdef CONFIG_DEBUG_FS
162         spin_lock_init(&crtc->crc.lock);
163         init_waitqueue_head(&crtc->crc.wq);
164         crtc->crc.source = kstrdup("auto", GFP_KERNEL);
165         if (!crtc->crc.source)
166                 return -ENOMEM;
167 #endif
168         return 0;
169 }
170
171 static void drm_crtc_crc_fini(struct drm_crtc *crtc)
172 {
173 #ifdef CONFIG_DEBUG_FS
174         kfree(crtc->crc.source);
175 #endif
176 }
177
178 static const struct dma_fence_ops drm_crtc_fence_ops;
179
180 static struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
181 {
182         BUG_ON(fence->ops != &drm_crtc_fence_ops);
183         return container_of(fence->lock, struct drm_crtc, fence_lock);
184 }
185
186 static const char *drm_crtc_fence_get_driver_name(struct dma_fence *fence)
187 {
188         struct drm_crtc *crtc = fence_to_crtc(fence);
189
190         return crtc->dev->driver->name;
191 }
192
193 static const char *drm_crtc_fence_get_timeline_name(struct dma_fence *fence)
194 {
195         struct drm_crtc *crtc = fence_to_crtc(fence);
196
197         return crtc->timeline_name;
198 }
199
200 static bool drm_crtc_fence_enable_signaling(struct dma_fence *fence)
201 {
202         return true;
203 }
204
205 static const struct dma_fence_ops drm_crtc_fence_ops = {
206         .get_driver_name = drm_crtc_fence_get_driver_name,
207         .get_timeline_name = drm_crtc_fence_get_timeline_name,
208         .enable_signaling = drm_crtc_fence_enable_signaling,
209         .wait = dma_fence_default_wait,
210 };
211
212 struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
213 {
214         struct dma_fence *fence;
215
216         fence = kzalloc(sizeof(*fence), GFP_KERNEL);
217         if (!fence)
218                 return NULL;
219
220         dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock,
221                        crtc->fence_context, ++crtc->fence_seqno);
222
223         return fence;
224 }
225
226 /**
227  * drm_crtc_init_with_planes - Initialise a new CRTC object with
228  *    specified primary and cursor planes.
229  * @dev: DRM device
230  * @crtc: CRTC object to init
231  * @primary: Primary plane for CRTC
232  * @cursor: Cursor plane for CRTC
233  * @funcs: callbacks for the new CRTC
234  * @name: printf style format string for the CRTC name, or NULL for default name
235  *
236  * Inits a new object created as base part of a driver crtc object. Drivers
237  * should use this function instead of drm_crtc_init(), which is only provided
238  * for backwards compatibility with drivers which do not yet support universal
239  * planes). For really simple hardware which has only 1 plane look at
240  * drm_simple_display_pipe_init() instead.
241  *
242  * Returns:
243  * Zero on success, error code on failure.
244  */
245 int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
246                               struct drm_plane *primary,
247                               struct drm_plane *cursor,
248                               const struct drm_crtc_funcs *funcs,
249                               const char *name, ...)
250 {
251         struct drm_mode_config *config = &dev->mode_config;
252         int ret;
253
254         WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
255         WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
256
257         crtc->dev = dev;
258         crtc->funcs = funcs;
259
260         INIT_LIST_HEAD(&crtc->commit_list);
261         spin_lock_init(&crtc->commit_lock);
262
263         drm_modeset_lock_init(&crtc->mutex);
264         ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
265         if (ret)
266                 return ret;
267
268         if (name) {
269                 va_list ap;
270
271                 va_start(ap, name);
272                 crtc->name = kvasprintf(GFP_KERNEL, name, ap);
273                 va_end(ap);
274         } else {
275                 crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
276                                        drm_num_crtcs(dev));
277         }
278         if (!crtc->name) {
279                 drm_mode_object_unregister(dev, &crtc->base);
280                 return -ENOMEM;
281         }
282
283         crtc->fence_context = dma_fence_context_alloc(1);
284         spin_lock_init(&crtc->fence_lock);
285         snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),
286                  "CRTC:%d-%s", crtc->base.id, crtc->name);
287
288         crtc->base.properties = &crtc->properties;
289
290         list_add_tail(&crtc->head, &config->crtc_list);
291         crtc->index = config->num_crtc++;
292
293         crtc->primary = primary;
294         crtc->cursor = cursor;
295         if (primary && !primary->possible_crtcs)
296                 primary->possible_crtcs = 1 << drm_crtc_index(crtc);
297         if (cursor && !cursor->possible_crtcs)
298                 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
299
300         ret = drm_crtc_crc_init(crtc);
301         if (ret) {
302                 drm_mode_object_unregister(dev, &crtc->base);
303                 return ret;
304         }
305
306         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
307                 drm_object_attach_property(&crtc->base, config->prop_active, 0);
308                 drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
309                 drm_object_attach_property(&crtc->base,
310                                            config->prop_out_fence_ptr, 0);
311         }
312
313         return 0;
314 }
315 EXPORT_SYMBOL(drm_crtc_init_with_planes);
316
317 /**
318  * drm_crtc_cleanup - Clean up the core crtc usage
319  * @crtc: CRTC to cleanup
320  *
321  * This function cleans up @crtc and removes it from the DRM mode setting
322  * core. Note that the function does *not* free the crtc structure itself,
323  * this is the responsibility of the caller.
324  */
325 void drm_crtc_cleanup(struct drm_crtc *crtc)
326 {
327         struct drm_device *dev = crtc->dev;
328
329         /* Note that the crtc_list is considered to be static; should we
330          * remove the drm_crtc at runtime we would have to decrement all
331          * the indices on the drm_crtc after us in the crtc_list.
332          */
333
334         drm_crtc_crc_fini(crtc);
335
336         kfree(crtc->gamma_store);
337         crtc->gamma_store = NULL;
338
339         drm_modeset_lock_fini(&crtc->mutex);
340
341         drm_mode_object_unregister(dev, &crtc->base);
342         list_del(&crtc->head);
343         dev->mode_config.num_crtc--;
344
345         WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
346         if (crtc->state && crtc->funcs->atomic_destroy_state)
347                 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
348
349         kfree(crtc->name);
350
351         memset(crtc, 0, sizeof(*crtc));
352 }
353 EXPORT_SYMBOL(drm_crtc_cleanup);
354
355 /**
356  * drm_mode_getcrtc - get CRTC configuration
357  * @dev: drm device for the ioctl
358  * @data: data pointer for the ioctl
359  * @file_priv: drm file for the ioctl call
360  *
361  * Construct a CRTC configuration structure to return to the user.
362  *
363  * Called by the user via ioctl.
364  *
365  * Returns:
366  * Zero on success, negative errno on failure.
367  */
368 int drm_mode_getcrtc(struct drm_device *dev,
369                      void *data, struct drm_file *file_priv)
370 {
371         struct drm_mode_crtc *crtc_resp = data;
372         struct drm_crtc *crtc;
373
374         if (!drm_core_check_feature(dev, DRIVER_MODESET))
375                 return -EINVAL;
376
377         crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
378         if (!crtc)
379                 return -ENOENT;
380
381         drm_modeset_lock_crtc(crtc, crtc->primary);
382         crtc_resp->gamma_size = crtc->gamma_size;
383
384         if (crtc->primary->state && crtc->primary->state->fb)
385                 crtc_resp->fb_id = crtc->primary->state->fb->base.id;
386         else if (!crtc->primary->state && crtc->primary->fb)
387                 crtc_resp->fb_id = crtc->primary->fb->base.id;
388         else
389                 crtc_resp->fb_id = 0;
390
391         if (crtc->state) {
392                 crtc_resp->x = crtc->primary->state->src_x >> 16;
393                 crtc_resp->y = crtc->primary->state->src_y >> 16;
394                 if (crtc->state->enable) {
395                         drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
396                         crtc_resp->mode_valid = 1;
397
398                 } else {
399                         crtc_resp->mode_valid = 0;
400                 }
401         } else {
402                 crtc_resp->x = crtc->x;
403                 crtc_resp->y = crtc->y;
404                 if (crtc->enabled) {
405                         drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
406                         crtc_resp->mode_valid = 1;
407
408                 } else {
409                         crtc_resp->mode_valid = 0;
410                 }
411         }
412         drm_modeset_unlock_crtc(crtc);
413
414         return 0;
415 }
416
417 /**
418  * drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
419  * @set: modeset config to set
420  *
421  * This is a little helper to wrap internal calls to the
422  * &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
423  * correct refcounting dance.
424  *
425  * Returns:
426  * Zero on success, negative errno on failure.
427  */
428 int drm_mode_set_config_internal(struct drm_mode_set *set)
429 {
430         struct drm_crtc *crtc = set->crtc;
431         struct drm_framebuffer *fb;
432         struct drm_crtc *tmp;
433         int ret;
434
435         /*
436          * NOTE: ->set_config can also disable other crtcs (if we steal all
437          * connectors from it), hence we need to refcount the fbs across all
438          * crtcs. Atomic modeset will have saner semantics ...
439          */
440         drm_for_each_crtc(tmp, crtc->dev)
441                 tmp->primary->old_fb = tmp->primary->fb;
442
443         fb = set->fb;
444
445         ret = crtc->funcs->set_config(set);
446         if (ret == 0) {
447                 crtc->primary->crtc = crtc;
448                 crtc->primary->fb = fb;
449         }
450
451         drm_for_each_crtc(tmp, crtc->dev) {
452                 if (tmp->primary->fb)
453                         drm_framebuffer_reference(tmp->primary->fb);
454                 if (tmp->primary->old_fb)
455                         drm_framebuffer_unreference(tmp->primary->old_fb);
456                 tmp->primary->old_fb = NULL;
457         }
458
459         return ret;
460 }
461 EXPORT_SYMBOL(drm_mode_set_config_internal);
462
463 /**
464  * drm_crtc_get_hv_timing - Fetches hdisplay/vdisplay for given mode
465  * @mode: mode to query
466  * @hdisplay: hdisplay value to fill in
467  * @vdisplay: vdisplay value to fill in
468  *
469  * The vdisplay value will be doubled if the specified mode is a stereo mode of
470  * the appropriate layout.
471  */
472 void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
473                             int *hdisplay, int *vdisplay)
474 {
475         struct drm_display_mode adjusted;
476
477         drm_mode_copy(&adjusted, mode);
478         drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE_ONLY);
479         *hdisplay = adjusted.crtc_hdisplay;
480         *vdisplay = adjusted.crtc_vdisplay;
481 }
482 EXPORT_SYMBOL(drm_crtc_get_hv_timing);
483
484 /**
485  * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
486  *     CRTC viewport
487  * @crtc: CRTC that framebuffer will be displayed on
488  * @x: x panning
489  * @y: y panning
490  * @mode: mode that framebuffer will be displayed under
491  * @fb: framebuffer to check size of
492  */
493 int drm_crtc_check_viewport(const struct drm_crtc *crtc,
494                             int x, int y,
495                             const struct drm_display_mode *mode,
496                             const struct drm_framebuffer *fb)
497
498 {
499         int hdisplay, vdisplay;
500
501         drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
502
503         if (crtc->state &&
504             drm_rotation_90_or_270(crtc->primary->state->rotation))
505                 swap(hdisplay, vdisplay);
506
507         return drm_framebuffer_check_src_coords(x << 16, y << 16,
508                                                 hdisplay << 16, vdisplay << 16,
509                                                 fb);
510 }
511 EXPORT_SYMBOL(drm_crtc_check_viewport);
512
513 /**
514  * drm_mode_setcrtc - set CRTC configuration
515  * @dev: drm device for the ioctl
516  * @data: data pointer for the ioctl
517  * @file_priv: drm file for the ioctl call
518  *
519  * Build a new CRTC configuration based on user request.
520  *
521  * Called by the user via ioctl.
522  *
523  * Returns:
524  * Zero on success, negative errno on failure.
525  */
526 int drm_mode_setcrtc(struct drm_device *dev, void *data,
527                      struct drm_file *file_priv)
528 {
529         struct drm_mode_config *config = &dev->mode_config;
530         struct drm_mode_crtc *crtc_req = data;
531         struct drm_crtc *crtc;
532         struct drm_connector **connector_set = NULL, *connector;
533         struct drm_framebuffer *fb = NULL;
534         struct drm_display_mode *mode = NULL;
535         struct drm_mode_set set;
536         uint32_t __user *set_connectors_ptr;
537         int ret;
538         int i;
539
540         if (!drm_core_check_feature(dev, DRIVER_MODESET))
541                 return -EINVAL;
542
543         /*
544          * Universal plane src offsets are only 16.16, prevent havoc for
545          * drivers using universal plane code internally.
546          */
547         if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
548                 return -ERANGE;
549
550         drm_modeset_lock_all(dev);
551         crtc = drm_crtc_find(dev, crtc_req->crtc_id);
552         if (!crtc) {
553                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
554                 ret = -ENOENT;
555                 goto out;
556         }
557         DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
558
559         if (crtc_req->mode_valid) {
560                 /* If we have a mode we need a framebuffer. */
561                 /* If we pass -1, set the mode with the currently bound fb */
562                 if (crtc_req->fb_id == -1) {
563                         if (!crtc->primary->fb) {
564                                 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
565                                 ret = -EINVAL;
566                                 goto out;
567                         }
568                         fb = crtc->primary->fb;
569                         /* Make refcounting symmetric with the lookup path. */
570                         drm_framebuffer_reference(fb);
571                 } else {
572                         fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
573                         if (!fb) {
574                                 DRM_DEBUG_KMS("Unknown FB ID%d\n",
575                                                 crtc_req->fb_id);
576                                 ret = -ENOENT;
577                                 goto out;
578                         }
579                 }
580
581                 mode = drm_mode_create(dev);
582                 if (!mode) {
583                         ret = -ENOMEM;
584                         goto out;
585                 }
586
587                 ret = drm_mode_convert_umode(mode, &crtc_req->mode);
588                 if (ret) {
589                         DRM_DEBUG_KMS("Invalid mode\n");
590                         goto out;
591                 }
592
593                 /*
594                  * Check whether the primary plane supports the fb pixel format.
595                  * Drivers not implementing the universal planes API use a
596                  * default formats list provided by the DRM core which doesn't
597                  * match real hardware capabilities. Skip the check in that
598                  * case.
599                  */
600                 if (!crtc->primary->format_default) {
601                         ret = drm_plane_check_pixel_format(crtc->primary,
602                                                            fb->format->format);
603                         if (ret) {
604                                 struct drm_format_name_buf format_name;
605                                 DRM_DEBUG_KMS("Invalid pixel format %s\n",
606                                               drm_get_format_name(fb->format->format,
607                                                                   &format_name));
608                                 goto out;
609                         }
610                 }
611
612                 ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
613                                               mode, fb);
614                 if (ret)
615                         goto out;
616
617         }
618
619         if (crtc_req->count_connectors == 0 && mode) {
620                 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
621                 ret = -EINVAL;
622                 goto out;
623         }
624
625         if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
626                 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
627                           crtc_req->count_connectors);
628                 ret = -EINVAL;
629                 goto out;
630         }
631
632         if (crtc_req->count_connectors > 0) {
633                 u32 out_id;
634
635                 /* Avoid unbounded kernel memory allocation */
636                 if (crtc_req->count_connectors > config->num_connector) {
637                         ret = -EINVAL;
638                         goto out;
639                 }
640
641                 connector_set = kmalloc_array(crtc_req->count_connectors,
642                                               sizeof(struct drm_connector *),
643                                               GFP_KERNEL);
644                 if (!connector_set) {
645                         ret = -ENOMEM;
646                         goto out;
647                 }
648
649                 for (i = 0; i < crtc_req->count_connectors; i++) {
650                         connector_set[i] = NULL;
651                         set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
652                         if (get_user(out_id, &set_connectors_ptr[i])) {
653                                 ret = -EFAULT;
654                                 goto out;
655                         }
656
657                         connector = drm_connector_lookup(dev, out_id);
658                         if (!connector) {
659                                 DRM_DEBUG_KMS("Connector id %d unknown\n",
660                                                 out_id);
661                                 ret = -ENOENT;
662                                 goto out;
663                         }
664                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
665                                         connector->base.id,
666                                         connector->name);
667
668                         connector_set[i] = connector;
669                 }
670         }
671
672         set.crtc = crtc;
673         set.x = crtc_req->x;
674         set.y = crtc_req->y;
675         set.mode = mode;
676         set.connectors = connector_set;
677         set.num_connectors = crtc_req->count_connectors;
678         set.fb = fb;
679         ret = drm_mode_set_config_internal(&set);
680
681 out:
682         if (fb)
683                 drm_framebuffer_unreference(fb);
684
685         if (connector_set) {
686                 for (i = 0; i < crtc_req->count_connectors; i++) {
687                         if (connector_set[i])
688                                 drm_connector_unreference(connector_set[i]);
689                 }
690         }
691         kfree(connector_set);
692         drm_mode_destroy(dev, mode);
693         drm_modeset_unlock_all(dev);
694         return ret;
695 }
696
697 int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
698                                struct drm_property *property,
699                                uint64_t value)
700 {
701         int ret = -EINVAL;
702         struct drm_crtc *crtc = obj_to_crtc(obj);
703
704         if (crtc->funcs->set_property)
705                 ret = crtc->funcs->set_property(crtc, property, value);
706         if (!ret)
707                 drm_object_property_set_value(obj, property, value);
708
709         return ret;
710 }