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