[go: nahoru, domu]

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