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