3ac81019ae6fd0e241b4c87a2207a548da80bebe
[linux-2.6-block.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 <drm/drmP.h>
37 #include <drm/drm_crtc.h>
38 #include <drm/drm_edid.h>
39 #include <drm/drm_fourcc.h>
40 #include <drm/drm_modeset_lock.h>
41 #include <drm/drm_atomic.h>
42 #include <drm/drm_auth.h>
43 #include <drm/drm_framebuffer.h>
44
45 #include "drm_crtc_internal.h"
46 #include "drm_internal.h"
47
48 /*
49  * Global properties
50  */
51 static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
52         { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
53         { DRM_PLANE_TYPE_PRIMARY, "Primary" },
54         { DRM_PLANE_TYPE_CURSOR, "Cursor" },
55 };
56
57 /*
58  * Optional properties
59  */
60 /**
61  * drm_crtc_force_disable - Forcibly turn off a CRTC
62  * @crtc: CRTC to turn off
63  *
64  * Returns:
65  * Zero on success, error code on failure.
66  */
67 int drm_crtc_force_disable(struct drm_crtc *crtc)
68 {
69         struct drm_mode_set set = {
70                 .crtc = crtc,
71         };
72
73         return drm_mode_set_config_internal(&set);
74 }
75 EXPORT_SYMBOL(drm_crtc_force_disable);
76
77 /**
78  * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs
79  * @dev: DRM device whose CRTCs to turn off
80  *
81  * Drivers may want to call this on unload to ensure that all displays are
82  * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
83  *
84  * Returns:
85  * Zero on success, error code on failure.
86  */
87 int drm_crtc_force_disable_all(struct drm_device *dev)
88 {
89         struct drm_crtc *crtc;
90         int ret = 0;
91
92         drm_modeset_lock_all(dev);
93         drm_for_each_crtc(crtc, dev)
94                 if (crtc->enabled) {
95                         ret = drm_crtc_force_disable(crtc);
96                         if (ret)
97                                 goto out;
98                 }
99 out:
100         drm_modeset_unlock_all(dev);
101         return ret;
102 }
103 EXPORT_SYMBOL(drm_crtc_force_disable_all);
104
105 DEFINE_WW_CLASS(crtc_ww_class);
106
107 static unsigned int drm_num_crtcs(struct drm_device *dev)
108 {
109         unsigned int num = 0;
110         struct drm_crtc *tmp;
111
112         drm_for_each_crtc(tmp, dev) {
113                 num++;
114         }
115
116         return num;
117 }
118
119 static int drm_crtc_register_all(struct drm_device *dev)
120 {
121         struct drm_crtc *crtc;
122         int ret = 0;
123
124         drm_for_each_crtc(crtc, dev) {
125                 if (crtc->funcs->late_register)
126                         ret = crtc->funcs->late_register(crtc);
127                 if (ret)
128                         return ret;
129         }
130
131         return 0;
132 }
133
134 static void drm_crtc_unregister_all(struct drm_device *dev)
135 {
136         struct drm_crtc *crtc;
137
138         drm_for_each_crtc(crtc, dev) {
139                 if (crtc->funcs->early_unregister)
140                         crtc->funcs->early_unregister(crtc);
141         }
142 }
143
144 /**
145  * drm_crtc_init_with_planes - Initialise a new CRTC object with
146  *    specified primary and cursor planes.
147  * @dev: DRM device
148  * @crtc: CRTC object to init
149  * @primary: Primary plane for CRTC
150  * @cursor: Cursor plane for CRTC
151  * @funcs: callbacks for the new CRTC
152  * @name: printf style format string for the CRTC name, or NULL for default name
153  *
154  * Inits a new object created as base part of a driver crtc object. Drivers
155  * should use this function instead of drm_crtc_init(), which is only provided
156  * for backwards compatibility with drivers which do not yet support universal
157  * planes). For really simple hardware which has only 1 plane look at
158  * drm_simple_display_pipe_init() instead.
159  *
160  * Returns:
161  * Zero on success, error code on failure.
162  */
163 int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
164                               struct drm_plane *primary,
165                               struct drm_plane *cursor,
166                               const struct drm_crtc_funcs *funcs,
167                               const char *name, ...)
168 {
169         struct drm_mode_config *config = &dev->mode_config;
170         int ret;
171
172         WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
173         WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
174
175         crtc->dev = dev;
176         crtc->funcs = funcs;
177
178         INIT_LIST_HEAD(&crtc->commit_list);
179         spin_lock_init(&crtc->commit_lock);
180
181         drm_modeset_lock_init(&crtc->mutex);
182         ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
183         if (ret)
184                 return ret;
185
186         if (name) {
187                 va_list ap;
188
189                 va_start(ap, name);
190                 crtc->name = kvasprintf(GFP_KERNEL, name, ap);
191                 va_end(ap);
192         } else {
193                 crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
194                                        drm_num_crtcs(dev));
195         }
196         if (!crtc->name) {
197                 drm_mode_object_unregister(dev, &crtc->base);
198                 return -ENOMEM;
199         }
200
201         crtc->base.properties = &crtc->properties;
202
203         list_add_tail(&crtc->head, &config->crtc_list);
204         crtc->index = config->num_crtc++;
205
206         crtc->primary = primary;
207         crtc->cursor = cursor;
208         if (primary)
209                 primary->possible_crtcs = 1 << drm_crtc_index(crtc);
210         if (cursor)
211                 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
212
213         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
214                 drm_object_attach_property(&crtc->base, config->prop_active, 0);
215                 drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
216         }
217
218         return 0;
219 }
220 EXPORT_SYMBOL(drm_crtc_init_with_planes);
221
222 /**
223  * drm_crtc_cleanup - Clean up the core crtc usage
224  * @crtc: CRTC to cleanup
225  *
226  * This function cleans up @crtc and removes it from the DRM mode setting
227  * core. Note that the function does *not* free the crtc structure itself,
228  * this is the responsibility of the caller.
229  */
230 void drm_crtc_cleanup(struct drm_crtc *crtc)
231 {
232         struct drm_device *dev = crtc->dev;
233
234         /* Note that the crtc_list is considered to be static; should we
235          * remove the drm_crtc at runtime we would have to decrement all
236          * the indices on the drm_crtc after us in the crtc_list.
237          */
238
239         kfree(crtc->gamma_store);
240         crtc->gamma_store = NULL;
241
242         drm_modeset_lock_fini(&crtc->mutex);
243
244         drm_mode_object_unregister(dev, &crtc->base);
245         list_del(&crtc->head);
246         dev->mode_config.num_crtc--;
247
248         WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
249         if (crtc->state && crtc->funcs->atomic_destroy_state)
250                 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
251
252         kfree(crtc->name);
253
254         memset(crtc, 0, sizeof(*crtc));
255 }
256 EXPORT_SYMBOL(drm_crtc_cleanup);
257
258 int drm_modeset_register_all(struct drm_device *dev)
259 {
260         int ret;
261
262         ret = drm_plane_register_all(dev);
263         if (ret)
264                 goto err_plane;
265
266         ret = drm_crtc_register_all(dev);
267         if  (ret)
268                 goto err_crtc;
269
270         ret = drm_encoder_register_all(dev);
271         if (ret)
272                 goto err_encoder;
273
274         ret = drm_connector_register_all(dev);
275         if (ret)
276                 goto err_connector;
277
278         return 0;
279
280 err_connector:
281         drm_encoder_unregister_all(dev);
282 err_encoder:
283         drm_crtc_unregister_all(dev);
284 err_crtc:
285         drm_plane_unregister_all(dev);
286 err_plane:
287         return ret;
288 }
289
290 void drm_modeset_unregister_all(struct drm_device *dev)
291 {
292         drm_connector_unregister_all(dev);
293         drm_encoder_unregister_all(dev);
294         drm_crtc_unregister_all(dev);
295         drm_plane_unregister_all(dev);
296 }
297
298 static int drm_mode_create_standard_properties(struct drm_device *dev)
299 {
300         struct drm_property *prop;
301         int ret;
302
303         ret = drm_connector_create_standard_properties(dev);
304         if (ret)
305                 return ret;
306
307         prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
308                                         "type", drm_plane_type_enum_list,
309                                         ARRAY_SIZE(drm_plane_type_enum_list));
310         if (!prop)
311                 return -ENOMEM;
312         dev->mode_config.plane_type_property = prop;
313
314         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
315                         "SRC_X", 0, UINT_MAX);
316         if (!prop)
317                 return -ENOMEM;
318         dev->mode_config.prop_src_x = prop;
319
320         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
321                         "SRC_Y", 0, UINT_MAX);
322         if (!prop)
323                 return -ENOMEM;
324         dev->mode_config.prop_src_y = prop;
325
326         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
327                         "SRC_W", 0, UINT_MAX);
328         if (!prop)
329                 return -ENOMEM;
330         dev->mode_config.prop_src_w = prop;
331
332         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
333                         "SRC_H", 0, UINT_MAX);
334         if (!prop)
335                 return -ENOMEM;
336         dev->mode_config.prop_src_h = prop;
337
338         prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
339                         "CRTC_X", INT_MIN, INT_MAX);
340         if (!prop)
341                 return -ENOMEM;
342         dev->mode_config.prop_crtc_x = prop;
343
344         prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
345                         "CRTC_Y", INT_MIN, INT_MAX);
346         if (!prop)
347                 return -ENOMEM;
348         dev->mode_config.prop_crtc_y = prop;
349
350         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
351                         "CRTC_W", 0, INT_MAX);
352         if (!prop)
353                 return -ENOMEM;
354         dev->mode_config.prop_crtc_w = prop;
355
356         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
357                         "CRTC_H", 0, INT_MAX);
358         if (!prop)
359                 return -ENOMEM;
360         dev->mode_config.prop_crtc_h = prop;
361
362         prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
363                         "FB_ID", DRM_MODE_OBJECT_FB);
364         if (!prop)
365                 return -ENOMEM;
366         dev->mode_config.prop_fb_id = prop;
367
368         prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
369                         "CRTC_ID", DRM_MODE_OBJECT_CRTC);
370         if (!prop)
371                 return -ENOMEM;
372         dev->mode_config.prop_crtc_id = prop;
373
374         prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
375                         "ACTIVE");
376         if (!prop)
377                 return -ENOMEM;
378         dev->mode_config.prop_active = prop;
379
380         prop = drm_property_create(dev,
381                         DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
382                         "MODE_ID", 0);
383         if (!prop)
384                 return -ENOMEM;
385         dev->mode_config.prop_mode_id = prop;
386
387         prop = drm_property_create(dev,
388                         DRM_MODE_PROP_BLOB,
389                         "DEGAMMA_LUT", 0);
390         if (!prop)
391                 return -ENOMEM;
392         dev->mode_config.degamma_lut_property = prop;
393
394         prop = drm_property_create_range(dev,
395                         DRM_MODE_PROP_IMMUTABLE,
396                         "DEGAMMA_LUT_SIZE", 0, UINT_MAX);
397         if (!prop)
398                 return -ENOMEM;
399         dev->mode_config.degamma_lut_size_property = prop;
400
401         prop = drm_property_create(dev,
402                         DRM_MODE_PROP_BLOB,
403                         "CTM", 0);
404         if (!prop)
405                 return -ENOMEM;
406         dev->mode_config.ctm_property = prop;
407
408         prop = drm_property_create(dev,
409                         DRM_MODE_PROP_BLOB,
410                         "GAMMA_LUT", 0);
411         if (!prop)
412                 return -ENOMEM;
413         dev->mode_config.gamma_lut_property = prop;
414
415         prop = drm_property_create_range(dev,
416                         DRM_MODE_PROP_IMMUTABLE,
417                         "GAMMA_LUT_SIZE", 0, UINT_MAX);
418         if (!prop)
419                 return -ENOMEM;
420         dev->mode_config.gamma_lut_size_property = prop;
421
422         return 0;
423 }
424
425 /**
426  * drm_mode_getresources - get graphics configuration
427  * @dev: drm device for the ioctl
428  * @data: data pointer for the ioctl
429  * @file_priv: drm file for the ioctl call
430  *
431  * Construct a set of configuration description structures and return
432  * them to the user, including CRTC, connector and framebuffer configuration.
433  *
434  * Called by the user via ioctl.
435  *
436  * Returns:
437  * Zero on success, negative errno on failure.
438  */
439 int drm_mode_getresources(struct drm_device *dev, void *data,
440                           struct drm_file *file_priv)
441 {
442         struct drm_mode_card_res *card_res = data;
443         struct list_head *lh;
444         struct drm_framebuffer *fb;
445         struct drm_connector *connector;
446         struct drm_crtc *crtc;
447         struct drm_encoder *encoder;
448         int ret = 0;
449         int connector_count = 0;
450         int crtc_count = 0;
451         int fb_count = 0;
452         int encoder_count = 0;
453         int copied = 0;
454         uint32_t __user *fb_id;
455         uint32_t __user *crtc_id;
456         uint32_t __user *connector_id;
457         uint32_t __user *encoder_id;
458
459         if (!drm_core_check_feature(dev, DRIVER_MODESET))
460                 return -EINVAL;
461
462
463         mutex_lock(&file_priv->fbs_lock);
464         /*
465          * For the non-control nodes we need to limit the list of resources
466          * by IDs in the group list for this node
467          */
468         list_for_each(lh, &file_priv->fbs)
469                 fb_count++;
470
471         /* handle this in 4 parts */
472         /* FBs */
473         if (card_res->count_fbs >= fb_count) {
474                 copied = 0;
475                 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
476                 list_for_each_entry(fb, &file_priv->fbs, filp_head) {
477                         if (put_user(fb->base.id, fb_id + copied)) {
478                                 mutex_unlock(&file_priv->fbs_lock);
479                                 return -EFAULT;
480                         }
481                         copied++;
482                 }
483         }
484         card_res->count_fbs = fb_count;
485         mutex_unlock(&file_priv->fbs_lock);
486
487         /* mode_config.mutex protects the connector list against e.g. DP MST
488          * connector hot-adding. CRTC/Plane lists are invariant. */
489         mutex_lock(&dev->mode_config.mutex);
490         drm_for_each_crtc(crtc, dev)
491                 crtc_count++;
492
493         drm_for_each_connector(connector, dev)
494                 connector_count++;
495
496         drm_for_each_encoder(encoder, dev)
497                 encoder_count++;
498
499         card_res->max_height = dev->mode_config.max_height;
500         card_res->min_height = dev->mode_config.min_height;
501         card_res->max_width = dev->mode_config.max_width;
502         card_res->min_width = dev->mode_config.min_width;
503
504         /* CRTCs */
505         if (card_res->count_crtcs >= crtc_count) {
506                 copied = 0;
507                 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
508                 drm_for_each_crtc(crtc, dev) {
509                         if (put_user(crtc->base.id, crtc_id + copied)) {
510                                 ret = -EFAULT;
511                                 goto out;
512                         }
513                         copied++;
514                 }
515         }
516         card_res->count_crtcs = crtc_count;
517
518         /* Encoders */
519         if (card_res->count_encoders >= encoder_count) {
520                 copied = 0;
521                 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
522                 drm_for_each_encoder(encoder, dev) {
523                         if (put_user(encoder->base.id, encoder_id +
524                                      copied)) {
525                                 ret = -EFAULT;
526                                 goto out;
527                         }
528                         copied++;
529                 }
530         }
531         card_res->count_encoders = encoder_count;
532
533         /* Connectors */
534         if (card_res->count_connectors >= connector_count) {
535                 copied = 0;
536                 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
537                 drm_for_each_connector(connector, dev) {
538                         if (put_user(connector->base.id,
539                                      connector_id + copied)) {
540                                 ret = -EFAULT;
541                                 goto out;
542                         }
543                         copied++;
544                 }
545         }
546         card_res->count_connectors = connector_count;
547
548 out:
549         mutex_unlock(&dev->mode_config.mutex);
550         return ret;
551 }
552
553 /**
554  * drm_mode_getcrtc - get CRTC configuration
555  * @dev: drm device for the ioctl
556  * @data: data pointer for the ioctl
557  * @file_priv: drm file for the ioctl call
558  *
559  * Construct a CRTC configuration structure to return to the user.
560  *
561  * Called by the user via ioctl.
562  *
563  * Returns:
564  * Zero on success, negative errno on failure.
565  */
566 int drm_mode_getcrtc(struct drm_device *dev,
567                      void *data, struct drm_file *file_priv)
568 {
569         struct drm_mode_crtc *crtc_resp = data;
570         struct drm_crtc *crtc;
571
572         if (!drm_core_check_feature(dev, DRIVER_MODESET))
573                 return -EINVAL;
574
575         crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
576         if (!crtc)
577                 return -ENOENT;
578
579         drm_modeset_lock_crtc(crtc, crtc->primary);
580         crtc_resp->gamma_size = crtc->gamma_size;
581         if (crtc->primary->fb)
582                 crtc_resp->fb_id = crtc->primary->fb->base.id;
583         else
584                 crtc_resp->fb_id = 0;
585
586         if (crtc->state) {
587                 crtc_resp->x = crtc->primary->state->src_x >> 16;
588                 crtc_resp->y = crtc->primary->state->src_y >> 16;
589                 if (crtc->state->enable) {
590                         drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
591                         crtc_resp->mode_valid = 1;
592
593                 } else {
594                         crtc_resp->mode_valid = 0;
595                 }
596         } else {
597                 crtc_resp->x = crtc->x;
598                 crtc_resp->y = crtc->y;
599                 if (crtc->enabled) {
600                         drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
601                         crtc_resp->mode_valid = 1;
602
603                 } else {
604                         crtc_resp->mode_valid = 0;
605                 }
606         }
607         drm_modeset_unlock_crtc(crtc);
608
609         return 0;
610 }
611
612 /**
613  * drm_mode_set_config_internal - helper to call ->set_config
614  * @set: modeset config to set
615  *
616  * This is a little helper to wrap internal calls to the ->set_config driver
617  * interface. The only thing it adds is correct refcounting dance.
618  *
619  * Returns:
620  * Zero on success, negative errno on failure.
621  */
622 int drm_mode_set_config_internal(struct drm_mode_set *set)
623 {
624         struct drm_crtc *crtc = set->crtc;
625         struct drm_framebuffer *fb;
626         struct drm_crtc *tmp;
627         int ret;
628
629         /*
630          * NOTE: ->set_config can also disable other crtcs (if we steal all
631          * connectors from it), hence we need to refcount the fbs across all
632          * crtcs. Atomic modeset will have saner semantics ...
633          */
634         drm_for_each_crtc(tmp, crtc->dev)
635                 tmp->primary->old_fb = tmp->primary->fb;
636
637         fb = set->fb;
638
639         ret = crtc->funcs->set_config(set);
640         if (ret == 0) {
641                 crtc->primary->crtc = crtc;
642                 crtc->primary->fb = fb;
643         }
644
645         drm_for_each_crtc(tmp, crtc->dev) {
646                 if (tmp->primary->fb)
647                         drm_framebuffer_reference(tmp->primary->fb);
648                 if (tmp->primary->old_fb)
649                         drm_framebuffer_unreference(tmp->primary->old_fb);
650                 tmp->primary->old_fb = NULL;
651         }
652
653         return ret;
654 }
655 EXPORT_SYMBOL(drm_mode_set_config_internal);
656
657 /**
658  * drm_crtc_get_hv_timing - Fetches hdisplay/vdisplay for given mode
659  * @mode: mode to query
660  * @hdisplay: hdisplay value to fill in
661  * @vdisplay: vdisplay value to fill in
662  *
663  * The vdisplay value will be doubled if the specified mode is a stereo mode of
664  * the appropriate layout.
665  */
666 void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
667                             int *hdisplay, int *vdisplay)
668 {
669         struct drm_display_mode adjusted;
670
671         drm_mode_copy(&adjusted, mode);
672         drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE_ONLY);
673         *hdisplay = adjusted.crtc_hdisplay;
674         *vdisplay = adjusted.crtc_vdisplay;
675 }
676 EXPORT_SYMBOL(drm_crtc_get_hv_timing);
677
678 /**
679  * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
680  *     CRTC viewport
681  * @crtc: CRTC that framebuffer will be displayed on
682  * @x: x panning
683  * @y: y panning
684  * @mode: mode that framebuffer will be displayed under
685  * @fb: framebuffer to check size of
686  */
687 int drm_crtc_check_viewport(const struct drm_crtc *crtc,
688                             int x, int y,
689                             const struct drm_display_mode *mode,
690                             const struct drm_framebuffer *fb)
691
692 {
693         int hdisplay, vdisplay;
694
695         drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
696
697         if (crtc->state &&
698             crtc->primary->state->rotation & (DRM_ROTATE_90 |
699                                               DRM_ROTATE_270))
700                 swap(hdisplay, vdisplay);
701
702         return drm_framebuffer_check_src_coords(x << 16, y << 16,
703                                                 hdisplay << 16, vdisplay << 16,
704                                                 fb);
705 }
706 EXPORT_SYMBOL(drm_crtc_check_viewport);
707
708 /**
709  * drm_mode_setcrtc - set CRTC configuration
710  * @dev: drm device for the ioctl
711  * @data: data pointer for the ioctl
712  * @file_priv: drm file for the ioctl call
713  *
714  * Build a new CRTC configuration based on user request.
715  *
716  * Called by the user via ioctl.
717  *
718  * Returns:
719  * Zero on success, negative errno on failure.
720  */
721 int drm_mode_setcrtc(struct drm_device *dev, void *data,
722                      struct drm_file *file_priv)
723 {
724         struct drm_mode_config *config = &dev->mode_config;
725         struct drm_mode_crtc *crtc_req = data;
726         struct drm_crtc *crtc;
727         struct drm_connector **connector_set = NULL, *connector;
728         struct drm_framebuffer *fb = NULL;
729         struct drm_display_mode *mode = NULL;
730         struct drm_mode_set set;
731         uint32_t __user *set_connectors_ptr;
732         int ret;
733         int i;
734
735         if (!drm_core_check_feature(dev, DRIVER_MODESET))
736                 return -EINVAL;
737
738         /*
739          * Universal plane src offsets are only 16.16, prevent havoc for
740          * drivers using universal plane code internally.
741          */
742         if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
743                 return -ERANGE;
744
745         drm_modeset_lock_all(dev);
746         crtc = drm_crtc_find(dev, crtc_req->crtc_id);
747         if (!crtc) {
748                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
749                 ret = -ENOENT;
750                 goto out;
751         }
752         DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
753
754         if (crtc_req->mode_valid) {
755                 /* If we have a mode we need a framebuffer. */
756                 /* If we pass -1, set the mode with the currently bound fb */
757                 if (crtc_req->fb_id == -1) {
758                         if (!crtc->primary->fb) {
759                                 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
760                                 ret = -EINVAL;
761                                 goto out;
762                         }
763                         fb = crtc->primary->fb;
764                         /* Make refcounting symmetric with the lookup path. */
765                         drm_framebuffer_reference(fb);
766                 } else {
767                         fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
768                         if (!fb) {
769                                 DRM_DEBUG_KMS("Unknown FB ID%d\n",
770                                                 crtc_req->fb_id);
771                                 ret = -ENOENT;
772                                 goto out;
773                         }
774                 }
775
776                 mode = drm_mode_create(dev);
777                 if (!mode) {
778                         ret = -ENOMEM;
779                         goto out;
780                 }
781
782                 ret = drm_mode_convert_umode(mode, &crtc_req->mode);
783                 if (ret) {
784                         DRM_DEBUG_KMS("Invalid mode\n");
785                         goto out;
786                 }
787
788                 /*
789                  * Check whether the primary plane supports the fb pixel format.
790                  * Drivers not implementing the universal planes API use a
791                  * default formats list provided by the DRM core which doesn't
792                  * match real hardware capabilities. Skip the check in that
793                  * case.
794                  */
795                 if (!crtc->primary->format_default) {
796                         ret = drm_plane_check_pixel_format(crtc->primary,
797                                                            fb->pixel_format);
798                         if (ret) {
799                                 char *format_name = drm_get_format_name(fb->pixel_format);
800                                 DRM_DEBUG_KMS("Invalid pixel format %s\n", format_name);
801                                 kfree(format_name);
802                                 goto out;
803                         }
804                 }
805
806                 ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
807                                               mode, fb);
808                 if (ret)
809                         goto out;
810
811         }
812
813         if (crtc_req->count_connectors == 0 && mode) {
814                 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
815                 ret = -EINVAL;
816                 goto out;
817         }
818
819         if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
820                 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
821                           crtc_req->count_connectors);
822                 ret = -EINVAL;
823                 goto out;
824         }
825
826         if (crtc_req->count_connectors > 0) {
827                 u32 out_id;
828
829                 /* Avoid unbounded kernel memory allocation */
830                 if (crtc_req->count_connectors > config->num_connector) {
831                         ret = -EINVAL;
832                         goto out;
833                 }
834
835                 connector_set = kmalloc_array(crtc_req->count_connectors,
836                                               sizeof(struct drm_connector *),
837                                               GFP_KERNEL);
838                 if (!connector_set) {
839                         ret = -ENOMEM;
840                         goto out;
841                 }
842
843                 for (i = 0; i < crtc_req->count_connectors; i++) {
844                         connector_set[i] = NULL;
845                         set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
846                         if (get_user(out_id, &set_connectors_ptr[i])) {
847                                 ret = -EFAULT;
848                                 goto out;
849                         }
850
851                         connector = drm_connector_lookup(dev, out_id);
852                         if (!connector) {
853                                 DRM_DEBUG_KMS("Connector id %d unknown\n",
854                                                 out_id);
855                                 ret = -ENOENT;
856                                 goto out;
857                         }
858                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
859                                         connector->base.id,
860                                         connector->name);
861
862                         connector_set[i] = connector;
863                 }
864         }
865
866         set.crtc = crtc;
867         set.x = crtc_req->x;
868         set.y = crtc_req->y;
869         set.mode = mode;
870         set.connectors = connector_set;
871         set.num_connectors = crtc_req->count_connectors;
872         set.fb = fb;
873         ret = drm_mode_set_config_internal(&set);
874
875 out:
876         if (fb)
877                 drm_framebuffer_unreference(fb);
878
879         if (connector_set) {
880                 for (i = 0; i < crtc_req->count_connectors; i++) {
881                         if (connector_set[i])
882                                 drm_connector_unreference(connector_set[i]);
883                 }
884         }
885         kfree(connector_set);
886         drm_mode_destroy(dev, mode);
887         drm_modeset_unlock_all(dev);
888         return ret;
889 }
890
891 int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
892                                struct drm_property *property,
893                                uint64_t value)
894 {
895         int ret = -EINVAL;
896         struct drm_crtc *crtc = obj_to_crtc(obj);
897
898         if (crtc->funcs->set_property)
899                 ret = crtc->funcs->set_property(crtc, property, value);
900         if (!ret)
901                 drm_object_property_set_value(obj, property, value);
902
903         return ret;
904 }
905
906 /**
907  * drm_mode_crtc_set_gamma_size - set the gamma table size
908  * @crtc: CRTC to set the gamma table size for
909  * @gamma_size: size of the gamma table
910  *
911  * Drivers which support gamma tables should set this to the supported gamma
912  * table size when initializing the CRTC. Currently the drm core only supports a
913  * fixed gamma table size.
914  *
915  * Returns:
916  * Zero on success, negative errno on failure.
917  */
918 int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
919                                  int gamma_size)
920 {
921         uint16_t *r_base, *g_base, *b_base;
922         int i;
923
924         crtc->gamma_size = gamma_size;
925
926         crtc->gamma_store = kcalloc(gamma_size, sizeof(uint16_t) * 3,
927                                     GFP_KERNEL);
928         if (!crtc->gamma_store) {
929                 crtc->gamma_size = 0;
930                 return -ENOMEM;
931         }
932
933         r_base = crtc->gamma_store;
934         g_base = r_base + gamma_size;
935         b_base = g_base + gamma_size;
936         for (i = 0; i < gamma_size; i++) {
937                 r_base[i] = i << 8;
938                 g_base[i] = i << 8;
939                 b_base[i] = i << 8;
940         }
941
942
943         return 0;
944 }
945 EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
946
947 /**
948  * drm_mode_gamma_set_ioctl - set the gamma table
949  * @dev: DRM device
950  * @data: ioctl data
951  * @file_priv: DRM file info
952  *
953  * Set the gamma table of a CRTC to the one passed in by the user. Userspace can
954  * inquire the required gamma table size through drm_mode_gamma_get_ioctl.
955  *
956  * Called by the user via ioctl.
957  *
958  * Returns:
959  * Zero on success, negative errno on failure.
960  */
961 int drm_mode_gamma_set_ioctl(struct drm_device *dev,
962                              void *data, struct drm_file *file_priv)
963 {
964         struct drm_mode_crtc_lut *crtc_lut = data;
965         struct drm_crtc *crtc;
966         void *r_base, *g_base, *b_base;
967         int size;
968         int ret = 0;
969
970         if (!drm_core_check_feature(dev, DRIVER_MODESET))
971                 return -EINVAL;
972
973         drm_modeset_lock_all(dev);
974         crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
975         if (!crtc) {
976                 ret = -ENOENT;
977                 goto out;
978         }
979
980         if (crtc->funcs->gamma_set == NULL) {
981                 ret = -ENOSYS;
982                 goto out;
983         }
984
985         /* memcpy into gamma store */
986         if (crtc_lut->gamma_size != crtc->gamma_size) {
987                 ret = -EINVAL;
988                 goto out;
989         }
990
991         size = crtc_lut->gamma_size * (sizeof(uint16_t));
992         r_base = crtc->gamma_store;
993         if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
994                 ret = -EFAULT;
995                 goto out;
996         }
997
998         g_base = r_base + size;
999         if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
1000                 ret = -EFAULT;
1001                 goto out;
1002         }
1003
1004         b_base = g_base + size;
1005         if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
1006                 ret = -EFAULT;
1007                 goto out;
1008         }
1009
1010         ret = crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
1011
1012 out:
1013         drm_modeset_unlock_all(dev);
1014         return ret;
1015
1016 }
1017
1018 /**
1019  * drm_mode_gamma_get_ioctl - get the gamma table
1020  * @dev: DRM device
1021  * @data: ioctl data
1022  * @file_priv: DRM file info
1023  *
1024  * Copy the current gamma table into the storage provided. This also provides
1025  * the gamma table size the driver expects, which can be used to size the
1026  * allocated storage.
1027  *
1028  * Called by the user via ioctl.
1029  *
1030  * Returns:
1031  * Zero on success, negative errno on failure.
1032  */
1033 int drm_mode_gamma_get_ioctl(struct drm_device *dev,
1034                              void *data, struct drm_file *file_priv)
1035 {
1036         struct drm_mode_crtc_lut *crtc_lut = data;
1037         struct drm_crtc *crtc;
1038         void *r_base, *g_base, *b_base;
1039         int size;
1040         int ret = 0;
1041
1042         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1043                 return -EINVAL;
1044
1045         drm_modeset_lock_all(dev);
1046         crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
1047         if (!crtc) {
1048                 ret = -ENOENT;
1049                 goto out;
1050         }
1051
1052         /* memcpy into gamma store */
1053         if (crtc_lut->gamma_size != crtc->gamma_size) {
1054                 ret = -EINVAL;
1055                 goto out;
1056         }
1057
1058         size = crtc_lut->gamma_size * (sizeof(uint16_t));
1059         r_base = crtc->gamma_store;
1060         if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
1061                 ret = -EFAULT;
1062                 goto out;
1063         }
1064
1065         g_base = r_base + size;
1066         if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
1067                 ret = -EFAULT;
1068                 goto out;
1069         }
1070
1071         b_base = g_base + size;
1072         if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
1073                 ret = -EFAULT;
1074                 goto out;
1075         }
1076 out:
1077         drm_modeset_unlock_all(dev);
1078         return ret;
1079 }
1080
1081 /**
1082  * drm_mode_config_reset - call ->reset callbacks
1083  * @dev: drm device
1084  *
1085  * This functions calls all the crtc's, encoder's and connector's ->reset
1086  * callback. Drivers can use this in e.g. their driver load or resume code to
1087  * reset hardware and software state.
1088  */
1089 void drm_mode_config_reset(struct drm_device *dev)
1090 {
1091         struct drm_crtc *crtc;
1092         struct drm_plane *plane;
1093         struct drm_encoder *encoder;
1094         struct drm_connector *connector;
1095
1096         drm_for_each_plane(plane, dev)
1097                 if (plane->funcs->reset)
1098                         plane->funcs->reset(plane);
1099
1100         drm_for_each_crtc(crtc, dev)
1101                 if (crtc->funcs->reset)
1102                         crtc->funcs->reset(crtc);
1103
1104         drm_for_each_encoder(encoder, dev)
1105                 if (encoder->funcs->reset)
1106                         encoder->funcs->reset(encoder);
1107
1108         mutex_lock(&dev->mode_config.mutex);
1109         drm_for_each_connector(connector, dev)
1110                 if (connector->funcs->reset)
1111                         connector->funcs->reset(connector);
1112         mutex_unlock(&dev->mode_config.mutex);
1113 }
1114 EXPORT_SYMBOL(drm_mode_config_reset);
1115
1116 /**
1117  * drm_mode_create_dumb_ioctl - create a dumb backing storage buffer
1118  * @dev: DRM device
1119  * @data: ioctl data
1120  * @file_priv: DRM file info
1121  *
1122  * This creates a new dumb buffer in the driver's backing storage manager (GEM,
1123  * TTM or something else entirely) and returns the resulting buffer handle. This
1124  * handle can then be wrapped up into a framebuffer modeset object.
1125  *
1126  * Note that userspace is not allowed to use such objects for render
1127  * acceleration - drivers must create their own private ioctls for such a use
1128  * case.
1129  *
1130  * Called by the user via ioctl.
1131  *
1132  * Returns:
1133  * Zero on success, negative errno on failure.
1134  */
1135 int drm_mode_create_dumb_ioctl(struct drm_device *dev,
1136                                void *data, struct drm_file *file_priv)
1137 {
1138         struct drm_mode_create_dumb *args = data;
1139         u32 cpp, stride, size;
1140
1141         if (!dev->driver->dumb_create)
1142                 return -ENOSYS;
1143         if (!args->width || !args->height || !args->bpp)
1144                 return -EINVAL;
1145
1146         /* overflow checks for 32bit size calculations */
1147         /* NOTE: DIV_ROUND_UP() can overflow */
1148         cpp = DIV_ROUND_UP(args->bpp, 8);
1149         if (!cpp || cpp > 0xffffffffU / args->width)
1150                 return -EINVAL;
1151         stride = cpp * args->width;
1152         if (args->height > 0xffffffffU / stride)
1153                 return -EINVAL;
1154
1155         /* test for wrap-around */
1156         size = args->height * stride;
1157         if (PAGE_ALIGN(size) == 0)
1158                 return -EINVAL;
1159
1160         /*
1161          * handle, pitch and size are output parameters. Zero them out to
1162          * prevent drivers from accidentally using uninitialized data. Since
1163          * not all existing userspace is clearing these fields properly we
1164          * cannot reject IOCTL with garbage in them.
1165          */
1166         args->handle = 0;
1167         args->pitch = 0;
1168         args->size = 0;
1169
1170         return dev->driver->dumb_create(file_priv, dev, args);
1171 }
1172
1173 /**
1174  * drm_mode_mmap_dumb_ioctl - create an mmap offset for a dumb backing storage buffer
1175  * @dev: DRM device
1176  * @data: ioctl data
1177  * @file_priv: DRM file info
1178  *
1179  * Allocate an offset in the drm device node's address space to be able to
1180  * memory map a dumb buffer.
1181  *
1182  * Called by the user via ioctl.
1183  *
1184  * Returns:
1185  * Zero on success, negative errno on failure.
1186  */
1187 int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
1188                              void *data, struct drm_file *file_priv)
1189 {
1190         struct drm_mode_map_dumb *args = data;
1191
1192         /* call driver ioctl to get mmap offset */
1193         if (!dev->driver->dumb_map_offset)
1194                 return -ENOSYS;
1195
1196         return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
1197 }
1198
1199 /**
1200  * drm_mode_destroy_dumb_ioctl - destroy a dumb backing strage buffer
1201  * @dev: DRM device
1202  * @data: ioctl data
1203  * @file_priv: DRM file info
1204  *
1205  * This destroys the userspace handle for the given dumb backing storage buffer.
1206  * Since buffer objects must be reference counted in the kernel a buffer object
1207  * won't be immediately freed if a framebuffer modeset object still uses it.
1208  *
1209  * Called by the user via ioctl.
1210  *
1211  * Returns:
1212  * Zero on success, negative errno on failure.
1213  */
1214 int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
1215                                 void *data, struct drm_file *file_priv)
1216 {
1217         struct drm_mode_destroy_dumb *args = data;
1218
1219         if (!dev->driver->dumb_destroy)
1220                 return -ENOSYS;
1221
1222         return dev->driver->dumb_destroy(file_priv, dev, args->handle);
1223 }
1224
1225 /**
1226  * drm_mode_config_init - initialize DRM mode_configuration structure
1227  * @dev: DRM device
1228  *
1229  * Initialize @dev's mode_config structure, used for tracking the graphics
1230  * configuration of @dev.
1231  *
1232  * Since this initializes the modeset locks, no locking is possible. Which is no
1233  * problem, since this should happen single threaded at init time. It is the
1234  * driver's problem to ensure this guarantee.
1235  *
1236  */
1237 void drm_mode_config_init(struct drm_device *dev)
1238 {
1239         mutex_init(&dev->mode_config.mutex);
1240         drm_modeset_lock_init(&dev->mode_config.connection_mutex);
1241         mutex_init(&dev->mode_config.idr_mutex);
1242         mutex_init(&dev->mode_config.fb_lock);
1243         mutex_init(&dev->mode_config.blob_lock);
1244         INIT_LIST_HEAD(&dev->mode_config.fb_list);
1245         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
1246         INIT_LIST_HEAD(&dev->mode_config.connector_list);
1247         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
1248         INIT_LIST_HEAD(&dev->mode_config.property_list);
1249         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
1250         INIT_LIST_HEAD(&dev->mode_config.plane_list);
1251         idr_init(&dev->mode_config.crtc_idr);
1252         idr_init(&dev->mode_config.tile_idr);
1253         ida_init(&dev->mode_config.connector_ida);
1254
1255         drm_modeset_lock_all(dev);
1256         drm_mode_create_standard_properties(dev);
1257         drm_modeset_unlock_all(dev);
1258
1259         /* Just to be sure */
1260         dev->mode_config.num_fb = 0;
1261         dev->mode_config.num_connector = 0;
1262         dev->mode_config.num_crtc = 0;
1263         dev->mode_config.num_encoder = 0;
1264         dev->mode_config.num_overlay_plane = 0;
1265         dev->mode_config.num_total_plane = 0;
1266 }
1267 EXPORT_SYMBOL(drm_mode_config_init);
1268
1269 /**
1270  * drm_mode_config_cleanup - free up DRM mode_config info
1271  * @dev: DRM device
1272  *
1273  * Free up all the connectors and CRTCs associated with this DRM device, then
1274  * free up the framebuffers and associated buffer objects.
1275  *
1276  * Note that since this /should/ happen single-threaded at driver/device
1277  * teardown time, no locking is required. It's the driver's job to ensure that
1278  * this guarantee actually holds true.
1279  *
1280  * FIXME: cleanup any dangling user buffer objects too
1281  */
1282 void drm_mode_config_cleanup(struct drm_device *dev)
1283 {
1284         struct drm_connector *connector, *ot;
1285         struct drm_crtc *crtc, *ct;
1286         struct drm_encoder *encoder, *enct;
1287         struct drm_framebuffer *fb, *fbt;
1288         struct drm_property *property, *pt;
1289         struct drm_property_blob *blob, *bt;
1290         struct drm_plane *plane, *plt;
1291
1292         list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
1293                                  head) {
1294                 encoder->funcs->destroy(encoder);
1295         }
1296
1297         list_for_each_entry_safe(connector, ot,
1298                                  &dev->mode_config.connector_list, head) {
1299                 connector->funcs->destroy(connector);
1300         }
1301
1302         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
1303                                  head) {
1304                 drm_property_destroy(dev, property);
1305         }
1306
1307         list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
1308                                  head) {
1309                 plane->funcs->destroy(plane);
1310         }
1311
1312         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
1313                 crtc->funcs->destroy(crtc);
1314         }
1315
1316         list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
1317                                  head_global) {
1318                 drm_property_unreference_blob(blob);
1319         }
1320
1321         /*
1322          * Single-threaded teardown context, so it's not required to grab the
1323          * fb_lock to protect against concurrent fb_list access. Contrary, it
1324          * would actually deadlock with the drm_framebuffer_cleanup function.
1325          *
1326          * Also, if there are any framebuffers left, that's a driver leak now,
1327          * so politely WARN about this.
1328          */
1329         WARN_ON(!list_empty(&dev->mode_config.fb_list));
1330         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
1331                 drm_framebuffer_free(&fb->base.refcount);
1332         }
1333
1334         ida_destroy(&dev->mode_config.connector_ida);
1335         idr_destroy(&dev->mode_config.tile_idr);
1336         idr_destroy(&dev->mode_config.crtc_idr);
1337         drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
1338 }
1339 EXPORT_SYMBOL(drm_mode_config_cleanup);
1340
1341 /**
1342  * DOC: Tile group
1343  *
1344  * Tile groups are used to represent tiled monitors with a unique
1345  * integer identifier. Tiled monitors using DisplayID v1.3 have
1346  * a unique 8-byte handle, we store this in a tile group, so we
1347  * have a common identifier for all tiles in a monitor group.
1348  */
1349 static void drm_tile_group_free(struct kref *kref)
1350 {
1351         struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
1352         struct drm_device *dev = tg->dev;
1353         mutex_lock(&dev->mode_config.idr_mutex);
1354         idr_remove(&dev->mode_config.tile_idr, tg->id);
1355         mutex_unlock(&dev->mode_config.idr_mutex);
1356         kfree(tg);
1357 }
1358
1359 /**
1360  * drm_mode_put_tile_group - drop a reference to a tile group.
1361  * @dev: DRM device
1362  * @tg: tile group to drop reference to.
1363  *
1364  * drop reference to tile group and free if 0.
1365  */
1366 void drm_mode_put_tile_group(struct drm_device *dev,
1367                              struct drm_tile_group *tg)
1368 {
1369         kref_put(&tg->refcount, drm_tile_group_free);
1370 }
1371
1372 /**
1373  * drm_mode_get_tile_group - get a reference to an existing tile group
1374  * @dev: DRM device
1375  * @topology: 8-bytes unique per monitor.
1376  *
1377  * Use the unique bytes to get a reference to an existing tile group.
1378  *
1379  * RETURNS:
1380  * tile group or NULL if not found.
1381  */
1382 struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
1383                                                char topology[8])
1384 {
1385         struct drm_tile_group *tg;
1386         int id;
1387         mutex_lock(&dev->mode_config.idr_mutex);
1388         idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
1389                 if (!memcmp(tg->group_data, topology, 8)) {
1390                         if (!kref_get_unless_zero(&tg->refcount))
1391                                 tg = NULL;
1392                         mutex_unlock(&dev->mode_config.idr_mutex);
1393                         return tg;
1394                 }
1395         }
1396         mutex_unlock(&dev->mode_config.idr_mutex);
1397         return NULL;
1398 }
1399 EXPORT_SYMBOL(drm_mode_get_tile_group);
1400
1401 /**
1402  * drm_mode_create_tile_group - create a tile group from a displayid description
1403  * @dev: DRM device
1404  * @topology: 8-bytes unique per monitor.
1405  *
1406  * Create a tile group for the unique monitor, and get a unique
1407  * identifier for the tile group.
1408  *
1409  * RETURNS:
1410  * new tile group or error.
1411  */
1412 struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
1413                                                   char topology[8])
1414 {
1415         struct drm_tile_group *tg;
1416         int ret;
1417
1418         tg = kzalloc(sizeof(*tg), GFP_KERNEL);
1419         if (!tg)
1420                 return ERR_PTR(-ENOMEM);
1421
1422         kref_init(&tg->refcount);
1423         memcpy(tg->group_data, topology, 8);
1424         tg->dev = dev;
1425
1426         mutex_lock(&dev->mode_config.idr_mutex);
1427         ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
1428         if (ret >= 0) {
1429                 tg->id = ret;
1430         } else {
1431                 kfree(tg);
1432                 tg = ERR_PTR(ret);
1433         }
1434
1435         mutex_unlock(&dev->mode_config.idr_mutex);
1436         return tg;
1437 }
1438 EXPORT_SYMBOL(drm_mode_create_tile_group);
1439
1440 /**
1441  * drm_crtc_enable_color_mgmt - enable color management properties
1442  * @crtc: DRM CRTC
1443  * @degamma_lut_size: the size of the degamma lut (before CSC)
1444  * @has_ctm: whether to attach ctm_property for CSC matrix
1445  * @gamma_lut_size: the size of the gamma lut (after CSC)
1446  *
1447  * This function lets the driver enable the color correction
1448  * properties on a CRTC. This includes 3 degamma, csc and gamma
1449  * properties that userspace can set and 2 size properties to inform
1450  * the userspace of the lut sizes. Each of the properties are
1451  * optional. The gamma and degamma properties are only attached if
1452  * their size is not 0 and ctm_property is only attached if has_ctm is
1453  * true.
1454  */
1455 void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
1456                                 uint degamma_lut_size,
1457                                 bool has_ctm,
1458                                 uint gamma_lut_size)
1459 {
1460         struct drm_device *dev = crtc->dev;
1461         struct drm_mode_config *config = &dev->mode_config;
1462
1463         if (degamma_lut_size) {
1464                 drm_object_attach_property(&crtc->base,
1465                                            config->degamma_lut_property, 0);
1466                 drm_object_attach_property(&crtc->base,
1467                                            config->degamma_lut_size_property,
1468                                            degamma_lut_size);
1469         }
1470
1471         if (has_ctm)
1472                 drm_object_attach_property(&crtc->base,
1473                                            config->ctm_property, 0);
1474
1475         if (gamma_lut_size) {
1476                 drm_object_attach_property(&crtc->base,
1477                                            config->gamma_lut_property, 0);
1478                 drm_object_attach_property(&crtc->base,
1479                                            config->gamma_lut_size_property,
1480                                            gamma_lut_size);
1481         }
1482 }
1483 EXPORT_SYMBOL(drm_crtc_enable_color_mgmt);