[go: nahoru, domu]

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