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