[go: nahoru, domu]

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