]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/drm_crtc.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch
[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/list.h>
33 #include <linux/slab.h>
34 #include <linux/export.h>
35 #include <drm/drmP.h>
36 #include <drm/drm_crtc.h>
37 #include <drm/drm_edid.h>
38 #include <drm/drm_fourcc.h>
39
40 /**
41  * drm_modeset_lock_all - take all modeset locks
42  * @dev: drm device
43  *
44  * This function takes all modeset locks, suitable where a more fine-grained
45  * scheme isn't (yet) implemented.
46  */
47 void drm_modeset_lock_all(struct drm_device *dev)
48 {
49         struct drm_crtc *crtc;
50
51         mutex_lock(&dev->mode_config.mutex);
52
53         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
54                 mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex);
55 }
56 EXPORT_SYMBOL(drm_modeset_lock_all);
57
58 /**
59  * drm_modeset_unlock_all - drop all modeset locks
60  * @dev: device
61  */
62 void drm_modeset_unlock_all(struct drm_device *dev)
63 {
64         struct drm_crtc *crtc;
65
66         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
67                 mutex_unlock(&crtc->mutex);
68
69         mutex_unlock(&dev->mode_config.mutex);
70 }
71 EXPORT_SYMBOL(drm_modeset_unlock_all);
72
73 /**
74  * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked
75  * @dev: device
76  */
77 void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
78 {
79         struct drm_crtc *crtc;
80
81         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
82                 WARN_ON(!mutex_is_locked(&crtc->mutex));
83
84         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
85 }
86 EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked);
87
88 /* Avoid boilerplate.  I'm tired of typing. */
89 #define DRM_ENUM_NAME_FN(fnname, list)                          \
90         char *fnname(int val)                                   \
91         {                                                       \
92                 int i;                                          \
93                 for (i = 0; i < ARRAY_SIZE(list); i++) {        \
94                         if (list[i].type == val)                \
95                                 return list[i].name;            \
96                 }                                               \
97                 return "(unknown)";                             \
98         }
99
100 /*
101  * Global properties
102  */
103 static struct drm_prop_enum_list drm_dpms_enum_list[] =
104 {       { DRM_MODE_DPMS_ON, "On" },
105         { DRM_MODE_DPMS_STANDBY, "Standby" },
106         { DRM_MODE_DPMS_SUSPEND, "Suspend" },
107         { DRM_MODE_DPMS_OFF, "Off" }
108 };
109
110 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
111
112 /*
113  * Optional properties
114  */
115 static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
116 {
117         { DRM_MODE_SCALE_NONE, "None" },
118         { DRM_MODE_SCALE_FULLSCREEN, "Full" },
119         { DRM_MODE_SCALE_CENTER, "Center" },
120         { DRM_MODE_SCALE_ASPECT, "Full aspect" },
121 };
122
123 static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
124 {
125         { DRM_MODE_DITHERING_OFF, "Off" },
126         { DRM_MODE_DITHERING_ON, "On" },
127         { DRM_MODE_DITHERING_AUTO, "Automatic" },
128 };
129
130 /*
131  * Non-global properties, but "required" for certain connectors.
132  */
133 static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
134 {
135         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
136         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
137         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
138 };
139
140 DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
141
142 static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
143 {
144         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
145         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
146         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
147 };
148
149 DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
150                  drm_dvi_i_subconnector_enum_list)
151
152 static struct drm_prop_enum_list drm_tv_select_enum_list[] =
153 {
154         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
155         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
156         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
157         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
158         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
159 };
160
161 DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
162
163 static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
164 {
165         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
166         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
167         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
168         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
169         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
170 };
171
172 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
173                  drm_tv_subconnector_enum_list)
174
175 static struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
176         { DRM_MODE_DIRTY_OFF,      "Off"      },
177         { DRM_MODE_DIRTY_ON,       "On"       },
178         { DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
179 };
180
181 DRM_ENUM_NAME_FN(drm_get_dirty_info_name,
182                  drm_dirty_info_enum_list)
183
184 struct drm_conn_prop_enum_list {
185         int type;
186         char *name;
187         int count;
188 };
189
190 /*
191  * Connector and encoder types.
192  */
193 static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
194 {       { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
195         { DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
196         { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
197         { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
198         { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
199         { DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
200         { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
201         { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
202         { DRM_MODE_CONNECTOR_Component, "Component", 0 },
203         { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
204         { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
205         { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
206         { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
207         { DRM_MODE_CONNECTOR_TV, "TV", 0 },
208         { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
209         { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0},
210 };
211
212 static struct drm_prop_enum_list drm_encoder_enum_list[] =
213 {       { DRM_MODE_ENCODER_NONE, "None" },
214         { DRM_MODE_ENCODER_DAC, "DAC" },
215         { DRM_MODE_ENCODER_TMDS, "TMDS" },
216         { DRM_MODE_ENCODER_LVDS, "LVDS" },
217         { DRM_MODE_ENCODER_TVDAC, "TV" },
218         { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
219 };
220
221 char *drm_get_encoder_name(struct drm_encoder *encoder)
222 {
223         static char buf[32];
224
225         snprintf(buf, 32, "%s-%d",
226                  drm_encoder_enum_list[encoder->encoder_type].name,
227                  encoder->base.id);
228         return buf;
229 }
230 EXPORT_SYMBOL(drm_get_encoder_name);
231
232 char *drm_get_connector_name(struct drm_connector *connector)
233 {
234         static char buf[32];
235
236         snprintf(buf, 32, "%s-%d",
237                  drm_connector_enum_list[connector->connector_type].name,
238                  connector->connector_type_id);
239         return buf;
240 }
241 EXPORT_SYMBOL(drm_get_connector_name);
242
243 char *drm_get_connector_status_name(enum drm_connector_status status)
244 {
245         if (status == connector_status_connected)
246                 return "connected";
247         else if (status == connector_status_disconnected)
248                 return "disconnected";
249         else
250                 return "unknown";
251 }
252
253 /**
254  * drm_mode_object_get - allocate a new modeset identifier
255  * @dev: DRM device
256  * @obj: object pointer, used to generate unique ID
257  * @obj_type: object type
258  *
259  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
260  * for tracking modes, CRTCs and connectors.
261  *
262  * RETURNS:
263  * New unique (relative to other objects in @dev) integer identifier for the
264  * object.
265  */
266 static int drm_mode_object_get(struct drm_device *dev,
267                                struct drm_mode_object *obj, uint32_t obj_type)
268 {
269         int ret;
270
271         mutex_lock(&dev->mode_config.idr_mutex);
272         ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL);
273         if (ret >= 0) {
274                 /*
275                  * Set up the object linking under the protection of the idr
276                  * lock so that other users can't see inconsistent state.
277                  */
278                 obj->id = ret;
279                 obj->type = obj_type;
280         }
281         mutex_unlock(&dev->mode_config.idr_mutex);
282
283         return ret < 0 ? ret : 0;
284 }
285
286 /**
287  * drm_mode_object_put - free a modeset identifer
288  * @dev: DRM device
289  * @object: object to free
290  *
291  * Free @id from @dev's unique identifier pool.
292  */
293 static void drm_mode_object_put(struct drm_device *dev,
294                                 struct drm_mode_object *object)
295 {
296         mutex_lock(&dev->mode_config.idr_mutex);
297         idr_remove(&dev->mode_config.crtc_idr, object->id);
298         mutex_unlock(&dev->mode_config.idr_mutex);
299 }
300
301 /**
302  * drm_mode_object_find - look up a drm object with static lifetime
303  * @dev: drm device
304  * @id: id of the mode object
305  * @type: type of the mode object
306  *
307  * Note that framebuffers cannot be looked up with this functions - since those
308  * are reference counted, they need special treatment.
309  */
310 struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
311                 uint32_t id, uint32_t type)
312 {
313         struct drm_mode_object *obj = NULL;
314
315         /* Framebuffers are reference counted and need their own lookup
316          * function.*/
317         WARN_ON(type == DRM_MODE_OBJECT_FB);
318
319         mutex_lock(&dev->mode_config.idr_mutex);
320         obj = idr_find(&dev->mode_config.crtc_idr, id);
321         if (!obj || (obj->type != type) || (obj->id != id))
322                 obj = NULL;
323         mutex_unlock(&dev->mode_config.idr_mutex);
324
325         return obj;
326 }
327 EXPORT_SYMBOL(drm_mode_object_find);
328
329 /**
330  * drm_framebuffer_init - initialize a framebuffer
331  * @dev: DRM device
332  * @fb: framebuffer to be initialized
333  * @funcs: ... with these functions
334  *
335  * Allocates an ID for the framebuffer's parent mode object, sets its mode
336  * functions & device file and adds it to the master fd list.
337  *
338  * IMPORTANT:
339  * This functions publishes the fb and makes it available for concurrent access
340  * by other users. Which means by this point the fb _must_ be fully set up -
341  * since all the fb attributes are invariant over its lifetime, no further
342  * locking but only correct reference counting is required.
343  *
344  * RETURNS:
345  * Zero on success, error code on failure.
346  */
347 int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
348                          const struct drm_framebuffer_funcs *funcs)
349 {
350         int ret;
351
352         mutex_lock(&dev->mode_config.fb_lock);
353         kref_init(&fb->refcount);
354         INIT_LIST_HEAD(&fb->filp_head);
355         fb->dev = dev;
356         fb->funcs = funcs;
357
358         ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
359         if (ret)
360                 goto out;
361
362         /* Grab the idr reference. */
363         drm_framebuffer_reference(fb);
364
365         dev->mode_config.num_fb++;
366         list_add(&fb->head, &dev->mode_config.fb_list);
367 out:
368         mutex_unlock(&dev->mode_config.fb_lock);
369
370         return 0;
371 }
372 EXPORT_SYMBOL(drm_framebuffer_init);
373
374 static void drm_framebuffer_free(struct kref *kref)
375 {
376         struct drm_framebuffer *fb =
377                         container_of(kref, struct drm_framebuffer, refcount);
378         fb->funcs->destroy(fb);
379 }
380
381 static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev,
382                                                         uint32_t id)
383 {
384         struct drm_mode_object *obj = NULL;
385         struct drm_framebuffer *fb;
386
387         mutex_lock(&dev->mode_config.idr_mutex);
388         obj = idr_find(&dev->mode_config.crtc_idr, id);
389         if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id))
390                 fb = NULL;
391         else
392                 fb = obj_to_fb(obj);
393         mutex_unlock(&dev->mode_config.idr_mutex);
394
395         return fb;
396 }
397
398 /**
399  * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
400  * @dev: drm device
401  * @id: id of the fb object
402  *
403  * If successful, this grabs an additional reference to the framebuffer -
404  * callers need to make sure to eventually unreference the returned framebuffer
405  * again.
406  */
407 struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
408                                                uint32_t id)
409 {
410         struct drm_framebuffer *fb;
411
412         mutex_lock(&dev->mode_config.fb_lock);
413         fb = __drm_framebuffer_lookup(dev, id);
414         if (fb)
415                 kref_get(&fb->refcount);
416         mutex_unlock(&dev->mode_config.fb_lock);
417
418         return fb;
419 }
420 EXPORT_SYMBOL(drm_framebuffer_lookup);
421
422 /**
423  * drm_framebuffer_unreference - unref a framebuffer
424  * @fb: framebuffer to unref
425  *
426  * This functions decrements the fb's refcount and frees it if it drops to zero.
427  */
428 void drm_framebuffer_unreference(struct drm_framebuffer *fb)
429 {
430         DRM_DEBUG("FB ID: %d\n", fb->base.id);
431         kref_put(&fb->refcount, drm_framebuffer_free);
432 }
433 EXPORT_SYMBOL(drm_framebuffer_unreference);
434
435 /**
436  * drm_framebuffer_reference - incr the fb refcnt
437  * @fb: framebuffer
438  */
439 void drm_framebuffer_reference(struct drm_framebuffer *fb)
440 {
441         DRM_DEBUG("FB ID: %d\n", fb->base.id);
442         kref_get(&fb->refcount);
443 }
444 EXPORT_SYMBOL(drm_framebuffer_reference);
445
446 static void drm_framebuffer_free_bug(struct kref *kref)
447 {
448         BUG();
449 }
450
451 static void __drm_framebuffer_unreference(struct drm_framebuffer *fb)
452 {
453         DRM_DEBUG("FB ID: %d\n", fb->base.id);
454         kref_put(&fb->refcount, drm_framebuffer_free_bug);
455 }
456
457 /* dev->mode_config.fb_lock must be held! */
458 static void __drm_framebuffer_unregister(struct drm_device *dev,
459                                          struct drm_framebuffer *fb)
460 {
461         mutex_lock(&dev->mode_config.idr_mutex);
462         idr_remove(&dev->mode_config.crtc_idr, fb->base.id);
463         mutex_unlock(&dev->mode_config.idr_mutex);
464
465         fb->base.id = 0;
466
467         __drm_framebuffer_unreference(fb);
468 }
469
470 /**
471  * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
472  * @fb: fb to unregister
473  *
474  * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
475  * those used for fbdev. Note that the caller must hold a reference of it's own,
476  * i.e. the object may not be destroyed through this call (since it'll lead to a
477  * locking inversion).
478  */
479 void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
480 {
481         struct drm_device *dev = fb->dev;
482
483         mutex_lock(&dev->mode_config.fb_lock);
484         /* Mark fb as reaped and drop idr ref. */
485         __drm_framebuffer_unregister(dev, fb);
486         mutex_unlock(&dev->mode_config.fb_lock);
487 }
488 EXPORT_SYMBOL(drm_framebuffer_unregister_private);
489
490 /**
491  * drm_framebuffer_cleanup - remove a framebuffer object
492  * @fb: framebuffer to remove
493  *
494  * Cleanup references to a user-created framebuffer. This function is intended
495  * to be used from the drivers ->destroy callback.
496  *
497  * Note that this function does not remove the fb from active usuage - if it is
498  * still used anywhere, hilarity can ensue since userspace could call getfb on
499  * the id and get back -EINVAL. Obviously no concern at driver unload time.
500  *
501  * Also, the framebuffer will not be removed from the lookup idr - for
502  * user-created framebuffers this will happen in in the rmfb ioctl. For
503  * driver-private objects (e.g. for fbdev) drivers need to explicitly call
504  * drm_framebuffer_unregister_private.
505  */
506 void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
507 {
508         struct drm_device *dev = fb->dev;
509
510         mutex_lock(&dev->mode_config.fb_lock);
511         list_del(&fb->head);
512         dev->mode_config.num_fb--;
513         mutex_unlock(&dev->mode_config.fb_lock);
514 }
515 EXPORT_SYMBOL(drm_framebuffer_cleanup);
516
517 /**
518  * drm_framebuffer_remove - remove and unreference a framebuffer object
519  * @fb: framebuffer to remove
520  *
521  * Scans all the CRTCs and planes in @dev's mode_config.  If they're
522  * using @fb, removes it, setting it to NULL. Then drops the reference to the
523  * passed-in framebuffer. Might take the modeset locks.
524  *
525  * Note that this function optimizes the cleanup away if the caller holds the
526  * last reference to the framebuffer. It is also guaranteed to not take the
527  * modeset locks in this case.
528  */
529 void drm_framebuffer_remove(struct drm_framebuffer *fb)
530 {
531         struct drm_device *dev = fb->dev;
532         struct drm_crtc *crtc;
533         struct drm_plane *plane;
534         struct drm_mode_set set;
535         int ret;
536
537         WARN_ON(!list_empty(&fb->filp_head));
538
539         /*
540          * drm ABI mandates that we remove any deleted framebuffers from active
541          * useage. But since most sane clients only remove framebuffers they no
542          * longer need, try to optimize this away.
543          *
544          * Since we're holding a reference ourselves, observing a refcount of 1
545          * means that we're the last holder and can skip it. Also, the refcount
546          * can never increase from 1 again, so we don't need any barriers or
547          * locks.
548          *
549          * Note that userspace could try to race with use and instate a new
550          * usage _after_ we've cleared all current ones. End result will be an
551          * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
552          * in this manner.
553          */
554         if (atomic_read(&fb->refcount.refcount) > 1) {
555                 drm_modeset_lock_all(dev);
556                 /* remove from any CRTC */
557                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
558                         if (crtc->fb == fb) {
559                                 /* should turn off the crtc */
560                                 memset(&set, 0, sizeof(struct drm_mode_set));
561                                 set.crtc = crtc;
562                                 set.fb = NULL;
563                                 ret = drm_mode_set_config_internal(&set);
564                                 if (ret)
565                                         DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
566                         }
567                 }
568
569                 list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
570                         if (plane->fb == fb) {
571                                 /* should turn off the crtc */
572                                 ret = plane->funcs->disable_plane(plane);
573                                 if (ret)
574                                         DRM_ERROR("failed to disable plane with busy fb\n");
575                                 /* disconnect the plane from the fb and crtc: */
576                                 __drm_framebuffer_unreference(plane->fb);
577                                 plane->fb = NULL;
578                                 plane->crtc = NULL;
579                         }
580                 }
581                 drm_modeset_unlock_all(dev);
582         }
583
584         drm_framebuffer_unreference(fb);
585 }
586 EXPORT_SYMBOL(drm_framebuffer_remove);
587
588 /**
589  * drm_crtc_init - Initialise a new CRTC object
590  * @dev: DRM device
591  * @crtc: CRTC object to init
592  * @funcs: callbacks for the new CRTC
593  *
594  * Inits a new object created as base part of an driver crtc object.
595  *
596  * RETURNS:
597  * Zero on success, error code on failure.
598  */
599 int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
600                    const struct drm_crtc_funcs *funcs)
601 {
602         int ret;
603
604         crtc->dev = dev;
605         crtc->funcs = funcs;
606         crtc->invert_dimensions = false;
607
608         drm_modeset_lock_all(dev);
609         mutex_init(&crtc->mutex);
610         mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex);
611
612         ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
613         if (ret)
614                 goto out;
615
616         crtc->base.properties = &crtc->properties;
617
618         list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
619         dev->mode_config.num_crtc++;
620
621  out:
622         drm_modeset_unlock_all(dev);
623
624         return ret;
625 }
626 EXPORT_SYMBOL(drm_crtc_init);
627
628 /**
629  * drm_crtc_cleanup - Cleans up the core crtc usage.
630  * @crtc: CRTC to cleanup
631  *
632  * Cleanup @crtc. Removes from drm modesetting space
633  * does NOT free object, caller does that.
634  */
635 void drm_crtc_cleanup(struct drm_crtc *crtc)
636 {
637         struct drm_device *dev = crtc->dev;
638
639         kfree(crtc->gamma_store);
640         crtc->gamma_store = NULL;
641
642         drm_mode_object_put(dev, &crtc->base);
643         list_del(&crtc->head);
644         dev->mode_config.num_crtc--;
645 }
646 EXPORT_SYMBOL(drm_crtc_cleanup);
647
648 /**
649  * drm_mode_probed_add - add a mode to a connector's probed mode list
650  * @connector: connector the new mode
651  * @mode: mode data
652  *
653  * Add @mode to @connector's mode list for later use.
654  */
655 void drm_mode_probed_add(struct drm_connector *connector,
656                          struct drm_display_mode *mode)
657 {
658         list_add(&mode->head, &connector->probed_modes);
659 }
660 EXPORT_SYMBOL(drm_mode_probed_add);
661
662 /**
663  * drm_mode_remove - remove and free a mode
664  * @connector: connector list to modify
665  * @mode: mode to remove
666  *
667  * Remove @mode from @connector's mode list, then free it.
668  */
669 void drm_mode_remove(struct drm_connector *connector,
670                      struct drm_display_mode *mode)
671 {
672         list_del(&mode->head);
673         drm_mode_destroy(connector->dev, mode);
674 }
675 EXPORT_SYMBOL(drm_mode_remove);
676
677 /**
678  * drm_connector_init - Init a preallocated connector
679  * @dev: DRM device
680  * @connector: the connector to init
681  * @funcs: callbacks for this connector
682  * @connector_type: user visible type of the connector
683  *
684  * Initialises a preallocated connector. Connectors should be
685  * subclassed as part of driver connector objects.
686  *
687  * RETURNS:
688  * Zero on success, error code on failure.
689  */
690 int drm_connector_init(struct drm_device *dev,
691                        struct drm_connector *connector,
692                        const struct drm_connector_funcs *funcs,
693                        int connector_type)
694 {
695         int ret;
696
697         drm_modeset_lock_all(dev);
698
699         ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
700         if (ret)
701                 goto out;
702
703         connector->base.properties = &connector->properties;
704         connector->dev = dev;
705         connector->funcs = funcs;
706         connector->connector_type = connector_type;
707         connector->connector_type_id =
708                 ++drm_connector_enum_list[connector_type].count; /* TODO */
709         INIT_LIST_HEAD(&connector->user_modes);
710         INIT_LIST_HEAD(&connector->probed_modes);
711         INIT_LIST_HEAD(&connector->modes);
712         connector->edid_blob_ptr = NULL;
713         connector->status = connector_status_unknown;
714
715         list_add_tail(&connector->head, &dev->mode_config.connector_list);
716         dev->mode_config.num_connector++;
717
718         if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
719                 drm_object_attach_property(&connector->base,
720                                               dev->mode_config.edid_property,
721                                               0);
722
723         drm_object_attach_property(&connector->base,
724                                       dev->mode_config.dpms_property, 0);
725
726  out:
727         drm_modeset_unlock_all(dev);
728
729         return ret;
730 }
731 EXPORT_SYMBOL(drm_connector_init);
732
733 /**
734  * drm_connector_cleanup - cleans up an initialised connector
735  * @connector: connector to cleanup
736  *
737  * Cleans up the connector but doesn't free the object.
738  */
739 void drm_connector_cleanup(struct drm_connector *connector)
740 {
741         struct drm_device *dev = connector->dev;
742         struct drm_display_mode *mode, *t;
743
744         list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
745                 drm_mode_remove(connector, mode);
746
747         list_for_each_entry_safe(mode, t, &connector->modes, head)
748                 drm_mode_remove(connector, mode);
749
750         list_for_each_entry_safe(mode, t, &connector->user_modes, head)
751                 drm_mode_remove(connector, mode);
752
753         drm_mode_object_put(dev, &connector->base);
754         list_del(&connector->head);
755         dev->mode_config.num_connector--;
756 }
757 EXPORT_SYMBOL(drm_connector_cleanup);
758
759 void drm_connector_unplug_all(struct drm_device *dev)
760 {
761         struct drm_connector *connector;
762
763         /* taking the mode config mutex ends up in a clash with sysfs */
764         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
765                 drm_sysfs_connector_remove(connector);
766
767 }
768 EXPORT_SYMBOL(drm_connector_unplug_all);
769
770 int drm_encoder_init(struct drm_device *dev,
771                       struct drm_encoder *encoder,
772                       const struct drm_encoder_funcs *funcs,
773                       int encoder_type)
774 {
775         int ret;
776
777         drm_modeset_lock_all(dev);
778
779         ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
780         if (ret)
781                 goto out;
782
783         encoder->dev = dev;
784         encoder->encoder_type = encoder_type;
785         encoder->funcs = funcs;
786
787         list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
788         dev->mode_config.num_encoder++;
789
790  out:
791         drm_modeset_unlock_all(dev);
792
793         return ret;
794 }
795 EXPORT_SYMBOL(drm_encoder_init);
796
797 void drm_encoder_cleanup(struct drm_encoder *encoder)
798 {
799         struct drm_device *dev = encoder->dev;
800         drm_modeset_lock_all(dev);
801         drm_mode_object_put(dev, &encoder->base);
802         list_del(&encoder->head);
803         dev->mode_config.num_encoder--;
804         drm_modeset_unlock_all(dev);
805 }
806 EXPORT_SYMBOL(drm_encoder_cleanup);
807
808 int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
809                    unsigned long possible_crtcs,
810                    const struct drm_plane_funcs *funcs,
811                    const uint32_t *formats, uint32_t format_count,
812                    bool priv)
813 {
814         int ret;
815
816         drm_modeset_lock_all(dev);
817
818         ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
819         if (ret)
820                 goto out;
821
822         plane->base.properties = &plane->properties;
823         plane->dev = dev;
824         plane->funcs = funcs;
825         plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
826                                       GFP_KERNEL);
827         if (!plane->format_types) {
828                 DRM_DEBUG_KMS("out of memory when allocating plane\n");
829                 drm_mode_object_put(dev, &plane->base);
830                 ret = -ENOMEM;
831                 goto out;
832         }
833
834         memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
835         plane->format_count = format_count;
836         plane->possible_crtcs = possible_crtcs;
837
838         /* private planes are not exposed to userspace, but depending on
839          * display hardware, might be convenient to allow sharing programming
840          * for the scanout engine with the crtc implementation.
841          */
842         if (!priv) {
843                 list_add_tail(&plane->head, &dev->mode_config.plane_list);
844                 dev->mode_config.num_plane++;
845         } else {
846                 INIT_LIST_HEAD(&plane->head);
847         }
848
849  out:
850         drm_modeset_unlock_all(dev);
851
852         return ret;
853 }
854 EXPORT_SYMBOL(drm_plane_init);
855
856 void drm_plane_cleanup(struct drm_plane *plane)
857 {
858         struct drm_device *dev = plane->dev;
859
860         drm_modeset_lock_all(dev);
861         kfree(plane->format_types);
862         drm_mode_object_put(dev, &plane->base);
863         /* if not added to a list, it must be a private plane */
864         if (!list_empty(&plane->head)) {
865                 list_del(&plane->head);
866                 dev->mode_config.num_plane--;
867         }
868         drm_modeset_unlock_all(dev);
869 }
870 EXPORT_SYMBOL(drm_plane_cleanup);
871
872 /**
873  * drm_mode_create - create a new display mode
874  * @dev: DRM device
875  *
876  * Create a new drm_display_mode, give it an ID, and return it.
877  *
878  * RETURNS:
879  * Pointer to new mode on success, NULL on error.
880  */
881 struct drm_display_mode *drm_mode_create(struct drm_device *dev)
882 {
883         struct drm_display_mode *nmode;
884
885         nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
886         if (!nmode)
887                 return NULL;
888
889         if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) {
890                 kfree(nmode);
891                 return NULL;
892         }
893
894         return nmode;
895 }
896 EXPORT_SYMBOL(drm_mode_create);
897
898 /**
899  * drm_mode_destroy - remove a mode
900  * @dev: DRM device
901  * @mode: mode to remove
902  *
903  * Free @mode's unique identifier, then free it.
904  */
905 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
906 {
907         if (!mode)
908                 return;
909
910         drm_mode_object_put(dev, &mode->base);
911
912         kfree(mode);
913 }
914 EXPORT_SYMBOL(drm_mode_destroy);
915
916 static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
917 {
918         struct drm_property *edid;
919         struct drm_property *dpms;
920
921         /*
922          * Standard properties (apply to all connectors)
923          */
924         edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
925                                    DRM_MODE_PROP_IMMUTABLE,
926                                    "EDID", 0);
927         dev->mode_config.edid_property = edid;
928
929         dpms = drm_property_create_enum(dev, 0,
930                                    "DPMS", drm_dpms_enum_list,
931                                    ARRAY_SIZE(drm_dpms_enum_list));
932         dev->mode_config.dpms_property = dpms;
933
934         return 0;
935 }
936
937 /**
938  * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
939  * @dev: DRM device
940  *
941  * Called by a driver the first time a DVI-I connector is made.
942  */
943 int drm_mode_create_dvi_i_properties(struct drm_device *dev)
944 {
945         struct drm_property *dvi_i_selector;
946         struct drm_property *dvi_i_subconnector;
947
948         if (dev->mode_config.dvi_i_select_subconnector_property)
949                 return 0;
950
951         dvi_i_selector =
952                 drm_property_create_enum(dev, 0,
953                                     "select subconnector",
954                                     drm_dvi_i_select_enum_list,
955                                     ARRAY_SIZE(drm_dvi_i_select_enum_list));
956         dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
957
958         dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
959                                     "subconnector",
960                                     drm_dvi_i_subconnector_enum_list,
961                                     ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
962         dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
963
964         return 0;
965 }
966 EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
967
968 /**
969  * drm_create_tv_properties - create TV specific connector properties
970  * @dev: DRM device
971  * @num_modes: number of different TV formats (modes) supported
972  * @modes: array of pointers to strings containing name of each format
973  *
974  * Called by a driver's TV initialization routine, this function creates
975  * the TV specific connector properties for a given device.  Caller is
976  * responsible for allocating a list of format names and passing them to
977  * this routine.
978  */
979 int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
980                                   char *modes[])
981 {
982         struct drm_property *tv_selector;
983         struct drm_property *tv_subconnector;
984         int i;
985
986         if (dev->mode_config.tv_select_subconnector_property)
987                 return 0;
988
989         /*
990          * Basic connector properties
991          */
992         tv_selector = drm_property_create_enum(dev, 0,
993                                           "select subconnector",
994                                           drm_tv_select_enum_list,
995                                           ARRAY_SIZE(drm_tv_select_enum_list));
996         dev->mode_config.tv_select_subconnector_property = tv_selector;
997
998         tv_subconnector =
999                 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1000                                     "subconnector",
1001                                     drm_tv_subconnector_enum_list,
1002                                     ARRAY_SIZE(drm_tv_subconnector_enum_list));
1003         dev->mode_config.tv_subconnector_property = tv_subconnector;
1004
1005         /*
1006          * Other, TV specific properties: margins & TV modes.
1007          */
1008         dev->mode_config.tv_left_margin_property =
1009                 drm_property_create_range(dev, 0, "left margin", 0, 100);
1010
1011         dev->mode_config.tv_right_margin_property =
1012                 drm_property_create_range(dev, 0, "right margin", 0, 100);
1013
1014         dev->mode_config.tv_top_margin_property =
1015                 drm_property_create_range(dev, 0, "top margin", 0, 100);
1016
1017         dev->mode_config.tv_bottom_margin_property =
1018                 drm_property_create_range(dev, 0, "bottom margin", 0, 100);
1019
1020         dev->mode_config.tv_mode_property =
1021                 drm_property_create(dev, DRM_MODE_PROP_ENUM,
1022                                     "mode", num_modes);
1023         for (i = 0; i < num_modes; i++)
1024                 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
1025                                       i, modes[i]);
1026
1027         dev->mode_config.tv_brightness_property =
1028                 drm_property_create_range(dev, 0, "brightness", 0, 100);
1029
1030         dev->mode_config.tv_contrast_property =
1031                 drm_property_create_range(dev, 0, "contrast", 0, 100);
1032
1033         dev->mode_config.tv_flicker_reduction_property =
1034                 drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
1035
1036         dev->mode_config.tv_overscan_property =
1037                 drm_property_create_range(dev, 0, "overscan", 0, 100);
1038
1039         dev->mode_config.tv_saturation_property =
1040                 drm_property_create_range(dev, 0, "saturation", 0, 100);
1041
1042         dev->mode_config.tv_hue_property =
1043                 drm_property_create_range(dev, 0, "hue", 0, 100);
1044
1045         return 0;
1046 }
1047 EXPORT_SYMBOL(drm_mode_create_tv_properties);
1048
1049 /**
1050  * drm_mode_create_scaling_mode_property - create scaling mode property
1051  * @dev: DRM device
1052  *
1053  * Called by a driver the first time it's needed, must be attached to desired
1054  * connectors.
1055  */
1056 int drm_mode_create_scaling_mode_property(struct drm_device *dev)
1057 {
1058         struct drm_property *scaling_mode;
1059
1060         if (dev->mode_config.scaling_mode_property)
1061                 return 0;
1062
1063         scaling_mode =
1064                 drm_property_create_enum(dev, 0, "scaling mode",
1065                                 drm_scaling_mode_enum_list,
1066                                     ARRAY_SIZE(drm_scaling_mode_enum_list));
1067
1068         dev->mode_config.scaling_mode_property = scaling_mode;
1069
1070         return 0;
1071 }
1072 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
1073
1074 /**
1075  * drm_mode_create_dithering_property - create dithering property
1076  * @dev: DRM device
1077  *
1078  * Called by a driver the first time it's needed, must be attached to desired
1079  * connectors.
1080  */
1081 int drm_mode_create_dithering_property(struct drm_device *dev)
1082 {
1083         struct drm_property *dithering_mode;
1084
1085         if (dev->mode_config.dithering_mode_property)
1086                 return 0;
1087
1088         dithering_mode =
1089                 drm_property_create_enum(dev, 0, "dithering",
1090                                 drm_dithering_mode_enum_list,
1091                                     ARRAY_SIZE(drm_dithering_mode_enum_list));
1092         dev->mode_config.dithering_mode_property = dithering_mode;
1093
1094         return 0;
1095 }
1096 EXPORT_SYMBOL(drm_mode_create_dithering_property);
1097
1098 /**
1099  * drm_mode_create_dirty_property - create dirty property
1100  * @dev: DRM device
1101  *
1102  * Called by a driver the first time it's needed, must be attached to desired
1103  * connectors.
1104  */
1105 int drm_mode_create_dirty_info_property(struct drm_device *dev)
1106 {
1107         struct drm_property *dirty_info;
1108
1109         if (dev->mode_config.dirty_info_property)
1110                 return 0;
1111
1112         dirty_info =
1113                 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1114                                     "dirty",
1115                                     drm_dirty_info_enum_list,
1116                                     ARRAY_SIZE(drm_dirty_info_enum_list));
1117         dev->mode_config.dirty_info_property = dirty_info;
1118
1119         return 0;
1120 }
1121 EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
1122
1123 /**
1124  * drm_mode_config_init - initialize DRM mode_configuration structure
1125  * @dev: DRM device
1126  *
1127  * Initialize @dev's mode_config structure, used for tracking the graphics
1128  * configuration of @dev.
1129  *
1130  * Since this initializes the modeset locks, no locking is possible. Which is no
1131  * problem, since this should happen single threaded at init time. It is the
1132  * driver's problem to ensure this guarantee.
1133  *
1134  */
1135 void drm_mode_config_init(struct drm_device *dev)
1136 {
1137         mutex_init(&dev->mode_config.mutex);
1138         mutex_init(&dev->mode_config.idr_mutex);
1139         mutex_init(&dev->mode_config.fb_lock);
1140         INIT_LIST_HEAD(&dev->mode_config.fb_list);
1141         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
1142         INIT_LIST_HEAD(&dev->mode_config.connector_list);
1143         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
1144         INIT_LIST_HEAD(&dev->mode_config.property_list);
1145         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
1146         INIT_LIST_HEAD(&dev->mode_config.plane_list);
1147         idr_init(&dev->mode_config.crtc_idr);
1148
1149         drm_modeset_lock_all(dev);
1150         drm_mode_create_standard_connector_properties(dev);
1151         drm_modeset_unlock_all(dev);
1152
1153         /* Just to be sure */
1154         dev->mode_config.num_fb = 0;
1155         dev->mode_config.num_connector = 0;
1156         dev->mode_config.num_crtc = 0;
1157         dev->mode_config.num_encoder = 0;
1158 }
1159 EXPORT_SYMBOL(drm_mode_config_init);
1160
1161 int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
1162 {
1163         uint32_t total_objects = 0;
1164
1165         total_objects += dev->mode_config.num_crtc;
1166         total_objects += dev->mode_config.num_connector;
1167         total_objects += dev->mode_config.num_encoder;
1168
1169         group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
1170         if (!group->id_list)
1171                 return -ENOMEM;
1172
1173         group->num_crtcs = 0;
1174         group->num_connectors = 0;
1175         group->num_encoders = 0;
1176         return 0;
1177 }
1178
1179 int drm_mode_group_init_legacy_group(struct drm_device *dev,
1180                                      struct drm_mode_group *group)
1181 {
1182         struct drm_crtc *crtc;
1183         struct drm_encoder *encoder;
1184         struct drm_connector *connector;
1185         int ret;
1186
1187         if ((ret = drm_mode_group_init(dev, group)))
1188                 return ret;
1189
1190         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
1191                 group->id_list[group->num_crtcs++] = crtc->base.id;
1192
1193         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
1194                 group->id_list[group->num_crtcs + group->num_encoders++] =
1195                 encoder->base.id;
1196
1197         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
1198                 group->id_list[group->num_crtcs + group->num_encoders +
1199                                group->num_connectors++] = connector->base.id;
1200
1201         return 0;
1202 }
1203 EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
1204
1205 /**
1206  * drm_mode_config_cleanup - free up DRM mode_config info
1207  * @dev: DRM device
1208  *
1209  * Free up all the connectors and CRTCs associated with this DRM device, then
1210  * free up the framebuffers and associated buffer objects.
1211  *
1212  * Note that since this /should/ happen single-threaded at driver/device
1213  * teardown time, no locking is required. It's the driver's job to ensure that
1214  * this guarantee actually holds true.
1215  *
1216  * FIXME: cleanup any dangling user buffer objects too
1217  */
1218 void drm_mode_config_cleanup(struct drm_device *dev)
1219 {
1220         struct drm_connector *connector, *ot;
1221         struct drm_crtc *crtc, *ct;
1222         struct drm_encoder *encoder, *enct;
1223         struct drm_framebuffer *fb, *fbt;
1224         struct drm_property *property, *pt;
1225         struct drm_plane *plane, *plt;
1226
1227         list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
1228                                  head) {
1229                 encoder->funcs->destroy(encoder);
1230         }
1231
1232         list_for_each_entry_safe(connector, ot,
1233                                  &dev->mode_config.connector_list, head) {
1234                 connector->funcs->destroy(connector);
1235         }
1236
1237         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
1238                                  head) {
1239                 drm_property_destroy(dev, property);
1240         }
1241
1242         /*
1243          * Single-threaded teardown context, so it's not required to grab the
1244          * fb_lock to protect against concurrent fb_list access. Contrary, it
1245          * would actually deadlock with the drm_framebuffer_cleanup function.
1246          *
1247          * Also, if there are any framebuffers left, that's a driver leak now,
1248          * so politely WARN about this.
1249          */
1250         WARN_ON(!list_empty(&dev->mode_config.fb_list));
1251         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
1252                 drm_framebuffer_remove(fb);
1253         }
1254
1255         list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
1256                                  head) {
1257                 plane->funcs->destroy(plane);
1258         }
1259
1260         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
1261                 crtc->funcs->destroy(crtc);
1262         }
1263
1264         idr_destroy(&dev->mode_config.crtc_idr);
1265 }
1266 EXPORT_SYMBOL(drm_mode_config_cleanup);
1267
1268 /**
1269  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
1270  * @out: drm_mode_modeinfo struct to return to the user
1271  * @in: drm_display_mode to use
1272  *
1273  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
1274  * the user.
1275  */
1276 static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
1277                                       const struct drm_display_mode *in)
1278 {
1279         WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
1280              in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
1281              in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
1282              in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
1283              in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
1284              "timing values too large for mode info\n");
1285
1286         out->clock = in->clock;
1287         out->hdisplay = in->hdisplay;
1288         out->hsync_start = in->hsync_start;
1289         out->hsync_end = in->hsync_end;
1290         out->htotal = in->htotal;
1291         out->hskew = in->hskew;
1292         out->vdisplay = in->vdisplay;
1293         out->vsync_start = in->vsync_start;
1294         out->vsync_end = in->vsync_end;
1295         out->vtotal = in->vtotal;
1296         out->vscan = in->vscan;
1297         out->vrefresh = in->vrefresh;
1298         out->flags = in->flags;
1299         out->type = in->type;
1300         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1301         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1302 }
1303
1304 /**
1305  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
1306  * @out: drm_display_mode to return to the user
1307  * @in: drm_mode_modeinfo to use
1308  *
1309  * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
1310  * the caller.
1311  *
1312  * RETURNS:
1313  * Zero on success, errno on failure.
1314  */
1315 static int drm_crtc_convert_umode(struct drm_display_mode *out,
1316                                   const struct drm_mode_modeinfo *in)
1317 {
1318         if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
1319                 return -ERANGE;
1320
1321         out->clock = in->clock;
1322         out->hdisplay = in->hdisplay;
1323         out->hsync_start = in->hsync_start;
1324         out->hsync_end = in->hsync_end;
1325         out->htotal = in->htotal;
1326         out->hskew = in->hskew;
1327         out->vdisplay = in->vdisplay;
1328         out->vsync_start = in->vsync_start;
1329         out->vsync_end = in->vsync_end;
1330         out->vtotal = in->vtotal;
1331         out->vscan = in->vscan;
1332         out->vrefresh = in->vrefresh;
1333         out->flags = in->flags;
1334         out->type = in->type;
1335         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1336         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1337
1338         return 0;
1339 }
1340
1341 /**
1342  * drm_mode_getresources - get graphics configuration
1343  * @dev: drm device for the ioctl
1344  * @data: data pointer for the ioctl
1345  * @file_priv: drm file for the ioctl call
1346  *
1347  * Construct a set of configuration description structures and return
1348  * them to the user, including CRTC, connector and framebuffer configuration.
1349  *
1350  * Called by the user via ioctl.
1351  *
1352  * RETURNS:
1353  * Zero on success, errno on failure.
1354  */
1355 int drm_mode_getresources(struct drm_device *dev, void *data,
1356                           struct drm_file *file_priv)
1357 {
1358         struct drm_mode_card_res *card_res = data;
1359         struct list_head *lh;
1360         struct drm_framebuffer *fb;
1361         struct drm_connector *connector;
1362         struct drm_crtc *crtc;
1363         struct drm_encoder *encoder;
1364         int ret = 0;
1365         int connector_count = 0;
1366         int crtc_count = 0;
1367         int fb_count = 0;
1368         int encoder_count = 0;
1369         int copied = 0, i;
1370         uint32_t __user *fb_id;
1371         uint32_t __user *crtc_id;
1372         uint32_t __user *connector_id;
1373         uint32_t __user *encoder_id;
1374         struct drm_mode_group *mode_group;
1375
1376         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1377                 return -EINVAL;
1378
1379
1380         mutex_lock(&file_priv->fbs_lock);
1381         /*
1382          * For the non-control nodes we need to limit the list of resources
1383          * by IDs in the group list for this node
1384          */
1385         list_for_each(lh, &file_priv->fbs)
1386                 fb_count++;
1387
1388         /* handle this in 4 parts */
1389         /* FBs */
1390         if (card_res->count_fbs >= fb_count) {
1391                 copied = 0;
1392                 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1393                 list_for_each_entry(fb, &file_priv->fbs, filp_head) {
1394                         if (put_user(fb->base.id, fb_id + copied)) {
1395                                 mutex_unlock(&file_priv->fbs_lock);
1396                                 return -EFAULT;
1397                         }
1398                         copied++;
1399                 }
1400         }
1401         card_res->count_fbs = fb_count;
1402         mutex_unlock(&file_priv->fbs_lock);
1403
1404         drm_modeset_lock_all(dev);
1405         mode_group = &file_priv->master->minor->mode_group;
1406         if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1407
1408                 list_for_each(lh, &dev->mode_config.crtc_list)
1409                         crtc_count++;
1410
1411                 list_for_each(lh, &dev->mode_config.connector_list)
1412                         connector_count++;
1413
1414                 list_for_each(lh, &dev->mode_config.encoder_list)
1415                         encoder_count++;
1416         } else {
1417
1418                 crtc_count = mode_group->num_crtcs;
1419                 connector_count = mode_group->num_connectors;
1420                 encoder_count = mode_group->num_encoders;
1421         }
1422
1423         card_res->max_height = dev->mode_config.max_height;
1424         card_res->min_height = dev->mode_config.min_height;
1425         card_res->max_width = dev->mode_config.max_width;
1426         card_res->min_width = dev->mode_config.min_width;
1427
1428         /* CRTCs */
1429         if (card_res->count_crtcs >= crtc_count) {
1430                 copied = 0;
1431                 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1432                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1433                         list_for_each_entry(crtc, &dev->mode_config.crtc_list,
1434                                             head) {
1435                                 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1436                                 if (put_user(crtc->base.id, crtc_id + copied)) {
1437                                         ret = -EFAULT;
1438                                         goto out;
1439                                 }
1440                                 copied++;
1441                         }
1442                 } else {
1443                         for (i = 0; i < mode_group->num_crtcs; i++) {
1444                                 if (put_user(mode_group->id_list[i],
1445                                              crtc_id + copied)) {
1446                                         ret = -EFAULT;
1447                                         goto out;
1448                                 }
1449                                 copied++;
1450                         }
1451                 }
1452         }
1453         card_res->count_crtcs = crtc_count;
1454
1455         /* Encoders */
1456         if (card_res->count_encoders >= encoder_count) {
1457                 copied = 0;
1458                 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
1459                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1460                         list_for_each_entry(encoder,
1461                                             &dev->mode_config.encoder_list,
1462                                             head) {
1463                                 DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
1464                                                 drm_get_encoder_name(encoder));
1465                                 if (put_user(encoder->base.id, encoder_id +
1466                                              copied)) {
1467                                         ret = -EFAULT;
1468                                         goto out;
1469                                 }
1470                                 copied++;
1471                         }
1472                 } else {
1473                         for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
1474                                 if (put_user(mode_group->id_list[i],
1475                                              encoder_id + copied)) {
1476                                         ret = -EFAULT;
1477                                         goto out;
1478                                 }
1479                                 copied++;
1480                         }
1481
1482                 }
1483         }
1484         card_res->count_encoders = encoder_count;
1485
1486         /* Connectors */
1487         if (card_res->count_connectors >= connector_count) {
1488                 copied = 0;
1489                 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
1490                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1491                         list_for_each_entry(connector,
1492                                             &dev->mode_config.connector_list,
1493                                             head) {
1494                                 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1495                                         connector->base.id,
1496                                         drm_get_connector_name(connector));
1497                                 if (put_user(connector->base.id,
1498                                              connector_id + copied)) {
1499                                         ret = -EFAULT;
1500                                         goto out;
1501                                 }
1502                                 copied++;
1503                         }
1504                 } else {
1505                         int start = mode_group->num_crtcs +
1506                                 mode_group->num_encoders;
1507                         for (i = start; i < start + mode_group->num_connectors; i++) {
1508                                 if (put_user(mode_group->id_list[i],
1509                                              connector_id + copied)) {
1510                                         ret = -EFAULT;
1511                                         goto out;
1512                                 }
1513                                 copied++;
1514                         }
1515                 }
1516         }
1517         card_res->count_connectors = connector_count;
1518
1519         DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
1520                   card_res->count_connectors, card_res->count_encoders);
1521
1522 out:
1523         drm_modeset_unlock_all(dev);
1524         return ret;
1525 }
1526
1527 /**
1528  * drm_mode_getcrtc - get CRTC configuration
1529  * @dev: drm device for the ioctl
1530  * @data: data pointer for the ioctl
1531  * @file_priv: drm file for the ioctl call
1532  *
1533  * Construct a CRTC configuration structure to return to the user.
1534  *
1535  * Called by the user via ioctl.
1536  *
1537  * RETURNS:
1538  * Zero on success, errno on failure.
1539  */
1540 int drm_mode_getcrtc(struct drm_device *dev,
1541                      void *data, struct drm_file *file_priv)
1542 {
1543         struct drm_mode_crtc *crtc_resp = data;
1544         struct drm_crtc *crtc;
1545         struct drm_mode_object *obj;
1546         int ret = 0;
1547
1548         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1549                 return -EINVAL;
1550
1551         drm_modeset_lock_all(dev);
1552
1553         obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
1554                                    DRM_MODE_OBJECT_CRTC);
1555         if (!obj) {
1556                 ret = -EINVAL;
1557                 goto out;
1558         }
1559         crtc = obj_to_crtc(obj);
1560
1561         crtc_resp->x = crtc->x;
1562         crtc_resp->y = crtc->y;
1563         crtc_resp->gamma_size = crtc->gamma_size;
1564         if (crtc->fb)
1565                 crtc_resp->fb_id = crtc->fb->base.id;
1566         else
1567                 crtc_resp->fb_id = 0;
1568
1569         if (crtc->enabled) {
1570
1571                 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1572                 crtc_resp->mode_valid = 1;
1573
1574         } else {
1575                 crtc_resp->mode_valid = 0;
1576         }
1577
1578 out:
1579         drm_modeset_unlock_all(dev);
1580         return ret;
1581 }
1582
1583 /**
1584  * drm_mode_getconnector - get connector configuration
1585  * @dev: drm device for the ioctl
1586  * @data: data pointer for the ioctl
1587  * @file_priv: drm file for the ioctl call
1588  *
1589  * Construct a connector configuration structure to return to the user.
1590  *
1591  * Called by the user via ioctl.
1592  *
1593  * RETURNS:
1594  * Zero on success, errno on failure.
1595  */
1596 int drm_mode_getconnector(struct drm_device *dev, void *data,
1597                           struct drm_file *file_priv)
1598 {
1599         struct drm_mode_get_connector *out_resp = data;
1600         struct drm_mode_object *obj;
1601         struct drm_connector *connector;
1602         struct drm_display_mode *mode;
1603         int mode_count = 0;
1604         int props_count = 0;
1605         int encoders_count = 0;
1606         int ret = 0;
1607         int copied = 0;
1608         int i;
1609         struct drm_mode_modeinfo u_mode;
1610         struct drm_mode_modeinfo __user *mode_ptr;
1611         uint32_t __user *prop_ptr;
1612         uint64_t __user *prop_values;
1613         uint32_t __user *encoder_ptr;
1614
1615         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1616                 return -EINVAL;
1617
1618         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1619
1620         DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
1621
1622         mutex_lock(&dev->mode_config.mutex);
1623
1624         obj = drm_mode_object_find(dev, out_resp->connector_id,
1625                                    DRM_MODE_OBJECT_CONNECTOR);
1626         if (!obj) {
1627                 ret = -EINVAL;
1628                 goto out;
1629         }
1630         connector = obj_to_connector(obj);
1631
1632         props_count = connector->properties.count;
1633
1634         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1635                 if (connector->encoder_ids[i] != 0) {
1636                         encoders_count++;
1637                 }
1638         }
1639
1640         if (out_resp->count_modes == 0) {
1641                 connector->funcs->fill_modes(connector,
1642                                              dev->mode_config.max_width,
1643                                              dev->mode_config.max_height);
1644         }
1645
1646         /* delayed so we get modes regardless of pre-fill_modes state */
1647         list_for_each_entry(mode, &connector->modes, head)
1648                 mode_count++;
1649
1650         out_resp->connector_id = connector->base.id;
1651         out_resp->connector_type = connector->connector_type;
1652         out_resp->connector_type_id = connector->connector_type_id;
1653         out_resp->mm_width = connector->display_info.width_mm;
1654         out_resp->mm_height = connector->display_info.height_mm;
1655         out_resp->subpixel = connector->display_info.subpixel_order;
1656         out_resp->connection = connector->status;
1657         if (connector->encoder)
1658                 out_resp->encoder_id = connector->encoder->base.id;
1659         else
1660                 out_resp->encoder_id = 0;
1661
1662         /*
1663          * This ioctl is called twice, once to determine how much space is
1664          * needed, and the 2nd time to fill it.
1665          */
1666         if ((out_resp->count_modes >= mode_count) && mode_count) {
1667                 copied = 0;
1668                 mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
1669                 list_for_each_entry(mode, &connector->modes, head) {
1670                         drm_crtc_convert_to_umode(&u_mode, mode);
1671                         if (copy_to_user(mode_ptr + copied,
1672                                          &u_mode, sizeof(u_mode))) {
1673                                 ret = -EFAULT;
1674                                 goto out;
1675                         }
1676                         copied++;
1677                 }
1678         }
1679         out_resp->count_modes = mode_count;
1680
1681         if ((out_resp->count_props >= props_count) && props_count) {
1682                 copied = 0;
1683                 prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr);
1684                 prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr);
1685                 for (i = 0; i < connector->properties.count; i++) {
1686                         if (put_user(connector->properties.ids[i],
1687                                      prop_ptr + copied)) {
1688                                 ret = -EFAULT;
1689                                 goto out;
1690                         }
1691
1692                         if (put_user(connector->properties.values[i],
1693                                      prop_values + copied)) {
1694                                 ret = -EFAULT;
1695                                 goto out;
1696                         }
1697                         copied++;
1698                 }
1699         }
1700         out_resp->count_props = props_count;
1701
1702         if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
1703                 copied = 0;
1704                 encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
1705                 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1706                         if (connector->encoder_ids[i] != 0) {
1707                                 if (put_user(connector->encoder_ids[i],
1708                                              encoder_ptr + copied)) {
1709                                         ret = -EFAULT;
1710                                         goto out;
1711                                 }
1712                                 copied++;
1713                         }
1714                 }
1715         }
1716         out_resp->count_encoders = encoders_count;
1717
1718 out:
1719         mutex_unlock(&dev->mode_config.mutex);
1720
1721         return ret;
1722 }
1723
1724 int drm_mode_getencoder(struct drm_device *dev, void *data,
1725                         struct drm_file *file_priv)
1726 {
1727         struct drm_mode_get_encoder *enc_resp = data;
1728         struct drm_mode_object *obj;
1729         struct drm_encoder *encoder;
1730         int ret = 0;
1731
1732         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1733                 return -EINVAL;
1734
1735         drm_modeset_lock_all(dev);
1736         obj = drm_mode_object_find(dev, enc_resp->encoder_id,
1737                                    DRM_MODE_OBJECT_ENCODER);
1738         if (!obj) {
1739                 ret = -EINVAL;
1740                 goto out;
1741         }
1742         encoder = obj_to_encoder(obj);
1743
1744         if (encoder->crtc)
1745                 enc_resp->crtc_id = encoder->crtc->base.id;
1746         else
1747                 enc_resp->crtc_id = 0;
1748         enc_resp->encoder_type = encoder->encoder_type;
1749         enc_resp->encoder_id = encoder->base.id;
1750         enc_resp->possible_crtcs = encoder->possible_crtcs;
1751         enc_resp->possible_clones = encoder->possible_clones;
1752
1753 out:
1754         drm_modeset_unlock_all(dev);
1755         return ret;
1756 }
1757
1758 /**
1759  * drm_mode_getplane_res - get plane info
1760  * @dev: DRM device
1761  * @data: ioctl data
1762  * @file_priv: DRM file info
1763  *
1764  * Return an plane count and set of IDs.
1765  */
1766 int drm_mode_getplane_res(struct drm_device *dev, void *data,
1767                             struct drm_file *file_priv)
1768 {
1769         struct drm_mode_get_plane_res *plane_resp = data;
1770         struct drm_mode_config *config;
1771         struct drm_plane *plane;
1772         uint32_t __user *plane_ptr;
1773         int copied = 0, ret = 0;
1774
1775         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1776                 return -EINVAL;
1777
1778         drm_modeset_lock_all(dev);
1779         config = &dev->mode_config;
1780
1781         /*
1782          * This ioctl is called twice, once to determine how much space is
1783          * needed, and the 2nd time to fill it.
1784          */
1785         if (config->num_plane &&
1786             (plane_resp->count_planes >= config->num_plane)) {
1787                 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
1788
1789                 list_for_each_entry(plane, &config->plane_list, head) {
1790                         if (put_user(plane->base.id, plane_ptr + copied)) {
1791                                 ret = -EFAULT;
1792                                 goto out;
1793                         }
1794                         copied++;
1795                 }
1796         }
1797         plane_resp->count_planes = config->num_plane;
1798
1799 out:
1800         drm_modeset_unlock_all(dev);
1801         return ret;
1802 }
1803
1804 /**
1805  * drm_mode_getplane - get plane info
1806  * @dev: DRM device
1807  * @data: ioctl data
1808  * @file_priv: DRM file info
1809  *
1810  * Return plane info, including formats supported, gamma size, any
1811  * current fb, etc.
1812  */
1813 int drm_mode_getplane(struct drm_device *dev, void *data,
1814                         struct drm_file *file_priv)
1815 {
1816         struct drm_mode_get_plane *plane_resp = data;
1817         struct drm_mode_object *obj;
1818         struct drm_plane *plane;
1819         uint32_t __user *format_ptr;
1820         int ret = 0;
1821
1822         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1823                 return -EINVAL;
1824
1825         drm_modeset_lock_all(dev);
1826         obj = drm_mode_object_find(dev, plane_resp->plane_id,
1827                                    DRM_MODE_OBJECT_PLANE);
1828         if (!obj) {
1829                 ret = -ENOENT;
1830                 goto out;
1831         }
1832         plane = obj_to_plane(obj);
1833
1834         if (plane->crtc)
1835                 plane_resp->crtc_id = plane->crtc->base.id;
1836         else
1837                 plane_resp->crtc_id = 0;
1838
1839         if (plane->fb)
1840                 plane_resp->fb_id = plane->fb->base.id;
1841         else
1842                 plane_resp->fb_id = 0;
1843
1844         plane_resp->plane_id = plane->base.id;
1845         plane_resp->possible_crtcs = plane->possible_crtcs;
1846         plane_resp->gamma_size = plane->gamma_size;
1847
1848         /*
1849          * This ioctl is called twice, once to determine how much space is
1850          * needed, and the 2nd time to fill it.
1851          */
1852         if (plane->format_count &&
1853             (plane_resp->count_format_types >= plane->format_count)) {
1854                 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
1855                 if (copy_to_user(format_ptr,
1856                                  plane->format_types,
1857                                  sizeof(uint32_t) * plane->format_count)) {
1858                         ret = -EFAULT;
1859                         goto out;
1860                 }
1861         }
1862         plane_resp->count_format_types = plane->format_count;
1863
1864 out:
1865         drm_modeset_unlock_all(dev);
1866         return ret;
1867 }
1868
1869 /**
1870  * drm_mode_setplane - set up or tear down an plane
1871  * @dev: DRM device
1872  * @data: ioctl data*
1873  * @file_priv: DRM file info
1874  *
1875  * Set plane info, including placement, fb, scaling, and other factors.
1876  * Or pass a NULL fb to disable.
1877  */
1878 int drm_mode_setplane(struct drm_device *dev, void *data,
1879                         struct drm_file *file_priv)
1880 {
1881         struct drm_mode_set_plane *plane_req = data;
1882         struct drm_mode_object *obj;
1883         struct drm_plane *plane;
1884         struct drm_crtc *crtc;
1885         struct drm_framebuffer *fb = NULL, *old_fb = NULL;
1886         int ret = 0;
1887         unsigned int fb_width, fb_height;
1888         int i;
1889
1890         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1891                 return -EINVAL;
1892
1893         /*
1894          * First, find the plane, crtc, and fb objects.  If not available,
1895          * we don't bother to call the driver.
1896          */
1897         obj = drm_mode_object_find(dev, plane_req->plane_id,
1898                                    DRM_MODE_OBJECT_PLANE);
1899         if (!obj) {
1900                 DRM_DEBUG_KMS("Unknown plane ID %d\n",
1901                               plane_req->plane_id);
1902                 return -ENOENT;
1903         }
1904         plane = obj_to_plane(obj);
1905
1906         /* No fb means shut it down */
1907         if (!plane_req->fb_id) {
1908                 drm_modeset_lock_all(dev);
1909                 old_fb = plane->fb;
1910                 plane->funcs->disable_plane(plane);
1911                 plane->crtc = NULL;
1912                 plane->fb = NULL;
1913                 drm_modeset_unlock_all(dev);
1914                 goto out;
1915         }
1916
1917         obj = drm_mode_object_find(dev, plane_req->crtc_id,
1918                                    DRM_MODE_OBJECT_CRTC);
1919         if (!obj) {
1920                 DRM_DEBUG_KMS("Unknown crtc ID %d\n",
1921                               plane_req->crtc_id);
1922                 ret = -ENOENT;
1923                 goto out;
1924         }
1925         crtc = obj_to_crtc(obj);
1926
1927         fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
1928         if (!fb) {
1929                 DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
1930                               plane_req->fb_id);
1931                 ret = -ENOENT;
1932                 goto out;
1933         }
1934
1935         /* Check whether this plane supports the fb pixel format. */
1936         for (i = 0; i < plane->format_count; i++)
1937                 if (fb->pixel_format == plane->format_types[i])
1938                         break;
1939         if (i == plane->format_count) {
1940                 DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format);
1941                 ret = -EINVAL;
1942                 goto out;
1943         }
1944
1945         fb_width = fb->width << 16;
1946         fb_height = fb->height << 16;
1947
1948         /* Make sure source coordinates are inside the fb. */
1949         if (plane_req->src_w > fb_width ||
1950             plane_req->src_x > fb_width - plane_req->src_w ||
1951             plane_req->src_h > fb_height ||
1952             plane_req->src_y > fb_height - plane_req->src_h) {
1953                 DRM_DEBUG_KMS("Invalid source coordinates "
1954                               "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
1955                               plane_req->src_w >> 16,
1956                               ((plane_req->src_w & 0xffff) * 15625) >> 10,
1957                               plane_req->src_h >> 16,
1958                               ((plane_req->src_h & 0xffff) * 15625) >> 10,
1959                               plane_req->src_x >> 16,
1960                               ((plane_req->src_x & 0xffff) * 15625) >> 10,
1961                               plane_req->src_y >> 16,
1962                               ((plane_req->src_y & 0xffff) * 15625) >> 10);
1963                 ret = -ENOSPC;
1964                 goto out;
1965         }
1966
1967         /* Give drivers some help against integer overflows */
1968         if (plane_req->crtc_w > INT_MAX ||
1969             plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w ||
1970             plane_req->crtc_h > INT_MAX ||
1971             plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) {
1972                 DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
1973                               plane_req->crtc_w, plane_req->crtc_h,
1974                               plane_req->crtc_x, plane_req->crtc_y);
1975                 ret = -ERANGE;
1976                 goto out;
1977         }
1978
1979         drm_modeset_lock_all(dev);
1980         ret = plane->funcs->update_plane(plane, crtc, fb,
1981                                          plane_req->crtc_x, plane_req->crtc_y,
1982                                          plane_req->crtc_w, plane_req->crtc_h,
1983                                          plane_req->src_x, plane_req->src_y,
1984                                          plane_req->src_w, plane_req->src_h);
1985         if (!ret) {
1986                 old_fb = plane->fb;
1987                 plane->crtc = crtc;
1988                 plane->fb = fb;
1989                 fb = NULL;
1990         }
1991         drm_modeset_unlock_all(dev);
1992
1993 out:
1994         if (fb)
1995                 drm_framebuffer_unreference(fb);
1996         if (old_fb)
1997                 drm_framebuffer_unreference(old_fb);
1998
1999         return ret;
2000 }
2001
2002 /**
2003  * drm_mode_set_config_internal - helper to call ->set_config
2004  * @set: modeset config to set
2005  *
2006  * This is a little helper to wrap internal calls to the ->set_config driver
2007  * interface. The only thing it adds is correct refcounting dance.
2008  */
2009 int drm_mode_set_config_internal(struct drm_mode_set *set)
2010 {
2011         struct drm_crtc *crtc = set->crtc;
2012         struct drm_framebuffer *fb, *old_fb;
2013         int ret;
2014
2015         old_fb = crtc->fb;
2016         fb = set->fb;
2017
2018         ret = crtc->funcs->set_config(set);
2019         if (ret == 0) {
2020                 if (old_fb)
2021                         drm_framebuffer_unreference(old_fb);
2022                 if (fb)
2023                         drm_framebuffer_reference(fb);
2024         }
2025
2026         return ret;
2027 }
2028 EXPORT_SYMBOL(drm_mode_set_config_internal);
2029
2030 /**
2031  * drm_mode_setcrtc - set CRTC configuration
2032  * @dev: drm device for the ioctl
2033  * @data: data pointer for the ioctl
2034  * @file_priv: drm file for the ioctl call
2035  *
2036  * Build a new CRTC configuration based on user request.
2037  *
2038  * Called by the user via ioctl.
2039  *
2040  * RETURNS:
2041  * Zero on success, errno on failure.
2042  */
2043 int drm_mode_setcrtc(struct drm_device *dev, void *data,
2044                      struct drm_file *file_priv)
2045 {
2046         struct drm_mode_config *config = &dev->mode_config;
2047         struct drm_mode_crtc *crtc_req = data;
2048         struct drm_mode_object *obj;
2049         struct drm_crtc *crtc;
2050         struct drm_connector **connector_set = NULL, *connector;
2051         struct drm_framebuffer *fb = NULL;
2052         struct drm_display_mode *mode = NULL;
2053         struct drm_mode_set set;
2054         uint32_t __user *set_connectors_ptr;
2055         int ret;
2056         int i;
2057
2058         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2059                 return -EINVAL;
2060
2061         /* For some reason crtc x/y offsets are signed internally. */
2062         if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
2063                 return -ERANGE;
2064
2065         drm_modeset_lock_all(dev);
2066         obj = drm_mode_object_find(dev, crtc_req->crtc_id,
2067                                    DRM_MODE_OBJECT_CRTC);
2068         if (!obj) {
2069                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
2070                 ret = -EINVAL;
2071                 goto out;
2072         }
2073         crtc = obj_to_crtc(obj);
2074         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
2075
2076         if (crtc_req->mode_valid) {
2077                 int hdisplay, vdisplay;
2078                 /* If we have a mode we need a framebuffer. */
2079                 /* If we pass -1, set the mode with the currently bound fb */
2080                 if (crtc_req->fb_id == -1) {
2081                         if (!crtc->fb) {
2082                                 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
2083                                 ret = -EINVAL;
2084                                 goto out;
2085                         }
2086                         fb = crtc->fb;
2087                         /* Make refcounting symmetric with the lookup path. */
2088                         drm_framebuffer_reference(fb);
2089                 } else {
2090                         fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
2091                         if (!fb) {
2092                                 DRM_DEBUG_KMS("Unknown FB ID%d\n",
2093                                                 crtc_req->fb_id);
2094                                 ret = -EINVAL;
2095                                 goto out;
2096                         }
2097                 }
2098
2099                 mode = drm_mode_create(dev);
2100                 if (!mode) {
2101                         ret = -ENOMEM;
2102                         goto out;
2103                 }
2104
2105                 ret = drm_crtc_convert_umode(mode, &crtc_req->mode);
2106                 if (ret) {
2107                         DRM_DEBUG_KMS("Invalid mode\n");
2108                         goto out;
2109                 }
2110
2111                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
2112
2113                 hdisplay = mode->hdisplay;
2114                 vdisplay = mode->vdisplay;
2115
2116                 if (crtc->invert_dimensions)
2117                         swap(hdisplay, vdisplay);
2118
2119                 if (hdisplay > fb->width ||
2120                     vdisplay > fb->height ||
2121                     crtc_req->x > fb->width - hdisplay ||
2122                     crtc_req->y > fb->height - vdisplay) {
2123                         DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
2124                                       fb->width, fb->height,
2125                                       hdisplay, vdisplay, crtc_req->x, crtc_req->y,
2126                                       crtc->invert_dimensions ? " (inverted)" : "");
2127                         ret = -ENOSPC;
2128                         goto out;
2129                 }
2130         }
2131
2132         if (crtc_req->count_connectors == 0 && mode) {
2133                 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
2134                 ret = -EINVAL;
2135                 goto out;
2136         }
2137
2138         if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
2139                 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
2140                           crtc_req->count_connectors);
2141                 ret = -EINVAL;
2142                 goto out;
2143         }
2144
2145         if (crtc_req->count_connectors > 0) {
2146                 u32 out_id;
2147
2148                 /* Avoid unbounded kernel memory allocation */
2149                 if (crtc_req->count_connectors > config->num_connector) {
2150                         ret = -EINVAL;
2151                         goto out;
2152                 }
2153
2154                 connector_set = kmalloc(crtc_req->count_connectors *
2155                                         sizeof(struct drm_connector *),
2156                                         GFP_KERNEL);
2157                 if (!connector_set) {
2158                         ret = -ENOMEM;
2159                         goto out;
2160                 }
2161
2162                 for (i = 0; i < crtc_req->count_connectors; i++) {
2163                         set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
2164                         if (get_user(out_id, &set_connectors_ptr[i])) {
2165                                 ret = -EFAULT;
2166                                 goto out;
2167                         }
2168
2169                         obj = drm_mode_object_find(dev, out_id,
2170                                                    DRM_MODE_OBJECT_CONNECTOR);
2171                         if (!obj) {
2172                                 DRM_DEBUG_KMS("Connector id %d unknown\n",
2173                                                 out_id);
2174                                 ret = -EINVAL;
2175                                 goto out;
2176                         }
2177                         connector = obj_to_connector(obj);
2178                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
2179                                         connector->base.id,
2180                                         drm_get_connector_name(connector));
2181
2182                         connector_set[i] = connector;
2183                 }
2184         }
2185
2186         set.crtc = crtc;
2187         set.x = crtc_req->x;
2188         set.y = crtc_req->y;
2189         set.mode = mode;
2190         set.connectors = connector_set;
2191         set.num_connectors = crtc_req->count_connectors;
2192         set.fb = fb;
2193         ret = drm_mode_set_config_internal(&set);
2194
2195 out:
2196         if (fb)
2197                 drm_framebuffer_unreference(fb);
2198
2199         kfree(connector_set);
2200         drm_mode_destroy(dev, mode);
2201         drm_modeset_unlock_all(dev);
2202         return ret;
2203 }
2204
2205 int drm_mode_cursor_ioctl(struct drm_device *dev,
2206                         void *data, struct drm_file *file_priv)
2207 {
2208         struct drm_mode_cursor *req = data;
2209         struct drm_mode_object *obj;
2210         struct drm_crtc *crtc;
2211         int ret = 0;
2212
2213         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2214                 return -EINVAL;
2215
2216         if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
2217                 return -EINVAL;
2218
2219         obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
2220         if (!obj) {
2221                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
2222                 return -EINVAL;
2223         }
2224         crtc = obj_to_crtc(obj);
2225
2226         mutex_lock(&crtc->mutex);
2227         if (req->flags & DRM_MODE_CURSOR_BO) {
2228                 if (!crtc->funcs->cursor_set) {
2229                         ret = -ENXIO;
2230                         goto out;
2231                 }
2232                 /* Turns off the cursor if handle is 0 */
2233                 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
2234                                               req->width, req->height);
2235         }
2236
2237         if (req->flags & DRM_MODE_CURSOR_MOVE) {
2238                 if (crtc->funcs->cursor_move) {
2239                         ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
2240                 } else {
2241                         ret = -EFAULT;
2242                         goto out;
2243                 }
2244         }
2245 out:
2246         mutex_unlock(&crtc->mutex);
2247
2248         return ret;
2249 }
2250
2251 /* Original addfb only supported RGB formats, so figure out which one */
2252 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
2253 {
2254         uint32_t fmt;
2255
2256         switch (bpp) {
2257         case 8:
2258                 fmt = DRM_FORMAT_C8;
2259                 break;
2260         case 16:
2261                 if (depth == 15)
2262                         fmt = DRM_FORMAT_XRGB1555;
2263                 else
2264                         fmt = DRM_FORMAT_RGB565;
2265                 break;
2266         case 24:
2267                 fmt = DRM_FORMAT_RGB888;
2268                 break;
2269         case 32:
2270                 if (depth == 24)
2271                         fmt = DRM_FORMAT_XRGB8888;
2272                 else if (depth == 30)
2273                         fmt = DRM_FORMAT_XRGB2101010;
2274                 else
2275                         fmt = DRM_FORMAT_ARGB8888;
2276                 break;
2277         default:
2278                 DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
2279                 fmt = DRM_FORMAT_XRGB8888;
2280                 break;
2281         }
2282
2283         return fmt;
2284 }
2285 EXPORT_SYMBOL(drm_mode_legacy_fb_format);
2286
2287 /**
2288  * drm_mode_addfb - add an FB to the graphics configuration
2289  * @dev: drm device for the ioctl
2290  * @data: data pointer for the ioctl
2291  * @file_priv: drm file for the ioctl call
2292  *
2293  * Add a new FB to the specified CRTC, given a user request.
2294  *
2295  * Called by the user via ioctl.
2296  *
2297  * RETURNS:
2298  * Zero on success, errno on failure.
2299  */
2300 int drm_mode_addfb(struct drm_device *dev,
2301                    void *data, struct drm_file *file_priv)
2302 {
2303         struct drm_mode_fb_cmd *or = data;
2304         struct drm_mode_fb_cmd2 r = {};
2305         struct drm_mode_config *config = &dev->mode_config;
2306         struct drm_framebuffer *fb;
2307         int ret = 0;
2308
2309         /* Use new struct with format internally */
2310         r.fb_id = or->fb_id;
2311         r.width = or->width;
2312         r.height = or->height;
2313         r.pitches[0] = or->pitch;
2314         r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
2315         r.handles[0] = or->handle;
2316
2317         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2318                 return -EINVAL;
2319
2320         if ((config->min_width > r.width) || (r.width > config->max_width))
2321                 return -EINVAL;
2322
2323         if ((config->min_height > r.height) || (r.height > config->max_height))
2324                 return -EINVAL;
2325
2326         fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
2327         if (IS_ERR(fb)) {
2328                 DRM_DEBUG_KMS("could not create framebuffer\n");
2329                 return PTR_ERR(fb);
2330         }
2331
2332         mutex_lock(&file_priv->fbs_lock);
2333         or->fb_id = fb->base.id;
2334         list_add(&fb->filp_head, &file_priv->fbs);
2335         DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
2336         mutex_unlock(&file_priv->fbs_lock);
2337
2338         return ret;
2339 }
2340
2341 static int format_check(const struct drm_mode_fb_cmd2 *r)
2342 {
2343         uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN;
2344
2345         switch (format) {
2346         case DRM_FORMAT_C8:
2347         case DRM_FORMAT_RGB332:
2348         case DRM_FORMAT_BGR233:
2349         case DRM_FORMAT_XRGB4444:
2350         case DRM_FORMAT_XBGR4444:
2351         case DRM_FORMAT_RGBX4444:
2352         case DRM_FORMAT_BGRX4444:
2353         case DRM_FORMAT_ARGB4444:
2354         case DRM_FORMAT_ABGR4444:
2355         case DRM_FORMAT_RGBA4444:
2356         case DRM_FORMAT_BGRA4444:
2357         case DRM_FORMAT_XRGB1555:
2358         case DRM_FORMAT_XBGR1555:
2359         case DRM_FORMAT_RGBX5551:
2360         case DRM_FORMAT_BGRX5551:
2361         case DRM_FORMAT_ARGB1555:
2362         case DRM_FORMAT_ABGR1555:
2363         case DRM_FORMAT_RGBA5551:
2364         case DRM_FORMAT_BGRA5551:
2365         case DRM_FORMAT_RGB565:
2366         case DRM_FORMAT_BGR565:
2367         case DRM_FORMAT_RGB888:
2368         case DRM_FORMAT_BGR888:
2369         case DRM_FORMAT_XRGB8888:
2370         case DRM_FORMAT_XBGR8888:
2371         case DRM_FORMAT_RGBX8888:
2372         case DRM_FORMAT_BGRX8888:
2373         case DRM_FORMAT_ARGB8888:
2374         case DRM_FORMAT_ABGR8888:
2375         case DRM_FORMAT_RGBA8888:
2376         case DRM_FORMAT_BGRA8888:
2377         case DRM_FORMAT_XRGB2101010:
2378         case DRM_FORMAT_XBGR2101010:
2379         case DRM_FORMAT_RGBX1010102:
2380         case DRM_FORMAT_BGRX1010102:
2381         case DRM_FORMAT_ARGB2101010:
2382         case DRM_FORMAT_ABGR2101010:
2383         case DRM_FORMAT_RGBA1010102:
2384         case DRM_FORMAT_BGRA1010102:
2385         case DRM_FORMAT_YUYV:
2386         case DRM_FORMAT_YVYU:
2387         case DRM_FORMAT_UYVY:
2388         case DRM_FORMAT_VYUY:
2389         case DRM_FORMAT_AYUV:
2390         case DRM_FORMAT_NV12:
2391         case DRM_FORMAT_NV21:
2392         case DRM_FORMAT_NV16:
2393         case DRM_FORMAT_NV61:
2394         case DRM_FORMAT_NV24:
2395         case DRM_FORMAT_NV42:
2396         case DRM_FORMAT_YUV410:
2397         case DRM_FORMAT_YVU410:
2398         case DRM_FORMAT_YUV411:
2399         case DRM_FORMAT_YVU411:
2400         case DRM_FORMAT_YUV420:
2401         case DRM_FORMAT_YVU420:
2402         case DRM_FORMAT_YUV422:
2403         case DRM_FORMAT_YVU422:
2404         case DRM_FORMAT_YUV444:
2405         case DRM_FORMAT_YVU444:
2406                 return 0;
2407         default:
2408                 return -EINVAL;
2409         }
2410 }
2411
2412 static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
2413 {
2414         int ret, hsub, vsub, num_planes, i;
2415
2416         ret = format_check(r);
2417         if (ret) {
2418                 DRM_DEBUG_KMS("bad framebuffer format 0x%08x\n", r->pixel_format);
2419                 return ret;
2420         }
2421
2422         hsub = drm_format_horz_chroma_subsampling(r->pixel_format);
2423         vsub = drm_format_vert_chroma_subsampling(r->pixel_format);
2424         num_planes = drm_format_num_planes(r->pixel_format);
2425
2426         if (r->width == 0 || r->width % hsub) {
2427                 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height);
2428                 return -EINVAL;
2429         }
2430
2431         if (r->height == 0 || r->height % vsub) {
2432                 DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
2433                 return -EINVAL;
2434         }
2435
2436         for (i = 0; i < num_planes; i++) {
2437                 unsigned int width = r->width / (i != 0 ? hsub : 1);
2438                 unsigned int height = r->height / (i != 0 ? vsub : 1);
2439                 unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);
2440
2441                 if (!r->handles[i]) {
2442                         DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
2443                         return -EINVAL;
2444                 }
2445
2446                 if ((uint64_t) width * cpp > UINT_MAX)
2447                         return -ERANGE;
2448
2449                 if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
2450                         return -ERANGE;
2451
2452                 if (r->pitches[i] < width * cpp) {
2453                         DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
2454                         return -EINVAL;
2455                 }
2456         }
2457
2458         return 0;
2459 }
2460
2461 /**
2462  * drm_mode_addfb2 - add an FB to the graphics configuration
2463  * @dev: drm device for the ioctl
2464  * @data: data pointer for the ioctl
2465  * @file_priv: drm file for the ioctl call
2466  *
2467  * Add a new FB to the specified CRTC, given a user request with format.
2468  *
2469  * Called by the user via ioctl.
2470  *
2471  * RETURNS:
2472  * Zero on success, errno on failure.
2473  */
2474 int drm_mode_addfb2(struct drm_device *dev,
2475                     void *data, struct drm_file *file_priv)
2476 {
2477         struct drm_mode_fb_cmd2 *r = data;
2478         struct drm_mode_config *config = &dev->mode_config;
2479         struct drm_framebuffer *fb;
2480         int ret;
2481
2482         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2483                 return -EINVAL;
2484
2485         if (r->flags & ~DRM_MODE_FB_INTERLACED) {
2486                 DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
2487                 return -EINVAL;
2488         }
2489
2490         if ((config->min_width > r->width) || (r->width > config->max_width)) {
2491                 DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
2492                           r->width, config->min_width, config->max_width);
2493                 return -EINVAL;
2494         }
2495         if ((config->min_height > r->height) || (r->height > config->max_height)) {
2496                 DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
2497                           r->height, config->min_height, config->max_height);
2498                 return -EINVAL;
2499         }
2500
2501         ret = framebuffer_check(r);
2502         if (ret)
2503                 return ret;
2504
2505         fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
2506         if (IS_ERR(fb)) {
2507                 DRM_DEBUG_KMS("could not create framebuffer\n");
2508                 return PTR_ERR(fb);
2509         }
2510
2511         mutex_lock(&file_priv->fbs_lock);
2512         r->fb_id = fb->base.id;
2513         list_add(&fb->filp_head, &file_priv->fbs);
2514         DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
2515         mutex_unlock(&file_priv->fbs_lock);
2516
2517
2518         return ret;
2519 }
2520
2521 /**
2522  * drm_mode_rmfb - remove an FB from the configuration
2523  * @dev: drm device for the ioctl
2524  * @data: data pointer for the ioctl
2525  * @file_priv: drm file for the ioctl call
2526  *
2527  * Remove the FB specified by the user.
2528  *
2529  * Called by the user via ioctl.
2530  *
2531  * RETURNS:
2532  * Zero on success, errno on failure.
2533  */
2534 int drm_mode_rmfb(struct drm_device *dev,
2535                    void *data, struct drm_file *file_priv)
2536 {
2537         struct drm_framebuffer *fb = NULL;
2538         struct drm_framebuffer *fbl = NULL;
2539         uint32_t *id = data;
2540         int found = 0;
2541
2542         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2543                 return -EINVAL;
2544
2545         mutex_lock(&file_priv->fbs_lock);
2546         mutex_lock(&dev->mode_config.fb_lock);
2547         fb = __drm_framebuffer_lookup(dev, *id);
2548         if (!fb)
2549                 goto fail_lookup;
2550
2551         list_for_each_entry(fbl, &file_priv->fbs, filp_head)
2552                 if (fb == fbl)
2553                         found = 1;
2554         if (!found)
2555                 goto fail_lookup;
2556
2557         /* Mark fb as reaped, we still have a ref from fpriv->fbs. */
2558         __drm_framebuffer_unregister(dev, fb);
2559
2560         list_del_init(&fb->filp_head);
2561         mutex_unlock(&dev->mode_config.fb_lock);
2562         mutex_unlock(&file_priv->fbs_lock);
2563
2564         drm_framebuffer_remove(fb);
2565
2566         return 0;
2567
2568 fail_lookup:
2569         mutex_unlock(&dev->mode_config.fb_lock);
2570         mutex_unlock(&file_priv->fbs_lock);
2571
2572         return -EINVAL;
2573 }
2574
2575 /**
2576  * drm_mode_getfb - get FB info
2577  * @dev: drm device for the ioctl
2578  * @data: data pointer for the ioctl
2579  * @file_priv: drm file for the ioctl call
2580  *
2581  * Lookup the FB given its ID and return info about it.
2582  *
2583  * Called by the user via ioctl.
2584  *
2585  * RETURNS:
2586  * Zero on success, errno on failure.
2587  */
2588 int drm_mode_getfb(struct drm_device *dev,
2589                    void *data, struct drm_file *file_priv)
2590 {
2591         struct drm_mode_fb_cmd *r = data;
2592         struct drm_framebuffer *fb;
2593         int ret;
2594
2595         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2596                 return -EINVAL;
2597
2598         fb = drm_framebuffer_lookup(dev, r->fb_id);
2599         if (!fb)
2600                 return -EINVAL;
2601
2602         r->height = fb->height;
2603         r->width = fb->width;
2604         r->depth = fb->depth;
2605         r->bpp = fb->bits_per_pixel;
2606         r->pitch = fb->pitches[0];
2607         if (fb->funcs->create_handle)
2608                 ret = fb->funcs->create_handle(fb, file_priv, &r->handle);
2609         else
2610                 ret = -ENODEV;
2611
2612         drm_framebuffer_unreference(fb);
2613
2614         return ret;
2615 }
2616
2617 int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
2618                            void *data, struct drm_file *file_priv)
2619 {
2620         struct drm_clip_rect __user *clips_ptr;
2621         struct drm_clip_rect *clips = NULL;
2622         struct drm_mode_fb_dirty_cmd *r = data;
2623         struct drm_framebuffer *fb;
2624         unsigned flags;
2625         int num_clips;
2626         int ret;
2627
2628         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2629                 return -EINVAL;
2630
2631         fb = drm_framebuffer_lookup(dev, r->fb_id);
2632         if (!fb)
2633                 return -EINVAL;
2634
2635         num_clips = r->num_clips;
2636         clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
2637
2638         if (!num_clips != !clips_ptr) {
2639                 ret = -EINVAL;
2640                 goto out_err1;
2641         }
2642
2643         flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
2644
2645         /* If userspace annotates copy, clips must come in pairs */
2646         if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
2647                 ret = -EINVAL;
2648                 goto out_err1;
2649         }
2650
2651         if (num_clips && clips_ptr) {
2652                 if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
2653                         ret = -EINVAL;
2654                         goto out_err1;
2655                 }
2656                 clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
2657                 if (!clips) {
2658                         ret = -ENOMEM;
2659                         goto out_err1;
2660                 }
2661
2662                 ret = copy_from_user(clips, clips_ptr,
2663                                      num_clips * sizeof(*clips));
2664                 if (ret) {
2665                         ret = -EFAULT;
2666                         goto out_err2;
2667                 }
2668         }
2669
2670         if (fb->funcs->dirty) {
2671                 drm_modeset_lock_all(dev);
2672                 ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
2673                                        clips, num_clips);
2674                 drm_modeset_unlock_all(dev);
2675         } else {
2676                 ret = -ENOSYS;
2677         }
2678
2679 out_err2:
2680         kfree(clips);
2681 out_err1:
2682         drm_framebuffer_unreference(fb);
2683
2684         return ret;
2685 }
2686
2687
2688 /**
2689  * drm_fb_release - remove and free the FBs on this file
2690  * @priv: drm file for the ioctl
2691  *
2692  * Destroy all the FBs associated with @filp.
2693  *
2694  * Called by the user via ioctl.
2695  *
2696  * RETURNS:
2697  * Zero on success, errno on failure.
2698  */
2699 void drm_fb_release(struct drm_file *priv)
2700 {
2701         struct drm_device *dev = priv->minor->dev;
2702         struct drm_framebuffer *fb, *tfb;
2703
2704         mutex_lock(&priv->fbs_lock);
2705         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
2706
2707                 mutex_lock(&dev->mode_config.fb_lock);
2708                 /* Mark fb as reaped, we still have a ref from fpriv->fbs. */
2709                 __drm_framebuffer_unregister(dev, fb);
2710                 mutex_unlock(&dev->mode_config.fb_lock);
2711
2712                 list_del_init(&fb->filp_head);
2713
2714                 /* This will also drop the fpriv->fbs reference. */
2715                 drm_framebuffer_remove(fb);
2716         }
2717         mutex_unlock(&priv->fbs_lock);
2718 }
2719
2720 /**
2721  * drm_mode_attachmode - add a mode to the user mode list
2722  * @dev: DRM device
2723  * @connector: connector to add the mode to
2724  * @mode: mode to add
2725  *
2726  * Add @mode to @connector's user mode list.
2727  */
2728 static void drm_mode_attachmode(struct drm_device *dev,
2729                                 struct drm_connector *connector,
2730                                 struct drm_display_mode *mode)
2731 {
2732         list_add_tail(&mode->head, &connector->user_modes);
2733 }
2734
2735 int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
2736                              const struct drm_display_mode *mode)
2737 {
2738         struct drm_connector *connector;
2739         int ret = 0;
2740         struct drm_display_mode *dup_mode, *next;
2741         LIST_HEAD(list);
2742
2743         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2744                 if (!connector->encoder)
2745                         continue;
2746                 if (connector->encoder->crtc == crtc) {
2747                         dup_mode = drm_mode_duplicate(dev, mode);
2748                         if (!dup_mode) {
2749                                 ret = -ENOMEM;
2750                                 goto out;
2751                         }
2752                         list_add_tail(&dup_mode->head, &list);
2753                 }
2754         }
2755
2756         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2757                 if (!connector->encoder)
2758                         continue;
2759                 if (connector->encoder->crtc == crtc)
2760                         list_move_tail(list.next, &connector->user_modes);
2761         }
2762
2763         WARN_ON(!list_empty(&list));
2764
2765  out:
2766         list_for_each_entry_safe(dup_mode, next, &list, head)
2767                 drm_mode_destroy(dev, dup_mode);
2768
2769         return ret;
2770 }
2771 EXPORT_SYMBOL(drm_mode_attachmode_crtc);
2772
2773 static int drm_mode_detachmode(struct drm_device *dev,
2774                                struct drm_connector *connector,
2775                                struct drm_display_mode *mode)
2776 {
2777         int found = 0;
2778         int ret = 0;
2779         struct drm_display_mode *match_mode, *t;
2780
2781         list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) {
2782                 if (drm_mode_equal(match_mode, mode)) {
2783                         list_del(&match_mode->head);
2784                         drm_mode_destroy(dev, match_mode);
2785                         found = 1;
2786                         break;
2787                 }
2788         }
2789
2790         if (!found)
2791                 ret = -EINVAL;
2792
2793         return ret;
2794 }
2795
2796 int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
2797 {
2798         struct drm_connector *connector;
2799
2800         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2801                 drm_mode_detachmode(dev, connector, mode);
2802         }
2803         return 0;
2804 }
2805 EXPORT_SYMBOL(drm_mode_detachmode_crtc);
2806
2807 /**
2808  * drm_fb_attachmode - Attach a user mode to an connector
2809  * @dev: drm device for the ioctl
2810  * @data: data pointer for the ioctl
2811  * @file_priv: drm file for the ioctl call
2812  *
2813  * This attaches a user specified mode to an connector.
2814  * Called by the user via ioctl.
2815  *
2816  * RETURNS:
2817  * Zero on success, errno on failure.
2818  */
2819 int drm_mode_attachmode_ioctl(struct drm_device *dev,
2820                               void *data, struct drm_file *file_priv)
2821 {
2822         struct drm_mode_mode_cmd *mode_cmd = data;
2823         struct drm_connector *connector;
2824         struct drm_display_mode *mode;
2825         struct drm_mode_object *obj;
2826         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
2827         int ret;
2828
2829         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2830                 return -EINVAL;
2831
2832         drm_modeset_lock_all(dev);
2833
2834         obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
2835         if (!obj) {
2836                 ret = -EINVAL;
2837                 goto out;
2838         }
2839         connector = obj_to_connector(obj);
2840
2841         mode = drm_mode_create(dev);
2842         if (!mode) {
2843                 ret = -ENOMEM;
2844                 goto out;
2845         }
2846
2847         ret = drm_crtc_convert_umode(mode, umode);
2848         if (ret) {
2849                 DRM_DEBUG_KMS("Invalid mode\n");
2850                 drm_mode_destroy(dev, mode);
2851                 goto out;
2852         }
2853
2854         drm_mode_attachmode(dev, connector, mode);
2855 out:
2856         drm_modeset_unlock_all(dev);
2857         return ret;
2858 }
2859
2860
2861 /**
2862  * drm_fb_detachmode - Detach a user specified mode from an connector
2863  * @dev: drm device for the ioctl
2864  * @data: data pointer for the ioctl
2865  * @file_priv: drm file for the ioctl call
2866  *
2867  * Called by the user via ioctl.
2868  *
2869  * RETURNS:
2870  * Zero on success, errno on failure.
2871  */
2872 int drm_mode_detachmode_ioctl(struct drm_device *dev,
2873                               void *data, struct drm_file *file_priv)
2874 {
2875         struct drm_mode_object *obj;
2876         struct drm_mode_mode_cmd *mode_cmd = data;
2877         struct drm_connector *connector;
2878         struct drm_display_mode mode;
2879         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
2880         int ret;
2881
2882         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2883                 return -EINVAL;
2884
2885         drm_modeset_lock_all(dev);
2886
2887         obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
2888         if (!obj) {
2889                 ret = -EINVAL;
2890                 goto out;
2891         }
2892         connector = obj_to_connector(obj);
2893
2894         ret = drm_crtc_convert_umode(&mode, umode);
2895         if (ret) {
2896                 DRM_DEBUG_KMS("Invalid mode\n");
2897                 goto out;
2898         }
2899
2900         ret = drm_mode_detachmode(dev, connector, &mode);
2901 out:
2902         drm_modeset_unlock_all(dev);
2903         return ret;
2904 }
2905
2906 struct drm_property *drm_property_create(struct drm_device *dev, int flags,
2907                                          const char *name, int num_values)
2908 {
2909         struct drm_property *property = NULL;
2910         int ret;
2911
2912         property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
2913         if (!property)
2914                 return NULL;
2915
2916         if (num_values) {
2917                 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
2918                 if (!property->values)
2919                         goto fail;
2920         }
2921
2922         ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
2923         if (ret)
2924                 goto fail;
2925
2926         property->flags = flags;
2927         property->num_values = num_values;
2928         INIT_LIST_HEAD(&property->enum_blob_list);
2929
2930         if (name) {
2931                 strncpy(property->name, name, DRM_PROP_NAME_LEN);
2932                 property->name[DRM_PROP_NAME_LEN-1] = '\0';
2933         }
2934
2935         list_add_tail(&property->head, &dev->mode_config.property_list);
2936         return property;
2937 fail:
2938         kfree(property->values);
2939         kfree(property);
2940         return NULL;
2941 }
2942 EXPORT_SYMBOL(drm_property_create);
2943
2944 struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
2945                                          const char *name,
2946                                          const struct drm_prop_enum_list *props,
2947                                          int num_values)
2948 {
2949         struct drm_property *property;
2950         int i, ret;
2951
2952         flags |= DRM_MODE_PROP_ENUM;
2953
2954         property = drm_property_create(dev, flags, name, num_values);
2955         if (!property)
2956                 return NULL;
2957
2958         for (i = 0; i < num_values; i++) {
2959                 ret = drm_property_add_enum(property, i,
2960                                       props[i].type,
2961                                       props[i].name);
2962                 if (ret) {
2963                         drm_property_destroy(dev, property);
2964                         return NULL;
2965                 }
2966         }
2967
2968         return property;
2969 }
2970 EXPORT_SYMBOL(drm_property_create_enum);
2971
2972 struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
2973                                          int flags, const char *name,
2974                                          const struct drm_prop_enum_list *props,
2975                                          int num_values)
2976 {
2977         struct drm_property *property;
2978         int i, ret;
2979
2980         flags |= DRM_MODE_PROP_BITMASK;
2981
2982         property = drm_property_create(dev, flags, name, num_values);
2983         if (!property)
2984                 return NULL;
2985
2986         for (i = 0; i < num_values; i++) {
2987                 ret = drm_property_add_enum(property, i,
2988                                       props[i].type,
2989                                       props[i].name);
2990                 if (ret) {
2991                         drm_property_destroy(dev, property);
2992                         return NULL;
2993                 }
2994         }
2995
2996         return property;
2997 }
2998 EXPORT_SYMBOL(drm_property_create_bitmask);
2999
3000 struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
3001                                          const char *name,
3002                                          uint64_t min, uint64_t max)
3003 {
3004         struct drm_property *property;
3005
3006         flags |= DRM_MODE_PROP_RANGE;
3007
3008         property = drm_property_create(dev, flags, name, 2);
3009         if (!property)
3010                 return NULL;
3011
3012         property->values[0] = min;
3013         property->values[1] = max;
3014
3015         return property;
3016 }
3017 EXPORT_SYMBOL(drm_property_create_range);
3018
3019 int drm_property_add_enum(struct drm_property *property, int index,
3020                           uint64_t value, const char *name)
3021 {
3022         struct drm_property_enum *prop_enum;
3023
3024         if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)))
3025                 return -EINVAL;
3026
3027         /*
3028          * Bitmask enum properties have the additional constraint of values
3029          * from 0 to 63
3030          */
3031         if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63))
3032                 return -EINVAL;
3033
3034         if (!list_empty(&property->enum_blob_list)) {
3035                 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
3036                         if (prop_enum->value == value) {
3037                                 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
3038                                 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
3039                                 return 0;
3040                         }
3041                 }
3042         }
3043
3044         prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
3045         if (!prop_enum)
3046                 return -ENOMEM;
3047
3048         strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
3049         prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
3050         prop_enum->value = value;
3051
3052         property->values[index] = value;
3053         list_add_tail(&prop_enum->head, &property->enum_blob_list);
3054         return 0;
3055 }
3056 EXPORT_SYMBOL(drm_property_add_enum);
3057
3058 void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
3059 {
3060         struct drm_property_enum *prop_enum, *pt;
3061
3062         list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
3063                 list_del(&prop_enum->head);
3064                 kfree(prop_enum);
3065         }
3066
3067         if (property->num_values)
3068                 kfree(property->values);
3069         drm_mode_object_put(dev, &property->base);
3070         list_del(&property->head);
3071         kfree(property);
3072 }
3073 EXPORT_SYMBOL(drm_property_destroy);
3074
3075 void drm_object_attach_property(struct drm_mode_object *obj,
3076                                 struct drm_property *property,
3077                                 uint64_t init_val)
3078 {
3079         int count = obj->properties->count;
3080
3081         if (count == DRM_OBJECT_MAX_PROPERTY) {
3082                 WARN(1, "Failed to attach object property (type: 0x%x). Please "
3083                         "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
3084                         "you see this message on the same object type.\n",
3085                         obj->type);
3086                 return;
3087         }
3088
3089         obj->properties->ids[count] = property->base.id;
3090         obj->properties->values[count] = init_val;
3091         obj->properties->count++;
3092 }
3093 EXPORT_SYMBOL(drm_object_attach_property);
3094
3095 int drm_object_property_set_value(struct drm_mode_object *obj,
3096                                   struct drm_property *property, uint64_t val)
3097 {
3098         int i;
3099
3100         for (i = 0; i < obj->properties->count; i++) {
3101                 if (obj->properties->ids[i] == property->base.id) {
3102                         obj->properties->values[i] = val;
3103                         return 0;
3104                 }
3105         }
3106
3107         return -EINVAL;
3108 }
3109 EXPORT_SYMBOL(drm_object_property_set_value);
3110
3111 int drm_object_property_get_value(struct drm_mode_object *obj,
3112                                   struct drm_property *property, uint64_t *val)
3113 {
3114         int i;
3115
3116         for (i = 0; i < obj->properties->count; i++) {
3117                 if (obj->properties->ids[i] == property->base.id) {
3118                         *val = obj->properties->values[i];
3119                         return 0;
3120                 }
3121         }
3122
3123         return -EINVAL;
3124 }
3125 EXPORT_SYMBOL(drm_object_property_get_value);
3126
3127 int drm_mode_getproperty_ioctl(struct drm_device *dev,
3128                                void *data, struct drm_file *file_priv)
3129 {
3130         struct drm_mode_object *obj;
3131         struct drm_mode_get_property *out_resp = data;
3132         struct drm_property *property;
3133         int enum_count = 0;
3134         int blob_count = 0;
3135         int value_count = 0;
3136         int ret = 0, i;
3137         int copied;
3138         struct drm_property_enum *prop_enum;
3139         struct drm_mode_property_enum __user *enum_ptr;
3140         struct drm_property_blob *prop_blob;
3141         uint32_t __user *blob_id_ptr;
3142         uint64_t __user *values_ptr;
3143         uint32_t __user *blob_length_ptr;
3144
3145         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3146                 return -EINVAL;
3147
3148         drm_modeset_lock_all(dev);
3149         obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
3150         if (!obj) {
3151                 ret = -EINVAL;
3152                 goto done;
3153         }
3154         property = obj_to_property(obj);
3155
3156         if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
3157                 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
3158                         enum_count++;
3159         } else if (property->flags & DRM_MODE_PROP_BLOB) {
3160                 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
3161                         blob_count++;
3162         }
3163
3164         value_count = property->num_values;
3165
3166         strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
3167         out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
3168         out_resp->flags = property->flags;
3169
3170         if ((out_resp->count_values >= value_count) && value_count) {
3171                 values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr;
3172                 for (i = 0; i < value_count; i++) {
3173                         if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
3174                                 ret = -EFAULT;
3175                                 goto done;
3176                         }
3177                 }
3178         }
3179         out_resp->count_values = value_count;
3180
3181         if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
3182                 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
3183                         copied = 0;
3184                         enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
3185                         list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
3186
3187                                 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
3188                                         ret = -EFAULT;
3189                                         goto done;
3190                                 }
3191
3192                                 if (copy_to_user(&enum_ptr[copied].name,
3193                                                  &prop_enum->name, DRM_PROP_NAME_LEN)) {
3194                                         ret = -EFAULT;
3195                                         goto done;
3196                                 }
3197                                 copied++;
3198                         }
3199                 }
3200                 out_resp->count_enum_blobs = enum_count;
3201         }
3202
3203         if (property->flags & DRM_MODE_PROP_BLOB) {
3204                 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
3205                         copied = 0;
3206                         blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;
3207                         blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr;
3208
3209                         list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
3210                                 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
3211                                         ret = -EFAULT;
3212                                         goto done;
3213                                 }
3214
3215                                 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
3216                                         ret = -EFAULT;
3217                                         goto done;
3218                                 }
3219
3220                                 copied++;
3221                         }
3222                 }
3223                 out_resp->count_enum_blobs = blob_count;
3224         }
3225 done:
3226         drm_modeset_unlock_all(dev);
3227         return ret;
3228 }
3229
3230 static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
3231                                                           void *data)
3232 {
3233         struct drm_property_blob *blob;
3234         int ret;
3235
3236         if (!length || !data)
3237                 return NULL;
3238
3239         blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
3240         if (!blob)
3241                 return NULL;
3242
3243         ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
3244         if (ret) {
3245                 kfree(blob);
3246                 return NULL;
3247         }
3248
3249         blob->length = length;
3250
3251         memcpy(blob->data, data, length);
3252
3253         list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
3254         return blob;
3255 }
3256
3257 static void drm_property_destroy_blob(struct drm_device *dev,
3258                                struct drm_property_blob *blob)
3259 {
3260         drm_mode_object_put(dev, &blob->base);
3261         list_del(&blob->head);
3262         kfree(blob);
3263 }
3264
3265 int drm_mode_getblob_ioctl(struct drm_device *dev,
3266                            void *data, struct drm_file *file_priv)
3267 {
3268         struct drm_mode_object *obj;
3269         struct drm_mode_get_blob *out_resp = data;
3270         struct drm_property_blob *blob;
3271         int ret = 0;
3272         void __user *blob_ptr;
3273
3274         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3275                 return -EINVAL;
3276
3277         drm_modeset_lock_all(dev);
3278         obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
3279         if (!obj) {
3280                 ret = -EINVAL;
3281                 goto done;
3282         }
3283         blob = obj_to_blob(obj);
3284
3285         if (out_resp->length == blob->length) {
3286                 blob_ptr = (void __user *)(unsigned long)out_resp->data;
3287                 if (copy_to_user(blob_ptr, blob->data, blob->length)){
3288                         ret = -EFAULT;
3289                         goto done;
3290                 }
3291         }
3292         out_resp->length = blob->length;
3293
3294 done:
3295         drm_modeset_unlock_all(dev);
3296         return ret;
3297 }
3298
3299 int drm_mode_connector_update_edid_property(struct drm_connector *connector,
3300                                             struct edid *edid)
3301 {
3302         struct drm_device *dev = connector->dev;
3303         int ret, size;
3304
3305         if (connector->edid_blob_ptr)
3306                 drm_property_destroy_blob(dev, connector->edid_blob_ptr);
3307
3308         /* Delete edid, when there is none. */
3309         if (!edid) {
3310                 connector->edid_blob_ptr = NULL;
3311                 ret = drm_object_property_set_value(&connector->base, dev->mode_config.edid_property, 0);
3312                 return ret;
3313         }
3314
3315         size = EDID_LENGTH * (1 + edid->extensions);
3316         connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
3317                                                             size, edid);
3318         if (!connector->edid_blob_ptr)
3319                 return -EINVAL;
3320
3321         ret = drm_object_property_set_value(&connector->base,
3322                                                dev->mode_config.edid_property,
3323                                                connector->edid_blob_ptr->base.id);
3324
3325         return ret;
3326 }
3327 EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
3328
3329 static bool drm_property_change_is_valid(struct drm_property *property,
3330                                          uint64_t value)
3331 {
3332         if (property->flags & DRM_MODE_PROP_IMMUTABLE)
3333                 return false;
3334         if (property->flags & DRM_MODE_PROP_RANGE) {
3335                 if (value < property->values[0] || value > property->values[1])
3336                         return false;
3337                 return true;
3338         } else if (property->flags & DRM_MODE_PROP_BITMASK) {
3339                 int i;
3340                 uint64_t valid_mask = 0;
3341                 for (i = 0; i < property->num_values; i++)
3342                         valid_mask |= (1ULL << property->values[i]);
3343                 return !(value & ~valid_mask);
3344         } else if (property->flags & DRM_MODE_PROP_BLOB) {
3345                 /* Only the driver knows */
3346                 return true;
3347         } else {
3348                 int i;
3349                 for (i = 0; i < property->num_values; i++)
3350                         if (property->values[i] == value)
3351                                 return true;
3352                 return false;
3353         }
3354 }
3355
3356 int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
3357                                        void *data, struct drm_file *file_priv)
3358 {
3359         struct drm_mode_connector_set_property *conn_set_prop = data;
3360         struct drm_mode_obj_set_property obj_set_prop = {
3361                 .value = conn_set_prop->value,
3362                 .prop_id = conn_set_prop->prop_id,
3363                 .obj_id = conn_set_prop->connector_id,
3364                 .obj_type = DRM_MODE_OBJECT_CONNECTOR
3365         };
3366
3367         /* It does all the locking and checking we need */
3368         return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv);
3369 }
3370
3371 static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
3372                                            struct drm_property *property,
3373                                            uint64_t value)
3374 {
3375         int ret = -EINVAL;
3376         struct drm_connector *connector = obj_to_connector(obj);
3377
3378         /* Do DPMS ourselves */
3379         if (property == connector->dev->mode_config.dpms_property) {
3380                 if (connector->funcs->dpms)
3381                         (*connector->funcs->dpms)(connector, (int)value);
3382                 ret = 0;
3383         } else if (connector->funcs->set_property)
3384                 ret = connector->funcs->set_property(connector, property, value);
3385
3386         /* store the property value if successful */
3387         if (!ret)
3388                 drm_object_property_set_value(&connector->base, property, value);
3389         return ret;
3390 }
3391
3392 static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
3393                                       struct drm_property *property,
3394                                       uint64_t value)
3395 {
3396         int ret = -EINVAL;
3397         struct drm_crtc *crtc = obj_to_crtc(obj);
3398
3399         if (crtc->funcs->set_property)
3400                 ret = crtc->funcs->set_property(crtc, property, value);
3401         if (!ret)
3402                 drm_object_property_set_value(obj, property, value);
3403
3404         return ret;
3405 }
3406
3407 static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
3408                                       struct drm_property *property,
3409                                       uint64_t value)
3410 {
3411         int ret = -EINVAL;
3412         struct drm_plane *plane = obj_to_plane(obj);
3413
3414         if (plane->funcs->set_property)
3415                 ret = plane->funcs->set_property(plane, property, value);
3416         if (!ret)
3417                 drm_object_property_set_value(obj, property, value);
3418
3419         return ret;
3420 }
3421
3422 int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
3423                                       struct drm_file *file_priv)
3424 {
3425         struct drm_mode_obj_get_properties *arg = data;
3426         struct drm_mode_object *obj;
3427         int ret = 0;
3428         int i;
3429         int copied = 0;
3430         int props_count = 0;
3431         uint32_t __user *props_ptr;
3432         uint64_t __user *prop_values_ptr;
3433
3434         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3435                 return -EINVAL;
3436
3437         drm_modeset_lock_all(dev);
3438
3439         obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
3440         if (!obj) {
3441                 ret = -EINVAL;
3442                 goto out;
3443         }
3444         if (!obj->properties) {
3445                 ret = -EINVAL;
3446                 goto out;
3447         }
3448
3449         props_count = obj->properties->count;
3450
3451         /* This ioctl is called twice, once to determine how much space is
3452          * needed, and the 2nd time to fill it. */
3453         if ((arg->count_props >= props_count) && props_count) {
3454                 copied = 0;
3455                 props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
3456                 prop_values_ptr = (uint64_t __user *)(unsigned long)
3457                                   (arg->prop_values_ptr);
3458                 for (i = 0; i < props_count; i++) {
3459                         if (put_user(obj->properties->ids[i],
3460                                      props_ptr + copied)) {
3461                                 ret = -EFAULT;
3462                                 goto out;
3463                         }
3464                         if (put_user(obj->properties->values[i],
3465                                      prop_values_ptr + copied)) {
3466                                 ret = -EFAULT;
3467                                 goto out;
3468                         }
3469                         copied++;
3470                 }
3471         }
3472         arg->count_props = props_count;
3473 out:
3474         drm_modeset_unlock_all(dev);
3475         return ret;
3476 }
3477
3478 int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
3479                                     struct drm_file *file_priv)
3480 {
3481         struct drm_mode_obj_set_property *arg = data;
3482         struct drm_mode_object *arg_obj;
3483         struct drm_mode_object *prop_obj;
3484         struct drm_property *property;
3485         int ret = -EINVAL;
3486         int i;
3487
3488         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3489                 return -EINVAL;
3490
3491         drm_modeset_lock_all(dev);
3492
3493         arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
3494         if (!arg_obj)
3495                 goto out;
3496         if (!arg_obj->properties)
3497                 goto out;
3498
3499         for (i = 0; i < arg_obj->properties->count; i++)
3500                 if (arg_obj->properties->ids[i] == arg->prop_id)
3501                         break;
3502
3503         if (i == arg_obj->properties->count)
3504                 goto out;
3505
3506         prop_obj = drm_mode_object_find(dev, arg->prop_id,
3507                                         DRM_MODE_OBJECT_PROPERTY);
3508         if (!prop_obj)
3509                 goto out;
3510         property = obj_to_property(prop_obj);
3511
3512         if (!drm_property_change_is_valid(property, arg->value))
3513                 goto out;
3514
3515         switch (arg_obj->type) {
3516         case DRM_MODE_OBJECT_CONNECTOR:
3517                 ret = drm_mode_connector_set_obj_prop(arg_obj, property,
3518                                                       arg->value);
3519                 break;
3520         case DRM_MODE_OBJECT_CRTC:
3521                 ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
3522                 break;
3523         case DRM_MODE_OBJECT_PLANE:
3524                 ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value);
3525                 break;
3526         }
3527
3528 out:
3529         drm_modeset_unlock_all(dev);
3530         return ret;
3531 }
3532
3533 int drm_mode_connector_attach_encoder(struct drm_connector *connector,
3534                                       struct drm_encoder *encoder)
3535 {
3536         int i;
3537
3538         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
3539                 if (connector->encoder_ids[i] == 0) {
3540                         connector->encoder_ids[i] = encoder->base.id;
3541                         return 0;
3542                 }
3543         }
3544         return -ENOMEM;
3545 }
3546 EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
3547
3548 void drm_mode_connector_detach_encoder(struct drm_connector *connector,
3549                                     struct drm_encoder *encoder)
3550 {
3551         int i;
3552         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
3553                 if (connector->encoder_ids[i] == encoder->base.id) {
3554                         connector->encoder_ids[i] = 0;
3555                         if (connector->encoder == encoder)
3556                                 connector->encoder = NULL;
3557                         break;
3558                 }
3559         }
3560 }
3561 EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
3562
3563 int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
3564                                   int gamma_size)
3565 {
3566         crtc->gamma_size = gamma_size;
3567
3568         crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
3569         if (!crtc->gamma_store) {
3570                 crtc->gamma_size = 0;
3571                 return -ENOMEM;
3572         }
3573
3574         return 0;
3575 }
3576 EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
3577
3578 int drm_mode_gamma_set_ioctl(struct drm_device *dev,
3579                              void *data, struct drm_file *file_priv)
3580 {
3581         struct drm_mode_crtc_lut *crtc_lut = data;
3582         struct drm_mode_object *obj;
3583         struct drm_crtc *crtc;
3584         void *r_base, *g_base, *b_base;
3585         int size;
3586         int ret = 0;
3587
3588         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3589                 return -EINVAL;
3590
3591         drm_modeset_lock_all(dev);
3592         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
3593         if (!obj) {
3594                 ret = -EINVAL;
3595                 goto out;
3596         }
3597         crtc = obj_to_crtc(obj);
3598
3599         if (crtc->funcs->gamma_set == NULL) {
3600                 ret = -ENOSYS;
3601                 goto out;
3602         }
3603
3604         /* memcpy into gamma store */
3605         if (crtc_lut->gamma_size != crtc->gamma_size) {
3606                 ret = -EINVAL;
3607                 goto out;
3608         }
3609
3610         size = crtc_lut->gamma_size * (sizeof(uint16_t));
3611         r_base = crtc->gamma_store;
3612         if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
3613                 ret = -EFAULT;
3614                 goto out;
3615         }
3616
3617         g_base = r_base + size;
3618         if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
3619                 ret = -EFAULT;
3620                 goto out;
3621         }
3622
3623         b_base = g_base + size;
3624         if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
3625                 ret = -EFAULT;
3626                 goto out;
3627         }
3628
3629         crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
3630
3631 out:
3632         drm_modeset_unlock_all(dev);
3633         return ret;
3634
3635 }
3636
3637 int drm_mode_gamma_get_ioctl(struct drm_device *dev,
3638                              void *data, struct drm_file *file_priv)
3639 {
3640         struct drm_mode_crtc_lut *crtc_lut = data;
3641         struct drm_mode_object *obj;
3642         struct drm_crtc *crtc;
3643         void *r_base, *g_base, *b_base;
3644         int size;
3645         int ret = 0;
3646
3647         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3648                 return -EINVAL;
3649
3650         drm_modeset_lock_all(dev);
3651         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
3652         if (!obj) {
3653                 ret = -EINVAL;
3654                 goto out;
3655         }
3656         crtc = obj_to_crtc(obj);
3657
3658         /* memcpy into gamma store */
3659         if (crtc_lut->gamma_size != crtc->gamma_size) {
3660                 ret = -EINVAL;
3661                 goto out;
3662         }
3663
3664         size = crtc_lut->gamma_size * (sizeof(uint16_t));
3665         r_base = crtc->gamma_store;
3666         if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
3667                 ret = -EFAULT;
3668                 goto out;
3669         }
3670
3671         g_base = r_base + size;
3672         if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
3673                 ret = -EFAULT;
3674                 goto out;
3675         }
3676
3677         b_base = g_base + size;
3678         if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
3679                 ret = -EFAULT;
3680                 goto out;
3681         }
3682 out:
3683         drm_modeset_unlock_all(dev);
3684         return ret;
3685 }
3686
3687 int drm_mode_page_flip_ioctl(struct drm_device *dev,
3688                              void *data, struct drm_file *file_priv)
3689 {
3690         struct drm_mode_crtc_page_flip *page_flip = data;
3691         struct drm_mode_object *obj;
3692         struct drm_crtc *crtc;
3693         struct drm_framebuffer *fb = NULL, *old_fb = NULL;
3694         struct drm_pending_vblank_event *e = NULL;
3695         unsigned long flags;
3696         int hdisplay, vdisplay;
3697         int ret = -EINVAL;
3698
3699         if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
3700             page_flip->reserved != 0)
3701                 return -EINVAL;
3702
3703         obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC);
3704         if (!obj)
3705                 return -EINVAL;
3706         crtc = obj_to_crtc(obj);
3707
3708         mutex_lock(&crtc->mutex);
3709         if (crtc->fb == NULL) {
3710                 /* The framebuffer is currently unbound, presumably
3711                  * due to a hotplug event, that userspace has not
3712                  * yet discovered.
3713                  */
3714                 ret = -EBUSY;
3715                 goto out;
3716         }
3717
3718         if (crtc->funcs->page_flip == NULL)
3719                 goto out;
3720
3721         fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
3722         if (!fb)
3723                 goto out;
3724
3725         hdisplay = crtc->mode.hdisplay;
3726         vdisplay = crtc->mode.vdisplay;
3727
3728         if (crtc->invert_dimensions)
3729                 swap(hdisplay, vdisplay);
3730
3731         if (hdisplay > fb->width ||
3732             vdisplay > fb->height ||
3733             crtc->x > fb->width - hdisplay ||
3734             crtc->y > fb->height - vdisplay) {
3735                 DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
3736                               fb->width, fb->height, hdisplay, vdisplay, crtc->x, crtc->y,
3737                               crtc->invert_dimensions ? " (inverted)" : "");
3738                 ret = -ENOSPC;
3739                 goto out;
3740         }
3741
3742         if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
3743                 ret = -ENOMEM;
3744                 spin_lock_irqsave(&dev->event_lock, flags);
3745                 if (file_priv->event_space < sizeof e->event) {
3746                         spin_unlock_irqrestore(&dev->event_lock, flags);
3747                         goto out;
3748                 }
3749                 file_priv->event_space -= sizeof e->event;
3750                 spin_unlock_irqrestore(&dev->event_lock, flags);
3751
3752                 e = kzalloc(sizeof *e, GFP_KERNEL);
3753                 if (e == NULL) {
3754                         spin_lock_irqsave(&dev->event_lock, flags);
3755                         file_priv->event_space += sizeof e->event;
3756                         spin_unlock_irqrestore(&dev->event_lock, flags);
3757                         goto out;
3758                 }
3759
3760                 e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
3761                 e->event.base.length = sizeof e->event;
3762                 e->event.user_data = page_flip->user_data;
3763                 e->base.event = &e->event.base;
3764                 e->base.file_priv = file_priv;
3765                 e->base.destroy =
3766                         (void (*) (struct drm_pending_event *)) kfree;
3767         }
3768
3769         old_fb = crtc->fb;
3770         ret = crtc->funcs->page_flip(crtc, fb, e);
3771         if (ret) {
3772                 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
3773                         spin_lock_irqsave(&dev->event_lock, flags);
3774                         file_priv->event_space += sizeof e->event;
3775                         spin_unlock_irqrestore(&dev->event_lock, flags);
3776                         kfree(e);
3777                 }
3778                 /* Keep the old fb, don't unref it. */
3779                 old_fb = NULL;
3780         } else {
3781                 /*
3782                  * Warn if the driver hasn't properly updated the crtc->fb
3783                  * field to reflect that the new framebuffer is now used.
3784                  * Failing to do so will screw with the reference counting
3785                  * on framebuffers.
3786                  */
3787                 WARN_ON(crtc->fb != fb);
3788                 /* Unref only the old framebuffer. */
3789                 fb = NULL;
3790         }
3791
3792 out:
3793         if (fb)
3794                 drm_framebuffer_unreference(fb);
3795         if (old_fb)
3796                 drm_framebuffer_unreference(old_fb);
3797         mutex_unlock(&crtc->mutex);
3798
3799         return ret;
3800 }
3801
3802 void drm_mode_config_reset(struct drm_device *dev)
3803 {
3804         struct drm_crtc *crtc;
3805         struct drm_encoder *encoder;
3806         struct drm_connector *connector;
3807
3808         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
3809                 if (crtc->funcs->reset)
3810                         crtc->funcs->reset(crtc);
3811
3812         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
3813                 if (encoder->funcs->reset)
3814                         encoder->funcs->reset(encoder);
3815
3816         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
3817                 connector->status = connector_status_unknown;
3818
3819                 if (connector->funcs->reset)
3820                         connector->funcs->reset(connector);
3821         }
3822 }
3823 EXPORT_SYMBOL(drm_mode_config_reset);
3824
3825 int drm_mode_create_dumb_ioctl(struct drm_device *dev,
3826                                void *data, struct drm_file *file_priv)
3827 {
3828         struct drm_mode_create_dumb *args = data;
3829
3830         if (!dev->driver->dumb_create)
3831                 return -ENOSYS;
3832         return dev->driver->dumb_create(file_priv, dev, args);
3833 }
3834
3835 int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
3836                              void *data, struct drm_file *file_priv)
3837 {
3838         struct drm_mode_map_dumb *args = data;
3839
3840         /* call driver ioctl to get mmap offset */
3841         if (!dev->driver->dumb_map_offset)
3842                 return -ENOSYS;
3843
3844         return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
3845 }
3846
3847 int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
3848                                 void *data, struct drm_file *file_priv)
3849 {
3850         struct drm_mode_destroy_dumb *args = data;
3851
3852         if (!dev->driver->dumb_destroy)
3853                 return -ENOSYS;
3854
3855         return dev->driver->dumb_destroy(file_priv, dev, args->handle);
3856 }
3857
3858 /*
3859  * Just need to support RGB formats here for compat with code that doesn't
3860  * use pixel formats directly yet.
3861  */
3862 void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
3863                           int *bpp)
3864 {
3865         switch (format) {
3866         case DRM_FORMAT_C8:
3867         case DRM_FORMAT_RGB332:
3868         case DRM_FORMAT_BGR233:
3869                 *depth = 8;
3870                 *bpp = 8;
3871                 break;
3872         case DRM_FORMAT_XRGB1555:
3873         case DRM_FORMAT_XBGR1555:
3874         case DRM_FORMAT_RGBX5551:
3875         case DRM_FORMAT_BGRX5551:
3876         case DRM_FORMAT_ARGB1555:
3877         case DRM_FORMAT_ABGR1555:
3878         case DRM_FORMAT_RGBA5551:
3879         case DRM_FORMAT_BGRA5551:
3880                 *depth = 15;
3881                 *bpp = 16;
3882                 break;
3883         case DRM_FORMAT_RGB565:
3884         case DRM_FORMAT_BGR565:
3885                 *depth = 16;
3886                 *bpp = 16;
3887                 break;
3888         case DRM_FORMAT_RGB888:
3889         case DRM_FORMAT_BGR888:
3890                 *depth = 24;
3891                 *bpp = 24;
3892                 break;
3893         case DRM_FORMAT_XRGB8888:
3894         case DRM_FORMAT_XBGR8888:
3895         case DRM_FORMAT_RGBX8888:
3896         case DRM_FORMAT_BGRX8888:
3897                 *depth = 24;
3898                 *bpp = 32;
3899                 break;
3900         case DRM_FORMAT_XRGB2101010:
3901         case DRM_FORMAT_XBGR2101010:
3902         case DRM_FORMAT_RGBX1010102:
3903         case DRM_FORMAT_BGRX1010102:
3904         case DRM_FORMAT_ARGB2101010:
3905         case DRM_FORMAT_ABGR2101010:
3906         case DRM_FORMAT_RGBA1010102:
3907         case DRM_FORMAT_BGRA1010102:
3908                 *depth = 30;
3909                 *bpp = 32;
3910                 break;
3911         case DRM_FORMAT_ARGB8888:
3912         case DRM_FORMAT_ABGR8888:
3913         case DRM_FORMAT_RGBA8888:
3914         case DRM_FORMAT_BGRA8888:
3915                 *depth = 32;
3916                 *bpp = 32;
3917                 break;
3918         default:
3919                 DRM_DEBUG_KMS("unsupported pixel format\n");
3920                 *depth = 0;
3921                 *bpp = 0;
3922                 break;
3923         }
3924 }
3925 EXPORT_SYMBOL(drm_fb_get_bpp_depth);
3926
3927 /**
3928  * drm_format_num_planes - get the number of planes for format
3929  * @format: pixel format (DRM_FORMAT_*)
3930  *
3931  * RETURNS:
3932  * The number of planes used by the specified pixel format.
3933  */
3934 int drm_format_num_planes(uint32_t format)
3935 {
3936         switch (format) {
3937         case DRM_FORMAT_YUV410:
3938         case DRM_FORMAT_YVU410:
3939         case DRM_FORMAT_YUV411:
3940         case DRM_FORMAT_YVU411:
3941         case DRM_FORMAT_YUV420:
3942         case DRM_FORMAT_YVU420:
3943         case DRM_FORMAT_YUV422:
3944         case DRM_FORMAT_YVU422:
3945         case DRM_FORMAT_YUV444:
3946         case DRM_FORMAT_YVU444:
3947                 return 3;
3948         case DRM_FORMAT_NV12:
3949         case DRM_FORMAT_NV21:
3950         case DRM_FORMAT_NV16:
3951         case DRM_FORMAT_NV61:
3952         case DRM_FORMAT_NV24:
3953         case DRM_FORMAT_NV42:
3954                 return 2;
3955         default:
3956                 return 1;
3957         }
3958 }
3959 EXPORT_SYMBOL(drm_format_num_planes);
3960
3961 /**
3962  * drm_format_plane_cpp - determine the bytes per pixel value
3963  * @format: pixel format (DRM_FORMAT_*)
3964  * @plane: plane index
3965  *
3966  * RETURNS:
3967  * The bytes per pixel value for the specified plane.
3968  */
3969 int drm_format_plane_cpp(uint32_t format, int plane)
3970 {
3971         unsigned int depth;
3972         int bpp;
3973
3974         if (plane >= drm_format_num_planes(format))
3975                 return 0;
3976
3977         switch (format) {
3978         case DRM_FORMAT_YUYV:
3979         case DRM_FORMAT_YVYU:
3980         case DRM_FORMAT_UYVY:
3981         case DRM_FORMAT_VYUY:
3982                 return 2;
3983         case DRM_FORMAT_NV12:
3984         case DRM_FORMAT_NV21:
3985         case DRM_FORMAT_NV16:
3986         case DRM_FORMAT_NV61:
3987         case DRM_FORMAT_NV24:
3988         case DRM_FORMAT_NV42:
3989                 return plane ? 2 : 1;
3990         case DRM_FORMAT_YUV410:
3991         case DRM_FORMAT_YVU410:
3992         case DRM_FORMAT_YUV411:
3993         case DRM_FORMAT_YVU411:
3994         case DRM_FORMAT_YUV420:
3995         case DRM_FORMAT_YVU420:
3996         case DRM_FORMAT_YUV422:
3997         case DRM_FORMAT_YVU422:
3998         case DRM_FORMAT_YUV444:
3999         case DRM_FORMAT_YVU444:
4000                 return 1;
4001         default:
4002                 drm_fb_get_bpp_depth(format, &depth, &bpp);
4003                 return bpp >> 3;
4004         }
4005 }
4006 EXPORT_SYMBOL(drm_format_plane_cpp);
4007
4008 /**
4009  * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
4010  * @format: pixel format (DRM_FORMAT_*)
4011  *
4012  * RETURNS:
4013  * The horizontal chroma subsampling factor for the
4014  * specified pixel format.
4015  */
4016 int drm_format_horz_chroma_subsampling(uint32_t format)
4017 {
4018         switch (format) {
4019         case DRM_FORMAT_YUV411:
4020         case DRM_FORMAT_YVU411:
4021         case DRM_FORMAT_YUV410:
4022         case DRM_FORMAT_YVU410:
4023                 return 4;
4024         case DRM_FORMAT_YUYV:
4025         case DRM_FORMAT_YVYU:
4026         case DRM_FORMAT_UYVY:
4027         case DRM_FORMAT_VYUY:
4028         case DRM_FORMAT_NV12:
4029         case DRM_FORMAT_NV21:
4030         case DRM_FORMAT_NV16:
4031         case DRM_FORMAT_NV61:
4032         case DRM_FORMAT_YUV422:
4033         case DRM_FORMAT_YVU422:
4034         case DRM_FORMAT_YUV420:
4035         case DRM_FORMAT_YVU420:
4036                 return 2;
4037         default:
4038                 return 1;
4039         }
4040 }
4041 EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
4042
4043 /**
4044  * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
4045  * @format: pixel format (DRM_FORMAT_*)
4046  *
4047  * RETURNS:
4048  * The vertical chroma subsampling factor for the
4049  * specified pixel format.
4050  */
4051 int drm_format_vert_chroma_subsampling(uint32_t format)
4052 {
4053         switch (format) {
4054         case DRM_FORMAT_YUV410:
4055         case DRM_FORMAT_YVU410:
4056                 return 4;
4057         case DRM_FORMAT_YUV420:
4058         case DRM_FORMAT_YVU420:
4059         case DRM_FORMAT_NV12:
4060         case DRM_FORMAT_NV21:
4061                 return 2;
4062         default:
4063                 return 1;
4064         }
4065 }
4066 EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);