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