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