Line data Source code
1 : /*
2 : * Copyright (c) 2006-2008 Intel Corporation
3 : * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
4 : * Copyright (c) 2008 Red Hat Inc.
5 : *
6 : * DRM core CRTC related functions
7 : *
8 : * Permission to use, copy, modify, distribute, and sell this software and its
9 : * documentation for any purpose is hereby granted without fee, provided that
10 : * the above copyright notice appear in all copies and that both that copyright
11 : * notice and this permission notice appear in supporting documentation, and
12 : * that the name of the copyright holders not be used in advertising or
13 : * publicity pertaining to distribution of the software without specific,
14 : * written prior permission. The copyright holders make no representations
15 : * about the suitability of this software for any purpose. It is provided "as
16 : * is" without express or implied warranty.
17 : *
18 : * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 : * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 : * OF THIS SOFTWARE.
25 : *
26 : * Authors:
27 : * Keith Packard
28 : * Eric Anholt <eric@anholt.net>
29 : * Dave Airlie <airlied@linux.ie>
30 : * Jesse Barnes <jesse.barnes@intel.com>
31 : */
32 : #ifdef __linux__
33 : #include <linux/ctype.h>
34 : #include <linux/list.h>
35 : #include <linux/slab.h>
36 : #include <linux/export.h>
37 : #endif
38 : #include <dev/pci/drm/drmP.h>
39 : #include <dev/pci/drm/drm_crtc.h>
40 : #include <dev/pci/drm/drm_edid.h>
41 : #include <dev/pci/drm/drm_fourcc.h>
42 : #include <dev/pci/drm/drm_modeset_lock.h>
43 : #include <dev/pci/drm/drm_atomic.h>
44 :
45 : #include "drm_crtc_internal.h"
46 : #include "drm_internal.h"
47 :
48 : static struct drm_framebuffer *
49 : internal_framebuffer_create(struct drm_device *dev,
50 : struct drm_mode_fb_cmd2 *r,
51 : struct drm_file *file_priv);
52 :
53 : /* Avoid boilerplate. I'm tired of typing. */
54 : #define DRM_ENUM_NAME_FN(fnname, list) \
55 : const char *fnname(int val) \
56 : { \
57 : int i; \
58 : for (i = 0; i < ARRAY_SIZE(list); i++) { \
59 : if (list[i].type == val) \
60 : return list[i].name; \
61 : } \
62 : return "(unknown)"; \
63 : }
64 :
65 : /*
66 : * Global properties
67 : */
68 : static const struct drm_prop_enum_list drm_dpms_enum_list[] = {
69 : { DRM_MODE_DPMS_ON, "On" },
70 : { DRM_MODE_DPMS_STANDBY, "Standby" },
71 : { DRM_MODE_DPMS_SUSPEND, "Suspend" },
72 : { DRM_MODE_DPMS_OFF, "Off" }
73 : };
74 :
75 0 : DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
76 :
77 : static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
78 : { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
79 : { DRM_PLANE_TYPE_PRIMARY, "Primary" },
80 : { DRM_PLANE_TYPE_CURSOR, "Cursor" },
81 : };
82 :
83 : /*
84 : * Optional properties
85 : */
86 : static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = {
87 : { DRM_MODE_SCALE_NONE, "None" },
88 : { DRM_MODE_SCALE_FULLSCREEN, "Full" },
89 : { DRM_MODE_SCALE_CENTER, "Center" },
90 : { DRM_MODE_SCALE_ASPECT, "Full aspect" },
91 : };
92 :
93 : static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
94 : { DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" },
95 : { DRM_MODE_PICTURE_ASPECT_4_3, "4:3" },
96 : { DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
97 : };
98 :
99 : /*
100 : * Non-global properties, but "required" for certain connectors.
101 : */
102 : static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
103 : { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
104 : { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
105 : { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
106 : };
107 :
108 0 : DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
109 :
110 : static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = {
111 : { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
112 : { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
113 : { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
114 : };
115 :
116 0 : DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
117 : drm_dvi_i_subconnector_enum_list)
118 :
119 : static const struct drm_prop_enum_list drm_tv_select_enum_list[] = {
120 : { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
121 : { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
122 : { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
123 : { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
124 : { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
125 : };
126 :
127 0 : DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
128 :
129 : static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
130 : { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
131 : { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
132 : { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
133 : { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
134 : { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
135 : };
136 :
137 0 : DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
138 : drm_tv_subconnector_enum_list)
139 :
140 : static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
141 : { DRM_MODE_DIRTY_OFF, "Off" },
142 : { DRM_MODE_DIRTY_ON, "On" },
143 : { DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
144 : };
145 :
146 : struct drm_conn_prop_enum_list {
147 : int type;
148 : const char *name;
149 : struct ida ida;
150 : };
151 :
152 : /*
153 : * Connector and encoder types.
154 : */
155 : static struct drm_conn_prop_enum_list drm_connector_enum_list[] = {
156 : { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
157 : { DRM_MODE_CONNECTOR_VGA, "VGA" },
158 : { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
159 : { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
160 : { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
161 : { DRM_MODE_CONNECTOR_Composite, "Composite" },
162 : { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },
163 : { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
164 : { DRM_MODE_CONNECTOR_Component, "Component" },
165 : { DRM_MODE_CONNECTOR_9PinDIN, "DIN" },
166 : { DRM_MODE_CONNECTOR_DisplayPort, "DP" },
167 : { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
168 : { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
169 : { DRM_MODE_CONNECTOR_TV, "TV" },
170 : { DRM_MODE_CONNECTOR_eDP, "eDP" },
171 : { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
172 : { DRM_MODE_CONNECTOR_DSI, "DSI" },
173 : };
174 :
175 : static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
176 : { DRM_MODE_ENCODER_NONE, "None" },
177 : { DRM_MODE_ENCODER_DAC, "DAC" },
178 : { DRM_MODE_ENCODER_TMDS, "TMDS" },
179 : { DRM_MODE_ENCODER_LVDS, "LVDS" },
180 : { DRM_MODE_ENCODER_TVDAC, "TV" },
181 : { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
182 : { DRM_MODE_ENCODER_DSI, "DSI" },
183 : { DRM_MODE_ENCODER_DPMST, "DP MST" },
184 : };
185 :
186 : static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
187 : { SubPixelUnknown, "Unknown" },
188 : { SubPixelHorizontalRGB, "Horizontal RGB" },
189 : { SubPixelHorizontalBGR, "Horizontal BGR" },
190 : { SubPixelVerticalRGB, "Vertical RGB" },
191 : { SubPixelVerticalBGR, "Vertical BGR" },
192 : { SubPixelNone, "None" },
193 : };
194 :
195 0 : void drm_connector_ida_init(void)
196 : {
197 : int i;
198 :
199 0 : for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)
200 0 : ida_init(&drm_connector_enum_list[i].ida);
201 0 : }
202 :
203 0 : void drm_connector_ida_destroy(void)
204 : {
205 : int i;
206 :
207 0 : for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)
208 0 : ida_destroy(&drm_connector_enum_list[i].ida);
209 0 : }
210 :
211 : /**
212 : * drm_get_connector_status_name - return a string for connector status
213 : * @status: connector status to compute name of
214 : *
215 : * In contrast to the other drm_get_*_name functions this one here returns a
216 : * const pointer and hence is threadsafe.
217 : */
218 0 : const char *drm_get_connector_status_name(enum drm_connector_status status)
219 : {
220 0 : if (status == connector_status_connected)
221 0 : return "connected";
222 0 : else if (status == connector_status_disconnected)
223 0 : return "disconnected";
224 : else
225 0 : return "unknown";
226 0 : }
227 : EXPORT_SYMBOL(drm_get_connector_status_name);
228 :
229 : /**
230 : * drm_get_subpixel_order_name - return a string for a given subpixel enum
231 : * @order: enum of subpixel_order
232 : *
233 : * Note you could abuse this and return something out of bounds, but that
234 : * would be a caller error. No unscrubbed user data should make it here.
235 : */
236 0 : const char *drm_get_subpixel_order_name(enum subpixel_order order)
237 : {
238 0 : return drm_subpixel_enum_list[order].name;
239 : }
240 : EXPORT_SYMBOL(drm_get_subpixel_order_name);
241 :
242 0 : static char printable_char(int c)
243 : {
244 0 : return isascii(c) && isprint(c) ? c : '?';
245 : }
246 :
247 : /**
248 : * drm_get_format_name - return a string for drm fourcc format
249 : * @format: format to compute name of
250 : *
251 : * Note that the buffer used by this function is globally shared and owned by
252 : * the function itself.
253 : *
254 : * FIXME: This isn't really multithreading safe.
255 : */
256 0 : const char *drm_get_format_name(uint32_t format)
257 : {
258 : static char buf[32];
259 :
260 0 : snprintf(buf, sizeof(buf),
261 : "%c%c%c%c %s-endian (0x%08x)",
262 0 : printable_char(format & 0xff),
263 0 : printable_char((format >> 8) & 0xff),
264 0 : printable_char((format >> 16) & 0xff),
265 0 : printable_char((format >> 24) & 0x7f),
266 0 : format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
267 : format);
268 :
269 0 : return buf;
270 : }
271 : EXPORT_SYMBOL(drm_get_format_name);
272 :
273 : /*
274 : * Internal function to assign a slot in the object idr and optionally
275 : * register the object into the idr.
276 : */
277 0 : static int drm_mode_object_get_reg(struct drm_device *dev,
278 : struct drm_mode_object *obj,
279 : uint32_t obj_type,
280 : bool register_obj)
281 : {
282 : int ret;
283 :
284 0 : mutex_lock(&dev->mode_config.idr_mutex);
285 0 : ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL);
286 0 : if (ret >= 0) {
287 : /*
288 : * Set up the object linking under the protection of the idr
289 : * lock so that other users can't see inconsistent state.
290 : */
291 0 : obj->id = ret;
292 0 : obj->type = obj_type;
293 0 : }
294 0 : mutex_unlock(&dev->mode_config.idr_mutex);
295 :
296 0 : return ret < 0 ? ret : 0;
297 : }
298 :
299 : /**
300 : * drm_mode_object_get - allocate a new modeset identifier
301 : * @dev: DRM device
302 : * @obj: object pointer, used to generate unique ID
303 : * @obj_type: object type
304 : *
305 : * Create a unique identifier based on @ptr in @dev's identifier space. Used
306 : * for tracking modes, CRTCs and connectors. Note that despite the _get postfix
307 : * modeset identifiers are _not_ reference counted. Hence don't use this for
308 : * reference counted modeset objects like framebuffers.
309 : *
310 : * Returns:
311 : * Zero on success, error code on failure.
312 : */
313 0 : int drm_mode_object_get(struct drm_device *dev,
314 : struct drm_mode_object *obj, uint32_t obj_type)
315 : {
316 0 : return drm_mode_object_get_reg(dev, obj, obj_type, true);
317 : }
318 :
319 0 : static void drm_mode_object_register(struct drm_device *dev,
320 : struct drm_mode_object *obj)
321 : {
322 0 : mutex_lock(&dev->mode_config.idr_mutex);
323 0 : idr_replace(&dev->mode_config.crtc_idr, obj, obj->id);
324 0 : mutex_unlock(&dev->mode_config.idr_mutex);
325 0 : }
326 :
327 : /**
328 : * drm_mode_object_put - free a modeset identifer
329 : * @dev: DRM device
330 : * @object: object to free
331 : *
332 : * Free @id from @dev's unique identifier pool. Note that despite the _get
333 : * postfix modeset identifiers are _not_ reference counted. Hence don't use this
334 : * for reference counted modeset objects like framebuffers.
335 : */
336 0 : void drm_mode_object_put(struct drm_device *dev,
337 : struct drm_mode_object *object)
338 : {
339 0 : mutex_lock(&dev->mode_config.idr_mutex);
340 0 : idr_remove(&dev->mode_config.crtc_idr, object->id);
341 0 : mutex_unlock(&dev->mode_config.idr_mutex);
342 0 : }
343 :
344 0 : static struct drm_mode_object *_object_find(struct drm_device *dev,
345 : uint32_t id, uint32_t type)
346 : {
347 : struct drm_mode_object *obj = NULL;
348 :
349 0 : mutex_lock(&dev->mode_config.idr_mutex);
350 0 : obj = idr_find(&dev->mode_config.crtc_idr, id);
351 0 : if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
352 0 : obj = NULL;
353 0 : if (obj && obj->id != id)
354 0 : obj = NULL;
355 : /* don't leak out unref'd fb's */
356 0 : if (obj &&
357 0 : (obj->type == DRM_MODE_OBJECT_FB ||
358 0 : obj->type == DRM_MODE_OBJECT_BLOB))
359 0 : obj = NULL;
360 0 : mutex_unlock(&dev->mode_config.idr_mutex);
361 :
362 0 : return obj;
363 : }
364 :
365 : /**
366 : * drm_mode_object_find - look up a drm object with static lifetime
367 : * @dev: drm device
368 : * @id: id of the mode object
369 : * @type: type of the mode object
370 : *
371 : * Note that framebuffers cannot be looked up with this functions - since those
372 : * are reference counted, they need special treatment. Even with
373 : * DRM_MODE_OBJECT_ANY (although that will simply return NULL
374 : * rather than WARN_ON()).
375 : */
376 0 : struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
377 : uint32_t id, uint32_t type)
378 : {
379 : struct drm_mode_object *obj = NULL;
380 :
381 : /* Framebuffers are reference counted and need their own lookup
382 : * function.*/
383 0 : WARN_ON(type == DRM_MODE_OBJECT_FB || type == DRM_MODE_OBJECT_BLOB);
384 0 : obj = _object_find(dev, id, type);
385 0 : return obj;
386 : }
387 : EXPORT_SYMBOL(drm_mode_object_find);
388 :
389 : /**
390 : * drm_framebuffer_init - initialize a framebuffer
391 : * @dev: DRM device
392 : * @fb: framebuffer to be initialized
393 : * @funcs: ... with these functions
394 : *
395 : * Allocates an ID for the framebuffer's parent mode object, sets its mode
396 : * functions & device file and adds it to the master fd list.
397 : *
398 : * IMPORTANT:
399 : * This functions publishes the fb and makes it available for concurrent access
400 : * by other users. Which means by this point the fb _must_ be fully set up -
401 : * since all the fb attributes are invariant over its lifetime, no further
402 : * locking but only correct reference counting is required.
403 : *
404 : * Returns:
405 : * Zero on success, error code on failure.
406 : */
407 0 : int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
408 : const struct drm_framebuffer_funcs *funcs)
409 : {
410 : int ret;
411 :
412 0 : mutex_lock(&dev->mode_config.fb_lock);
413 0 : kref_init(&fb->refcount);
414 0 : INIT_LIST_HEAD(&fb->filp_head);
415 0 : fb->dev = dev;
416 0 : fb->funcs = funcs;
417 :
418 0 : ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
419 0 : if (ret)
420 : goto out;
421 :
422 0 : dev->mode_config.num_fb++;
423 0 : list_add(&fb->head, &dev->mode_config.fb_list);
424 : out:
425 0 : mutex_unlock(&dev->mode_config.fb_lock);
426 :
427 0 : return ret;
428 : }
429 : EXPORT_SYMBOL(drm_framebuffer_init);
430 :
431 : /* dev->mode_config.fb_lock must be held! */
432 0 : static void __drm_framebuffer_unregister(struct drm_device *dev,
433 : struct drm_framebuffer *fb)
434 : {
435 0 : mutex_lock(&dev->mode_config.idr_mutex);
436 0 : idr_remove(&dev->mode_config.crtc_idr, fb->base.id);
437 0 : mutex_unlock(&dev->mode_config.idr_mutex);
438 :
439 0 : fb->base.id = 0;
440 0 : }
441 :
442 0 : static void drm_framebuffer_free(struct kref *kref)
443 : {
444 : struct drm_framebuffer *fb =
445 0 : container_of(kref, struct drm_framebuffer, refcount);
446 0 : struct drm_device *dev = fb->dev;
447 :
448 : /*
449 : * The lookup idr holds a weak reference, which has not necessarily been
450 : * removed at this point. Check for that.
451 : */
452 0 : mutex_lock(&dev->mode_config.fb_lock);
453 0 : if (fb->base.id) {
454 : /* Mark fb as reaped and drop idr ref. */
455 0 : __drm_framebuffer_unregister(dev, fb);
456 0 : }
457 0 : mutex_unlock(&dev->mode_config.fb_lock);
458 :
459 0 : fb->funcs->destroy(fb);
460 0 : }
461 :
462 0 : static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev,
463 : uint32_t id)
464 : {
465 : struct drm_mode_object *obj = NULL;
466 : struct drm_framebuffer *fb;
467 :
468 0 : mutex_lock(&dev->mode_config.idr_mutex);
469 0 : obj = idr_find(&dev->mode_config.crtc_idr, id);
470 0 : if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id))
471 0 : fb = NULL;
472 : else
473 0 : fb = obj_to_fb(obj);
474 0 : mutex_unlock(&dev->mode_config.idr_mutex);
475 :
476 0 : return fb;
477 : }
478 :
479 : /**
480 : * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
481 : * @dev: drm device
482 : * @id: id of the fb object
483 : *
484 : * If successful, this grabs an additional reference to the framebuffer -
485 : * callers need to make sure to eventually unreference the returned framebuffer
486 : * again, using @drm_framebuffer_unreference.
487 : */
488 0 : struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
489 : uint32_t id)
490 : {
491 : struct drm_framebuffer *fb;
492 :
493 0 : mutex_lock(&dev->mode_config.fb_lock);
494 0 : fb = __drm_framebuffer_lookup(dev, id);
495 0 : if (fb) {
496 0 : if (!kref_get_unless_zero(&fb->refcount))
497 0 : fb = NULL;
498 : }
499 0 : mutex_unlock(&dev->mode_config.fb_lock);
500 :
501 0 : return fb;
502 : }
503 : EXPORT_SYMBOL(drm_framebuffer_lookup);
504 :
505 : /**
506 : * drm_framebuffer_unreference - unref a framebuffer
507 : * @fb: framebuffer to unref
508 : *
509 : * This functions decrements the fb's refcount and frees it if it drops to zero.
510 : */
511 0 : void drm_framebuffer_unreference(struct drm_framebuffer *fb)
512 : {
513 : DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
514 0 : kref_put(&fb->refcount, drm_framebuffer_free);
515 0 : }
516 : EXPORT_SYMBOL(drm_framebuffer_unreference);
517 :
518 : /**
519 : * drm_framebuffer_reference - incr the fb refcnt
520 : * @fb: framebuffer
521 : *
522 : * This functions increments the fb's refcount.
523 : */
524 0 : void drm_framebuffer_reference(struct drm_framebuffer *fb)
525 : {
526 : DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
527 0 : kref_get(&fb->refcount);
528 0 : }
529 : EXPORT_SYMBOL(drm_framebuffer_reference);
530 :
531 : /**
532 : * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
533 : * @fb: fb to unregister
534 : *
535 : * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
536 : * those used for fbdev. Note that the caller must hold a reference of it's own,
537 : * i.e. the object may not be destroyed through this call (since it'll lead to a
538 : * locking inversion).
539 : */
540 0 : void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
541 : {
542 : struct drm_device *dev;
543 :
544 0 : if (!fb)
545 0 : return;
546 :
547 0 : dev = fb->dev;
548 :
549 0 : mutex_lock(&dev->mode_config.fb_lock);
550 : /* Mark fb as reaped and drop idr ref. */
551 0 : __drm_framebuffer_unregister(dev, fb);
552 0 : mutex_unlock(&dev->mode_config.fb_lock);
553 0 : }
554 : EXPORT_SYMBOL(drm_framebuffer_unregister_private);
555 :
556 : /**
557 : * drm_framebuffer_cleanup - remove a framebuffer object
558 : * @fb: framebuffer to remove
559 : *
560 : * Cleanup framebuffer. This function is intended to be used from the drivers
561 : * ->destroy callback. It can also be used to clean up driver private
562 : * framebuffers embedded into a larger structure.
563 : *
564 : * Note that this function does not remove the fb from active usuage - if it is
565 : * still used anywhere, hilarity can ensue since userspace could call getfb on
566 : * the id and get back -EINVAL. Obviously no concern at driver unload time.
567 : *
568 : * Also, the framebuffer will not be removed from the lookup idr - for
569 : * user-created framebuffers this will happen in in the rmfb ioctl. For
570 : * driver-private objects (e.g. for fbdev) drivers need to explicitly call
571 : * drm_framebuffer_unregister_private.
572 : */
573 0 : void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
574 : {
575 0 : struct drm_device *dev = fb->dev;
576 :
577 0 : mutex_lock(&dev->mode_config.fb_lock);
578 0 : list_del(&fb->head);
579 0 : dev->mode_config.num_fb--;
580 0 : mutex_unlock(&dev->mode_config.fb_lock);
581 0 : }
582 : EXPORT_SYMBOL(drm_framebuffer_cleanup);
583 :
584 : /**
585 : * drm_framebuffer_remove - remove and unreference a framebuffer object
586 : * @fb: framebuffer to remove
587 : *
588 : * Scans all the CRTCs and planes in @dev's mode_config. If they're
589 : * using @fb, removes it, setting it to NULL. Then drops the reference to the
590 : * passed-in framebuffer. Might take the modeset locks.
591 : *
592 : * Note that this function optimizes the cleanup away if the caller holds the
593 : * last reference to the framebuffer. It is also guaranteed to not take the
594 : * modeset locks in this case.
595 : */
596 0 : void drm_framebuffer_remove(struct drm_framebuffer *fb)
597 : {
598 : struct drm_device *dev;
599 : struct drm_crtc *crtc;
600 : struct drm_plane *plane;
601 0 : struct drm_mode_set set;
602 : int ret;
603 :
604 0 : if (!fb)
605 0 : return;
606 :
607 0 : dev = fb->dev;
608 :
609 0 : WARN_ON(!list_empty(&fb->filp_head));
610 :
611 : /*
612 : * drm ABI mandates that we remove any deleted framebuffers from active
613 : * useage. But since most sane clients only remove framebuffers they no
614 : * longer need, try to optimize this away.
615 : *
616 : * Since we're holding a reference ourselves, observing a refcount of 1
617 : * means that we're the last holder and can skip it. Also, the refcount
618 : * can never increase from 1 again, so we don't need any barriers or
619 : * locks.
620 : *
621 : * Note that userspace could try to race with use and instate a new
622 : * usage _after_ we've cleared all current ones. End result will be an
623 : * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
624 : * in this manner.
625 : */
626 0 : if (atomic_read(&fb->refcount.refcount) > 1) {
627 0 : drm_modeset_lock_all(dev);
628 : /* remove from any CRTC */
629 0 : drm_for_each_crtc(crtc, dev) {
630 0 : if (crtc->primary->fb == fb) {
631 : /* should turn off the crtc */
632 0 : memset(&set, 0, sizeof(struct drm_mode_set));
633 0 : set.crtc = crtc;
634 0 : set.fb = NULL;
635 0 : ret = drm_mode_set_config_internal(&set);
636 0 : if (ret)
637 0 : DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
638 : }
639 : }
640 :
641 0 : drm_for_each_plane(plane, dev) {
642 0 : if (plane->fb == fb)
643 0 : drm_plane_force_disable(plane);
644 : }
645 0 : drm_modeset_unlock_all(dev);
646 0 : }
647 :
648 0 : drm_framebuffer_unreference(fb);
649 0 : }
650 : EXPORT_SYMBOL(drm_framebuffer_remove);
651 :
652 : DEFINE_WW_CLASS(crtc_ww_class);
653 :
654 : /**
655 : * drm_crtc_init_with_planes - Initialise a new CRTC object with
656 : * specified primary and cursor planes.
657 : * @dev: DRM device
658 : * @crtc: CRTC object to init
659 : * @primary: Primary plane for CRTC
660 : * @cursor: Cursor plane for CRTC
661 : * @funcs: callbacks for the new CRTC
662 : *
663 : * Inits a new object created as base part of a driver crtc object.
664 : *
665 : * Returns:
666 : * Zero on success, error code on failure.
667 : */
668 0 : int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
669 : struct drm_plane *primary,
670 : struct drm_plane *cursor,
671 : const struct drm_crtc_funcs *funcs)
672 : {
673 0 : struct drm_mode_config *config = &dev->mode_config;
674 : int ret;
675 :
676 0 : WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
677 0 : WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
678 :
679 0 : crtc->dev = dev;
680 0 : crtc->funcs = funcs;
681 :
682 0 : drm_modeset_lock_init(&crtc->mutex);
683 0 : ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
684 0 : if (ret)
685 0 : return ret;
686 :
687 0 : crtc->base.properties = &crtc->properties;
688 :
689 0 : list_add_tail(&crtc->head, &config->crtc_list);
690 0 : config->num_crtc++;
691 :
692 0 : crtc->primary = primary;
693 0 : crtc->cursor = cursor;
694 0 : if (primary)
695 0 : primary->possible_crtcs = 1 << drm_crtc_index(crtc);
696 0 : if (cursor)
697 0 : cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
698 :
699 0 : if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
700 0 : drm_object_attach_property(&crtc->base, config->prop_active, 0);
701 0 : drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
702 0 : }
703 :
704 0 : return 0;
705 0 : }
706 : EXPORT_SYMBOL(drm_crtc_init_with_planes);
707 :
708 : /**
709 : * drm_crtc_cleanup - Clean up the core crtc usage
710 : * @crtc: CRTC to cleanup
711 : *
712 : * This function cleans up @crtc and removes it from the DRM mode setting
713 : * core. Note that the function does *not* free the crtc structure itself,
714 : * this is the responsibility of the caller.
715 : */
716 0 : void drm_crtc_cleanup(struct drm_crtc *crtc)
717 : {
718 0 : struct drm_device *dev = crtc->dev;
719 :
720 0 : kfree(crtc->gamma_store);
721 0 : crtc->gamma_store = NULL;
722 :
723 0 : drm_modeset_lock_fini(&crtc->mutex);
724 :
725 0 : drm_mode_object_put(dev, &crtc->base);
726 0 : list_del(&crtc->head);
727 0 : dev->mode_config.num_crtc--;
728 :
729 0 : WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
730 0 : if (crtc->state && crtc->funcs->atomic_destroy_state)
731 0 : crtc->funcs->atomic_destroy_state(crtc, crtc->state);
732 :
733 0 : memset(crtc, 0, sizeof(*crtc));
734 0 : }
735 : EXPORT_SYMBOL(drm_crtc_cleanup);
736 :
737 : /**
738 : * drm_crtc_index - find the index of a registered CRTC
739 : * @crtc: CRTC to find index for
740 : *
741 : * Given a registered CRTC, return the index of that CRTC within a DRM
742 : * device's list of CRTCs.
743 : */
744 0 : unsigned int drm_crtc_index(struct drm_crtc *crtc)
745 : {
746 : unsigned int index = 0;
747 : struct drm_crtc *tmp;
748 :
749 0 : drm_for_each_crtc(tmp, crtc->dev) {
750 0 : if (tmp == crtc)
751 : return index;
752 :
753 0 : index++;
754 : }
755 :
756 0 : BUG();
757 0 : }
758 : EXPORT_SYMBOL(drm_crtc_index);
759 :
760 : /*
761 : * drm_mode_remove - remove and free a mode
762 : * @connector: connector list to modify
763 : * @mode: mode to remove
764 : *
765 : * Remove @mode from @connector's mode list, then free it.
766 : */
767 0 : static void drm_mode_remove(struct drm_connector *connector,
768 : struct drm_display_mode *mode)
769 : {
770 0 : list_del(&mode->head);
771 0 : drm_mode_destroy(connector->dev, mode);
772 0 : }
773 :
774 : /**
775 : * drm_display_info_set_bus_formats - set the supported bus formats
776 : * @info: display info to store bus formats in
777 : * @formats: array containing the supported bus formats
778 : * @num_formats: the number of entries in the fmts array
779 : *
780 : * Store the supported bus formats in display info structure.
781 : * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for
782 : * a full list of available formats.
783 : */
784 0 : int drm_display_info_set_bus_formats(struct drm_display_info *info,
785 : const u32 *formats,
786 : unsigned int num_formats)
787 : {
788 : u32 *fmts = NULL;
789 :
790 0 : if (!formats && num_formats)
791 0 : return -EINVAL;
792 :
793 0 : if (formats && num_formats) {
794 0 : fmts = kmemdup(formats, sizeof(*formats) * num_formats,
795 : GFP_KERNEL);
796 0 : if (!fmts)
797 0 : return -ENOMEM;
798 : }
799 :
800 0 : kfree(info->bus_formats);
801 0 : info->bus_formats = fmts;
802 0 : info->num_bus_formats = num_formats;
803 :
804 0 : return 0;
805 0 : }
806 : EXPORT_SYMBOL(drm_display_info_set_bus_formats);
807 :
808 : /**
809 : * drm_connector_get_cmdline_mode - reads the user's cmdline mode
810 : * @connector: connector to quwery
811 : *
812 : * The kernel supports per-connector configration of its consoles through
813 : * use of the video= parameter. This function parses that option and
814 : * extracts the user's specified mode (or enable/disable status) for a
815 : * particular connector. This is typically only used during the early fbdev
816 : * setup.
817 : */
818 0 : static void drm_connector_get_cmdline_mode(struct drm_connector *connector)
819 : {
820 0 : struct drm_cmdline_mode *mode = &connector->cmdline_mode;
821 : char *option = NULL;
822 :
823 : #ifdef __linux__
824 : if (fb_get_options(connector->name, &option))
825 : return;
826 : #endif
827 :
828 0 : if (!drm_mode_parse_command_line_for_connector(option,
829 : connector,
830 : mode))
831 0 : return;
832 :
833 0 : if (mode->force) {
834 : const char *s;
835 :
836 0 : switch (mode->force) {
837 : case DRM_FORCE_OFF:
838 : s = "OFF";
839 0 : break;
840 : case DRM_FORCE_ON_DIGITAL:
841 : s = "ON - dig";
842 0 : break;
843 : default:
844 : case DRM_FORCE_ON:
845 : s = "ON";
846 0 : break;
847 : }
848 :
849 : DRM_INFO("forcing %s connector %s\n", connector->name, s);
850 0 : connector->force = mode->force;
851 0 : }
852 :
853 : DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
854 : connector->name,
855 : mode->xres, mode->yres,
856 : mode->refresh_specified ? mode->refresh : 60,
857 : mode->rb ? " reduced blanking" : "",
858 : mode->margins ? " with margins" : "",
859 : mode->interlace ? " interlaced" : "");
860 0 : }
861 :
862 : /**
863 : * drm_connector_init - Init a preallocated connector
864 : * @dev: DRM device
865 : * @connector: the connector to init
866 : * @funcs: callbacks for this connector
867 : * @connector_type: user visible type of the connector
868 : *
869 : * Initialises a preallocated connector. Connectors should be
870 : * subclassed as part of driver connector objects.
871 : *
872 : * Returns:
873 : * Zero on success, error code on failure.
874 : */
875 0 : int drm_connector_init(struct drm_device *dev,
876 : struct drm_connector *connector,
877 : const struct drm_connector_funcs *funcs,
878 : int connector_type)
879 : {
880 0 : struct drm_mode_config *config = &dev->mode_config;
881 : int ret;
882 : struct ida *connector_ida =
883 0 : &drm_connector_enum_list[connector_type].ida;
884 :
885 0 : drm_modeset_lock_all(dev);
886 :
887 0 : ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false);
888 0 : if (ret)
889 : goto out_unlock;
890 :
891 0 : connector->base.properties = &connector->properties;
892 0 : connector->dev = dev;
893 0 : connector->funcs = funcs;
894 0 : connector->connector_type = connector_type;
895 0 : connector->connector_type_id =
896 0 : ida_simple_get(connector_ida, 1, 0, GFP_KERNEL);
897 0 : if (connector->connector_type_id < 0) {
898 : ret = connector->connector_type_id;
899 0 : goto out_put;
900 : }
901 0 : connector->name =
902 0 : kasprintf(GFP_KERNEL, "%s-%d",
903 0 : drm_connector_enum_list[connector_type].name,
904 : connector->connector_type_id);
905 0 : if (!connector->name) {
906 : ret = -ENOMEM;
907 0 : goto out_put;
908 : }
909 :
910 0 : INIT_LIST_HEAD(&connector->probed_modes);
911 0 : INIT_LIST_HEAD(&connector->modes);
912 0 : connector->edid_blob_ptr = NULL;
913 0 : connector->status = connector_status_unknown;
914 :
915 0 : drm_connector_get_cmdline_mode(connector);
916 :
917 : /* We should add connectors at the end to avoid upsetting the connector
918 : * index too much. */
919 0 : list_add_tail(&connector->head, &config->connector_list);
920 0 : config->num_connector++;
921 :
922 0 : if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
923 0 : drm_object_attach_property(&connector->base,
924 0 : config->edid_property,
925 : 0);
926 :
927 0 : drm_object_attach_property(&connector->base,
928 0 : config->dpms_property, 0);
929 :
930 0 : if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
931 0 : drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
932 0 : }
933 :
934 0 : connector->debugfs_entry = NULL;
935 :
936 : out_put:
937 0 : if (ret)
938 0 : drm_mode_object_put(dev, &connector->base);
939 :
940 : out_unlock:
941 0 : drm_modeset_unlock_all(dev);
942 :
943 0 : return ret;
944 : }
945 : EXPORT_SYMBOL(drm_connector_init);
946 :
947 : /**
948 : * drm_connector_cleanup - cleans up an initialised connector
949 : * @connector: connector to cleanup
950 : *
951 : * Cleans up the connector but doesn't free the object.
952 : */
953 0 : void drm_connector_cleanup(struct drm_connector *connector)
954 : {
955 0 : struct drm_device *dev = connector->dev;
956 : struct drm_display_mode *mode, *t;
957 :
958 0 : if (connector->tile_group) {
959 0 : drm_mode_put_tile_group(dev, connector->tile_group);
960 0 : connector->tile_group = NULL;
961 0 : }
962 :
963 0 : list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
964 0 : drm_mode_remove(connector, mode);
965 :
966 0 : list_for_each_entry_safe(mode, t, &connector->modes, head)
967 0 : drm_mode_remove(connector, mode);
968 :
969 0 : ida_remove(&drm_connector_enum_list[connector->connector_type].ida,
970 0 : connector->connector_type_id);
971 :
972 0 : kfree(connector->display_info.bus_formats);
973 0 : drm_mode_object_put(dev, &connector->base);
974 0 : kfree(connector->name);
975 0 : connector->name = NULL;
976 0 : list_del(&connector->head);
977 0 : dev->mode_config.num_connector--;
978 :
979 0 : WARN_ON(connector->state && !connector->funcs->atomic_destroy_state);
980 0 : if (connector->state && connector->funcs->atomic_destroy_state)
981 0 : connector->funcs->atomic_destroy_state(connector,
982 : connector->state);
983 :
984 0 : memset(connector, 0, sizeof(*connector));
985 0 : }
986 : EXPORT_SYMBOL(drm_connector_cleanup);
987 :
988 : /**
989 : * drm_connector_index - find the index of a registered connector
990 : * @connector: connector to find index for
991 : *
992 : * Given a registered connector, return the index of that connector within a DRM
993 : * device's list of connectors.
994 : */
995 0 : unsigned int drm_connector_index(struct drm_connector *connector)
996 : {
997 : unsigned int index = 0;
998 : struct drm_connector *tmp;
999 0 : struct drm_mode_config *config = &connector->dev->mode_config;
1000 :
1001 0 : WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
1002 :
1003 0 : drm_for_each_connector(tmp, connector->dev) {
1004 0 : if (tmp == connector)
1005 : return index;
1006 :
1007 0 : index++;
1008 : }
1009 :
1010 0 : BUG();
1011 0 : }
1012 : EXPORT_SYMBOL(drm_connector_index);
1013 :
1014 : /**
1015 : * drm_connector_register - register a connector
1016 : * @connector: the connector to register
1017 : *
1018 : * Register userspace interfaces for a connector
1019 : *
1020 : * Returns:
1021 : * Zero on success, error code on failure.
1022 : */
1023 0 : int drm_connector_register(struct drm_connector *connector)
1024 : {
1025 : int ret;
1026 :
1027 0 : drm_mode_object_register(connector->dev, &connector->base);
1028 :
1029 0 : ret = drm_sysfs_connector_add(connector);
1030 0 : if (ret)
1031 0 : return ret;
1032 :
1033 0 : ret = drm_debugfs_connector_add(connector);
1034 0 : if (ret) {
1035 0 : drm_sysfs_connector_remove(connector);
1036 0 : return ret;
1037 : }
1038 :
1039 0 : return 0;
1040 0 : }
1041 : EXPORT_SYMBOL(drm_connector_register);
1042 :
1043 : /**
1044 : * drm_connector_unregister - unregister a connector
1045 : * @connector: the connector to unregister
1046 : *
1047 : * Unregister userspace interfaces for a connector
1048 : */
1049 0 : void drm_connector_unregister(struct drm_connector *connector)
1050 : {
1051 0 : drm_sysfs_connector_remove(connector);
1052 0 : drm_debugfs_connector_remove(connector);
1053 0 : }
1054 : EXPORT_SYMBOL(drm_connector_unregister);
1055 :
1056 :
1057 : /**
1058 : * drm_connector_unplug_all - unregister connector userspace interfaces
1059 : * @dev: drm device
1060 : *
1061 : * This function unregisters all connector userspace interfaces in sysfs. Should
1062 : * be call when the device is disconnected, e.g. from an usb driver's
1063 : * ->disconnect callback.
1064 : */
1065 0 : void drm_connector_unplug_all(struct drm_device *dev)
1066 : {
1067 : struct drm_connector *connector;
1068 :
1069 : /* FIXME: taking the mode config mutex ends up in a clash with sysfs */
1070 0 : list_for_each_entry(connector, &dev->mode_config.connector_list, head)
1071 0 : drm_connector_unregister(connector);
1072 :
1073 0 : }
1074 : EXPORT_SYMBOL(drm_connector_unplug_all);
1075 :
1076 : /**
1077 : * drm_encoder_init - Init a preallocated encoder
1078 : * @dev: drm device
1079 : * @encoder: the encoder to init
1080 : * @funcs: callbacks for this encoder
1081 : * @encoder_type: user visible type of the encoder
1082 : *
1083 : * Initialises a preallocated encoder. Encoder should be
1084 : * subclassed as part of driver encoder objects.
1085 : *
1086 : * Returns:
1087 : * Zero on success, error code on failure.
1088 : */
1089 0 : int drm_encoder_init(struct drm_device *dev,
1090 : struct drm_encoder *encoder,
1091 : const struct drm_encoder_funcs *funcs,
1092 : int encoder_type)
1093 : {
1094 : int ret;
1095 :
1096 0 : drm_modeset_lock_all(dev);
1097 :
1098 0 : ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
1099 0 : if (ret)
1100 : goto out_unlock;
1101 :
1102 0 : encoder->dev = dev;
1103 0 : encoder->encoder_type = encoder_type;
1104 0 : encoder->funcs = funcs;
1105 0 : encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
1106 0 : drm_encoder_enum_list[encoder_type].name,
1107 0 : encoder->base.id);
1108 0 : if (!encoder->name) {
1109 : ret = -ENOMEM;
1110 0 : goto out_put;
1111 : }
1112 :
1113 0 : list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
1114 0 : dev->mode_config.num_encoder++;
1115 :
1116 : out_put:
1117 0 : if (ret)
1118 0 : drm_mode_object_put(dev, &encoder->base);
1119 :
1120 : out_unlock:
1121 0 : drm_modeset_unlock_all(dev);
1122 :
1123 0 : return ret;
1124 : }
1125 : EXPORT_SYMBOL(drm_encoder_init);
1126 :
1127 : /**
1128 : * drm_encoder_cleanup - cleans up an initialised encoder
1129 : * @encoder: encoder to cleanup
1130 : *
1131 : * Cleans up the encoder but doesn't free the object.
1132 : */
1133 0 : void drm_encoder_cleanup(struct drm_encoder *encoder)
1134 : {
1135 0 : struct drm_device *dev = encoder->dev;
1136 :
1137 0 : drm_modeset_lock_all(dev);
1138 0 : drm_mode_object_put(dev, &encoder->base);
1139 0 : kfree(encoder->name);
1140 0 : list_del(&encoder->head);
1141 0 : dev->mode_config.num_encoder--;
1142 0 : drm_modeset_unlock_all(dev);
1143 :
1144 0 : memset(encoder, 0, sizeof(*encoder));
1145 0 : }
1146 : EXPORT_SYMBOL(drm_encoder_cleanup);
1147 :
1148 : /**
1149 : * drm_universal_plane_init - Initialize a new universal plane object
1150 : * @dev: DRM device
1151 : * @plane: plane object to init
1152 : * @possible_crtcs: bitmask of possible CRTCs
1153 : * @funcs: callbacks for the new plane
1154 : * @formats: array of supported formats (%DRM_FORMAT_*)
1155 : * @format_count: number of elements in @formats
1156 : * @type: type of plane (overlay, primary, cursor)
1157 : *
1158 : * Initializes a plane object of type @type.
1159 : *
1160 : * Returns:
1161 : * Zero on success, error code on failure.
1162 : */
1163 0 : int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1164 : unsigned long possible_crtcs,
1165 : const struct drm_plane_funcs *funcs,
1166 : const uint32_t *formats, unsigned int format_count,
1167 : enum drm_plane_type type)
1168 : {
1169 0 : struct drm_mode_config *config = &dev->mode_config;
1170 : int ret;
1171 :
1172 0 : ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
1173 0 : if (ret)
1174 0 : return ret;
1175 :
1176 0 : drm_modeset_lock_init(&plane->mutex);
1177 :
1178 0 : plane->base.properties = &plane->properties;
1179 0 : plane->dev = dev;
1180 0 : plane->funcs = funcs;
1181 0 : plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
1182 : GFP_KERNEL);
1183 0 : if (!plane->format_types) {
1184 : DRM_DEBUG_KMS("out of memory when allocating plane\n");
1185 0 : drm_mode_object_put(dev, &plane->base);
1186 0 : return -ENOMEM;
1187 : }
1188 :
1189 0 : memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
1190 0 : plane->format_count = format_count;
1191 0 : plane->possible_crtcs = possible_crtcs;
1192 0 : plane->type = type;
1193 :
1194 0 : list_add_tail(&plane->head, &config->plane_list);
1195 0 : config->num_total_plane++;
1196 0 : if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1197 0 : config->num_overlay_plane++;
1198 :
1199 0 : drm_object_attach_property(&plane->base,
1200 0 : config->plane_type_property,
1201 0 : plane->type);
1202 :
1203 0 : if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
1204 0 : drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
1205 0 : drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
1206 0 : drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
1207 0 : drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
1208 0 : drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
1209 0 : drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
1210 0 : drm_object_attach_property(&plane->base, config->prop_src_x, 0);
1211 0 : drm_object_attach_property(&plane->base, config->prop_src_y, 0);
1212 0 : drm_object_attach_property(&plane->base, config->prop_src_w, 0);
1213 0 : drm_object_attach_property(&plane->base, config->prop_src_h, 0);
1214 0 : }
1215 :
1216 0 : return 0;
1217 0 : }
1218 : EXPORT_SYMBOL(drm_universal_plane_init);
1219 :
1220 : /**
1221 : * drm_plane_init - Initialize a legacy plane
1222 : * @dev: DRM device
1223 : * @plane: plane object to init
1224 : * @possible_crtcs: bitmask of possible CRTCs
1225 : * @funcs: callbacks for the new plane
1226 : * @formats: array of supported formats (%DRM_FORMAT_*)
1227 : * @format_count: number of elements in @formats
1228 : * @is_primary: plane type (primary vs overlay)
1229 : *
1230 : * Legacy API to initialize a DRM plane.
1231 : *
1232 : * New drivers should call drm_universal_plane_init() instead.
1233 : *
1234 : * Returns:
1235 : * Zero on success, error code on failure.
1236 : */
1237 0 : int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
1238 : unsigned long possible_crtcs,
1239 : const struct drm_plane_funcs *funcs,
1240 : const uint32_t *formats, unsigned int format_count,
1241 : bool is_primary)
1242 : {
1243 : enum drm_plane_type type;
1244 :
1245 0 : type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
1246 0 : return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
1247 : formats, format_count, type);
1248 : }
1249 : EXPORT_SYMBOL(drm_plane_init);
1250 :
1251 : /**
1252 : * drm_plane_cleanup - Clean up the core plane usage
1253 : * @plane: plane to cleanup
1254 : *
1255 : * This function cleans up @plane and removes it from the DRM mode setting
1256 : * core. Note that the function does *not* free the plane structure itself,
1257 : * this is the responsibility of the caller.
1258 : */
1259 0 : void drm_plane_cleanup(struct drm_plane *plane)
1260 : {
1261 0 : struct drm_device *dev = plane->dev;
1262 :
1263 0 : drm_modeset_lock_all(dev);
1264 0 : kfree(plane->format_types);
1265 0 : drm_mode_object_put(dev, &plane->base);
1266 :
1267 0 : BUG_ON(list_empty(&plane->head));
1268 :
1269 0 : list_del(&plane->head);
1270 0 : dev->mode_config.num_total_plane--;
1271 0 : if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1272 0 : dev->mode_config.num_overlay_plane--;
1273 0 : drm_modeset_unlock_all(dev);
1274 :
1275 0 : WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
1276 0 : if (plane->state && plane->funcs->atomic_destroy_state)
1277 0 : plane->funcs->atomic_destroy_state(plane, plane->state);
1278 :
1279 0 : memset(plane, 0, sizeof(*plane));
1280 0 : }
1281 : EXPORT_SYMBOL(drm_plane_cleanup);
1282 :
1283 : /**
1284 : * drm_plane_index - find the index of a registered plane
1285 : * @plane: plane to find index for
1286 : *
1287 : * Given a registered plane, return the index of that CRTC within a DRM
1288 : * device's list of planes.
1289 : */
1290 0 : unsigned int drm_plane_index(struct drm_plane *plane)
1291 : {
1292 : unsigned int index = 0;
1293 : struct drm_plane *tmp;
1294 :
1295 0 : drm_for_each_plane(tmp, plane->dev) {
1296 0 : if (tmp == plane)
1297 : return index;
1298 :
1299 0 : index++;
1300 : }
1301 :
1302 0 : BUG();
1303 0 : }
1304 : EXPORT_SYMBOL(drm_plane_index);
1305 :
1306 : /**
1307 : * drm_plane_from_index - find the registered plane at an index
1308 : * @dev: DRM device
1309 : * @idx: index of registered plane to find for
1310 : *
1311 : * Given a plane index, return the registered plane from DRM device's
1312 : * list of planes with matching index.
1313 : */
1314 : struct drm_plane *
1315 0 : drm_plane_from_index(struct drm_device *dev, int idx)
1316 : {
1317 : struct drm_plane *plane;
1318 : unsigned int i = 0;
1319 :
1320 0 : drm_for_each_plane(plane, dev) {
1321 0 : if (i == idx)
1322 0 : return plane;
1323 0 : i++;
1324 : }
1325 0 : return NULL;
1326 0 : }
1327 : EXPORT_SYMBOL(drm_plane_from_index);
1328 :
1329 : /**
1330 : * drm_plane_force_disable - Forcibly disable a plane
1331 : * @plane: plane to disable
1332 : *
1333 : * Forces the plane to be disabled.
1334 : *
1335 : * Used when the plane's current framebuffer is destroyed,
1336 : * and when restoring fbdev mode.
1337 : */
1338 0 : void drm_plane_force_disable(struct drm_plane *plane)
1339 : {
1340 : int ret;
1341 :
1342 0 : if (!plane->fb)
1343 0 : return;
1344 :
1345 0 : plane->old_fb = plane->fb;
1346 0 : ret = plane->funcs->disable_plane(plane);
1347 0 : if (ret) {
1348 0 : DRM_ERROR("failed to disable plane with busy fb\n");
1349 0 : plane->old_fb = NULL;
1350 0 : return;
1351 : }
1352 : /* disconnect the plane from the fb and crtc: */
1353 0 : drm_framebuffer_unreference(plane->old_fb);
1354 0 : plane->old_fb = NULL;
1355 0 : plane->fb = NULL;
1356 0 : plane->crtc = NULL;
1357 0 : }
1358 : EXPORT_SYMBOL(drm_plane_force_disable);
1359 :
1360 0 : static int drm_mode_create_standard_properties(struct drm_device *dev)
1361 : {
1362 : struct drm_property *prop;
1363 :
1364 : /*
1365 : * Standard properties (apply to all connectors)
1366 : */
1367 0 : prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
1368 : DRM_MODE_PROP_IMMUTABLE,
1369 : "EDID", 0);
1370 0 : if (!prop)
1371 0 : return -ENOMEM;
1372 0 : dev->mode_config.edid_property = prop;
1373 :
1374 0 : prop = drm_property_create_enum(dev, 0,
1375 : "DPMS", drm_dpms_enum_list,
1376 : ARRAY_SIZE(drm_dpms_enum_list));
1377 0 : if (!prop)
1378 0 : return -ENOMEM;
1379 0 : dev->mode_config.dpms_property = prop;
1380 :
1381 0 : prop = drm_property_create(dev,
1382 : DRM_MODE_PROP_BLOB |
1383 : DRM_MODE_PROP_IMMUTABLE,
1384 : "PATH", 0);
1385 0 : if (!prop)
1386 0 : return -ENOMEM;
1387 0 : dev->mode_config.path_property = prop;
1388 :
1389 0 : prop = drm_property_create(dev,
1390 : DRM_MODE_PROP_BLOB |
1391 : DRM_MODE_PROP_IMMUTABLE,
1392 : "TILE", 0);
1393 0 : if (!prop)
1394 0 : return -ENOMEM;
1395 0 : dev->mode_config.tile_property = prop;
1396 :
1397 0 : prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1398 : "type", drm_plane_type_enum_list,
1399 : ARRAY_SIZE(drm_plane_type_enum_list));
1400 0 : if (!prop)
1401 0 : return -ENOMEM;
1402 0 : dev->mode_config.plane_type_property = prop;
1403 :
1404 0 : prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1405 : "SRC_X", 0, UINT_MAX);
1406 0 : if (!prop)
1407 0 : return -ENOMEM;
1408 0 : dev->mode_config.prop_src_x = prop;
1409 :
1410 0 : prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1411 : "SRC_Y", 0, UINT_MAX);
1412 0 : if (!prop)
1413 0 : return -ENOMEM;
1414 0 : dev->mode_config.prop_src_y = prop;
1415 :
1416 0 : prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1417 : "SRC_W", 0, UINT_MAX);
1418 0 : if (!prop)
1419 0 : return -ENOMEM;
1420 0 : dev->mode_config.prop_src_w = prop;
1421 :
1422 0 : prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1423 : "SRC_H", 0, UINT_MAX);
1424 0 : if (!prop)
1425 0 : return -ENOMEM;
1426 0 : dev->mode_config.prop_src_h = prop;
1427 :
1428 0 : prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
1429 : "CRTC_X", INT_MIN, INT_MAX);
1430 0 : if (!prop)
1431 0 : return -ENOMEM;
1432 0 : dev->mode_config.prop_crtc_x = prop;
1433 :
1434 0 : prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
1435 : "CRTC_Y", INT_MIN, INT_MAX);
1436 0 : if (!prop)
1437 0 : return -ENOMEM;
1438 0 : dev->mode_config.prop_crtc_y = prop;
1439 :
1440 0 : prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1441 : "CRTC_W", 0, INT_MAX);
1442 0 : if (!prop)
1443 0 : return -ENOMEM;
1444 0 : dev->mode_config.prop_crtc_w = prop;
1445 :
1446 0 : prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1447 : "CRTC_H", 0, INT_MAX);
1448 0 : if (!prop)
1449 0 : return -ENOMEM;
1450 0 : dev->mode_config.prop_crtc_h = prop;
1451 :
1452 0 : prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
1453 : "FB_ID", DRM_MODE_OBJECT_FB);
1454 0 : if (!prop)
1455 0 : return -ENOMEM;
1456 0 : dev->mode_config.prop_fb_id = prop;
1457 :
1458 0 : prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
1459 : "CRTC_ID", DRM_MODE_OBJECT_CRTC);
1460 0 : if (!prop)
1461 0 : return -ENOMEM;
1462 0 : dev->mode_config.prop_crtc_id = prop;
1463 :
1464 0 : prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
1465 : "ACTIVE");
1466 0 : if (!prop)
1467 0 : return -ENOMEM;
1468 0 : dev->mode_config.prop_active = prop;
1469 :
1470 0 : prop = drm_property_create(dev,
1471 : DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
1472 : "MODE_ID", 0);
1473 0 : if (!prop)
1474 0 : return -ENOMEM;
1475 0 : dev->mode_config.prop_mode_id = prop;
1476 :
1477 0 : return 0;
1478 0 : }
1479 :
1480 : /**
1481 : * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
1482 : * @dev: DRM device
1483 : *
1484 : * Called by a driver the first time a DVI-I connector is made.
1485 : */
1486 0 : int drm_mode_create_dvi_i_properties(struct drm_device *dev)
1487 : {
1488 : struct drm_property *dvi_i_selector;
1489 : struct drm_property *dvi_i_subconnector;
1490 :
1491 0 : if (dev->mode_config.dvi_i_select_subconnector_property)
1492 0 : return 0;
1493 :
1494 : dvi_i_selector =
1495 0 : drm_property_create_enum(dev, 0,
1496 : "select subconnector",
1497 : drm_dvi_i_select_enum_list,
1498 : ARRAY_SIZE(drm_dvi_i_select_enum_list));
1499 0 : dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
1500 :
1501 0 : dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1502 : "subconnector",
1503 : drm_dvi_i_subconnector_enum_list,
1504 : ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
1505 0 : dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
1506 :
1507 0 : return 0;
1508 0 : }
1509 : EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
1510 :
1511 : /**
1512 : * drm_create_tv_properties - create TV specific connector properties
1513 : * @dev: DRM device
1514 : * @num_modes: number of different TV formats (modes) supported
1515 : * @modes: array of pointers to strings containing name of each format
1516 : *
1517 : * Called by a driver's TV initialization routine, this function creates
1518 : * the TV specific connector properties for a given device. Caller is
1519 : * responsible for allocating a list of format names and passing them to
1520 : * this routine.
1521 : */
1522 0 : int drm_mode_create_tv_properties(struct drm_device *dev,
1523 : unsigned int num_modes,
1524 : const char * const modes[])
1525 : {
1526 : struct drm_property *tv_selector;
1527 : struct drm_property *tv_subconnector;
1528 : unsigned int i;
1529 :
1530 0 : if (dev->mode_config.tv_select_subconnector_property)
1531 0 : return 0;
1532 :
1533 : /*
1534 : * Basic connector properties
1535 : */
1536 0 : tv_selector = drm_property_create_enum(dev, 0,
1537 : "select subconnector",
1538 : drm_tv_select_enum_list,
1539 : ARRAY_SIZE(drm_tv_select_enum_list));
1540 0 : if (!tv_selector)
1541 : goto nomem;
1542 :
1543 0 : dev->mode_config.tv_select_subconnector_property = tv_selector;
1544 :
1545 : tv_subconnector =
1546 0 : drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1547 : "subconnector",
1548 : drm_tv_subconnector_enum_list,
1549 : ARRAY_SIZE(drm_tv_subconnector_enum_list));
1550 0 : if (!tv_subconnector)
1551 : goto nomem;
1552 0 : dev->mode_config.tv_subconnector_property = tv_subconnector;
1553 :
1554 : /*
1555 : * Other, TV specific properties: margins & TV modes.
1556 : */
1557 0 : dev->mode_config.tv_left_margin_property =
1558 0 : drm_property_create_range(dev, 0, "left margin", 0, 100);
1559 0 : if (!dev->mode_config.tv_left_margin_property)
1560 : goto nomem;
1561 :
1562 0 : dev->mode_config.tv_right_margin_property =
1563 0 : drm_property_create_range(dev, 0, "right margin", 0, 100);
1564 0 : if (!dev->mode_config.tv_right_margin_property)
1565 : goto nomem;
1566 :
1567 0 : dev->mode_config.tv_top_margin_property =
1568 0 : drm_property_create_range(dev, 0, "top margin", 0, 100);
1569 0 : if (!dev->mode_config.tv_top_margin_property)
1570 : goto nomem;
1571 :
1572 0 : dev->mode_config.tv_bottom_margin_property =
1573 0 : drm_property_create_range(dev, 0, "bottom margin", 0, 100);
1574 0 : if (!dev->mode_config.tv_bottom_margin_property)
1575 : goto nomem;
1576 :
1577 0 : dev->mode_config.tv_mode_property =
1578 0 : drm_property_create(dev, DRM_MODE_PROP_ENUM,
1579 : "mode", num_modes);
1580 0 : if (!dev->mode_config.tv_mode_property)
1581 : goto nomem;
1582 :
1583 0 : for (i = 0; i < num_modes; i++)
1584 0 : drm_property_add_enum(dev->mode_config.tv_mode_property, i,
1585 0 : i, modes[i]);
1586 :
1587 0 : dev->mode_config.tv_brightness_property =
1588 0 : drm_property_create_range(dev, 0, "brightness", 0, 100);
1589 0 : if (!dev->mode_config.tv_brightness_property)
1590 : goto nomem;
1591 :
1592 0 : dev->mode_config.tv_contrast_property =
1593 0 : drm_property_create_range(dev, 0, "contrast", 0, 100);
1594 0 : if (!dev->mode_config.tv_contrast_property)
1595 : goto nomem;
1596 :
1597 0 : dev->mode_config.tv_flicker_reduction_property =
1598 0 : drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
1599 0 : if (!dev->mode_config.tv_flicker_reduction_property)
1600 : goto nomem;
1601 :
1602 0 : dev->mode_config.tv_overscan_property =
1603 0 : drm_property_create_range(dev, 0, "overscan", 0, 100);
1604 0 : if (!dev->mode_config.tv_overscan_property)
1605 : goto nomem;
1606 :
1607 0 : dev->mode_config.tv_saturation_property =
1608 0 : drm_property_create_range(dev, 0, "saturation", 0, 100);
1609 0 : if (!dev->mode_config.tv_saturation_property)
1610 : goto nomem;
1611 :
1612 0 : dev->mode_config.tv_hue_property =
1613 0 : drm_property_create_range(dev, 0, "hue", 0, 100);
1614 0 : if (!dev->mode_config.tv_hue_property)
1615 : goto nomem;
1616 :
1617 0 : return 0;
1618 : nomem:
1619 0 : return -ENOMEM;
1620 0 : }
1621 : EXPORT_SYMBOL(drm_mode_create_tv_properties);
1622 :
1623 : /**
1624 : * drm_mode_create_scaling_mode_property - create scaling mode property
1625 : * @dev: DRM device
1626 : *
1627 : * Called by a driver the first time it's needed, must be attached to desired
1628 : * connectors.
1629 : */
1630 0 : int drm_mode_create_scaling_mode_property(struct drm_device *dev)
1631 : {
1632 : struct drm_property *scaling_mode;
1633 :
1634 0 : if (dev->mode_config.scaling_mode_property)
1635 0 : return 0;
1636 :
1637 : scaling_mode =
1638 0 : drm_property_create_enum(dev, 0, "scaling mode",
1639 : drm_scaling_mode_enum_list,
1640 : ARRAY_SIZE(drm_scaling_mode_enum_list));
1641 :
1642 0 : dev->mode_config.scaling_mode_property = scaling_mode;
1643 :
1644 0 : return 0;
1645 0 : }
1646 : EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
1647 :
1648 : /**
1649 : * drm_mode_create_aspect_ratio_property - create aspect ratio property
1650 : * @dev: DRM device
1651 : *
1652 : * Called by a driver the first time it's needed, must be attached to desired
1653 : * connectors.
1654 : *
1655 : * Returns:
1656 : * Zero on success, negative errno on failure.
1657 : */
1658 0 : int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
1659 : {
1660 0 : if (dev->mode_config.aspect_ratio_property)
1661 0 : return 0;
1662 :
1663 0 : dev->mode_config.aspect_ratio_property =
1664 0 : drm_property_create_enum(dev, 0, "aspect ratio",
1665 : drm_aspect_ratio_enum_list,
1666 : ARRAY_SIZE(drm_aspect_ratio_enum_list));
1667 :
1668 0 : if (dev->mode_config.aspect_ratio_property == NULL)
1669 0 : return -ENOMEM;
1670 :
1671 0 : return 0;
1672 0 : }
1673 : EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
1674 :
1675 : /**
1676 : * drm_mode_create_dirty_property - create dirty property
1677 : * @dev: DRM device
1678 : *
1679 : * Called by a driver the first time it's needed, must be attached to desired
1680 : * connectors.
1681 : */
1682 0 : int drm_mode_create_dirty_info_property(struct drm_device *dev)
1683 : {
1684 : struct drm_property *dirty_info;
1685 :
1686 0 : if (dev->mode_config.dirty_info_property)
1687 0 : return 0;
1688 :
1689 : dirty_info =
1690 0 : drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1691 : "dirty",
1692 : drm_dirty_info_enum_list,
1693 : ARRAY_SIZE(drm_dirty_info_enum_list));
1694 0 : dev->mode_config.dirty_info_property = dirty_info;
1695 :
1696 0 : return 0;
1697 0 : }
1698 : EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
1699 :
1700 : /**
1701 : * drm_mode_create_suggested_offset_properties - create suggests offset properties
1702 : * @dev: DRM device
1703 : *
1704 : * Create the the suggested x/y offset property for connectors.
1705 : */
1706 0 : int drm_mode_create_suggested_offset_properties(struct drm_device *dev)
1707 : {
1708 0 : if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property)
1709 0 : return 0;
1710 :
1711 0 : dev->mode_config.suggested_x_property =
1712 0 : drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff);
1713 :
1714 0 : dev->mode_config.suggested_y_property =
1715 0 : drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff);
1716 :
1717 0 : if (dev->mode_config.suggested_x_property == NULL ||
1718 0 : dev->mode_config.suggested_y_property == NULL)
1719 0 : return -ENOMEM;
1720 0 : return 0;
1721 0 : }
1722 : EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
1723 :
1724 : /**
1725 : * drm_mode_getresources - get graphics configuration
1726 : * @dev: drm device for the ioctl
1727 : * @data: data pointer for the ioctl
1728 : * @file_priv: drm file for the ioctl call
1729 : *
1730 : * Construct a set of configuration description structures and return
1731 : * them to the user, including CRTC, connector and framebuffer configuration.
1732 : *
1733 : * Called by the user via ioctl.
1734 : *
1735 : * Returns:
1736 : * Zero on success, negative errno on failure.
1737 : */
1738 0 : int drm_mode_getresources(struct drm_device *dev, void *data,
1739 : struct drm_file *file_priv)
1740 : {
1741 0 : struct drm_mode_card_res *card_res = data;
1742 : struct list_head *lh;
1743 : struct drm_framebuffer *fb;
1744 : struct drm_connector *connector;
1745 : struct drm_crtc *crtc;
1746 : struct drm_encoder *encoder;
1747 : int ret = 0;
1748 : int connector_count = 0;
1749 : int crtc_count = 0;
1750 : int fb_count = 0;
1751 : int encoder_count = 0;
1752 : int copied = 0;
1753 : uint32_t __user *fb_id;
1754 : uint32_t __user *crtc_id;
1755 : uint32_t __user *connector_id;
1756 : uint32_t __user *encoder_id;
1757 :
1758 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
1759 0 : return -EINVAL;
1760 :
1761 :
1762 0 : mutex_lock(&file_priv->fbs_lock);
1763 : /*
1764 : * For the non-control nodes we need to limit the list of resources
1765 : * by IDs in the group list for this node
1766 : */
1767 0 : list_for_each(lh, &file_priv->fbs)
1768 0 : fb_count++;
1769 :
1770 : /* handle this in 4 parts */
1771 : /* FBs */
1772 0 : if (card_res->count_fbs >= fb_count) {
1773 : copied = 0;
1774 0 : fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1775 0 : list_for_each_entry(fb, &file_priv->fbs, filp_head) {
1776 0 : if (put_user(fb->base.id, fb_id + copied)) {
1777 0 : mutex_unlock(&file_priv->fbs_lock);
1778 0 : return -EFAULT;
1779 : }
1780 0 : copied++;
1781 : }
1782 : }
1783 0 : card_res->count_fbs = fb_count;
1784 0 : mutex_unlock(&file_priv->fbs_lock);
1785 :
1786 : /* mode_config.mutex protects the connector list against e.g. DP MST
1787 : * connector hot-adding. CRTC/Plane lists are invariant. */
1788 0 : mutex_lock(&dev->mode_config.mutex);
1789 0 : drm_for_each_crtc(crtc, dev)
1790 0 : crtc_count++;
1791 :
1792 0 : drm_for_each_connector(connector, dev)
1793 0 : connector_count++;
1794 :
1795 0 : drm_for_each_encoder(encoder, dev)
1796 0 : encoder_count++;
1797 :
1798 0 : card_res->max_height = dev->mode_config.max_height;
1799 0 : card_res->min_height = dev->mode_config.min_height;
1800 0 : card_res->max_width = dev->mode_config.max_width;
1801 0 : card_res->min_width = dev->mode_config.min_width;
1802 :
1803 : /* CRTCs */
1804 0 : if (card_res->count_crtcs >= crtc_count) {
1805 : copied = 0;
1806 0 : crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1807 0 : drm_for_each_crtc(crtc, dev) {
1808 : DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1809 0 : if (put_user(crtc->base.id, crtc_id + copied)) {
1810 : ret = -EFAULT;
1811 0 : goto out;
1812 : }
1813 0 : copied++;
1814 : }
1815 : }
1816 0 : card_res->count_crtcs = crtc_count;
1817 :
1818 : /* Encoders */
1819 0 : if (card_res->count_encoders >= encoder_count) {
1820 : copied = 0;
1821 0 : encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
1822 0 : drm_for_each_encoder(encoder, dev) {
1823 : DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
1824 : encoder->name);
1825 0 : if (put_user(encoder->base.id, encoder_id +
1826 : copied)) {
1827 : ret = -EFAULT;
1828 0 : goto out;
1829 : }
1830 0 : copied++;
1831 : }
1832 : }
1833 0 : card_res->count_encoders = encoder_count;
1834 :
1835 : /* Connectors */
1836 0 : if (card_res->count_connectors >= connector_count) {
1837 : copied = 0;
1838 0 : connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
1839 0 : drm_for_each_connector(connector, dev) {
1840 : DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1841 : connector->base.id,
1842 : connector->name);
1843 0 : if (put_user(connector->base.id,
1844 : connector_id + copied)) {
1845 : ret = -EFAULT;
1846 0 : goto out;
1847 : }
1848 0 : copied++;
1849 : }
1850 : }
1851 0 : card_res->count_connectors = connector_count;
1852 :
1853 0 : DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
1854 : card_res->count_connectors, card_res->count_encoders);
1855 :
1856 : out:
1857 0 : mutex_unlock(&dev->mode_config.mutex);
1858 0 : return ret;
1859 0 : }
1860 :
1861 : /**
1862 : * drm_mode_getcrtc - get CRTC configuration
1863 : * @dev: drm device for the ioctl
1864 : * @data: data pointer for the ioctl
1865 : * @file_priv: drm file for the ioctl call
1866 : *
1867 : * Construct a CRTC configuration structure to return to the user.
1868 : *
1869 : * Called by the user via ioctl.
1870 : *
1871 : * Returns:
1872 : * Zero on success, negative errno on failure.
1873 : */
1874 0 : int drm_mode_getcrtc(struct drm_device *dev,
1875 : void *data, struct drm_file *file_priv)
1876 : {
1877 0 : struct drm_mode_crtc *crtc_resp = data;
1878 : struct drm_crtc *crtc;
1879 :
1880 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
1881 0 : return -EINVAL;
1882 :
1883 0 : crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
1884 0 : if (!crtc)
1885 0 : return -ENOENT;
1886 :
1887 0 : drm_modeset_lock_crtc(crtc, crtc->primary);
1888 0 : crtc_resp->gamma_size = crtc->gamma_size;
1889 0 : if (crtc->primary->fb)
1890 0 : crtc_resp->fb_id = crtc->primary->fb->base.id;
1891 : else
1892 0 : crtc_resp->fb_id = 0;
1893 :
1894 0 : if (crtc->state) {
1895 0 : crtc_resp->x = crtc->primary->state->src_x >> 16;
1896 0 : crtc_resp->y = crtc->primary->state->src_y >> 16;
1897 0 : if (crtc->state->enable) {
1898 0 : drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
1899 0 : crtc_resp->mode_valid = 1;
1900 :
1901 0 : } else {
1902 0 : crtc_resp->mode_valid = 0;
1903 : }
1904 : } else {
1905 0 : crtc_resp->x = crtc->x;
1906 0 : crtc_resp->y = crtc->y;
1907 0 : if (crtc->enabled) {
1908 0 : drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1909 0 : crtc_resp->mode_valid = 1;
1910 :
1911 0 : } else {
1912 0 : crtc_resp->mode_valid = 0;
1913 : }
1914 : }
1915 0 : drm_modeset_unlock_crtc(crtc);
1916 :
1917 0 : return 0;
1918 0 : }
1919 :
1920 0 : static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
1921 : const struct drm_file *file_priv)
1922 : {
1923 : /*
1924 : * If user-space hasn't configured the driver to expose the stereo 3D
1925 : * modes, don't expose them.
1926 : */
1927 0 : if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode))
1928 0 : return false;
1929 :
1930 0 : return true;
1931 0 : }
1932 :
1933 0 : static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector)
1934 : {
1935 : /* For atomic drivers only state objects are synchronously updated and
1936 : * protected by modeset locks, so check those first. */
1937 0 : if (connector->state)
1938 0 : return connector->state->best_encoder;
1939 0 : return connector->encoder;
1940 0 : }
1941 :
1942 : /* helper for getconnector and getproperties ioctls */
1943 0 : static int get_properties(struct drm_mode_object *obj, bool atomic,
1944 : uint32_t __user *prop_ptr, uint64_t __user *prop_values,
1945 : uint32_t *arg_count_props)
1946 : {
1947 : int props_count;
1948 : int i, ret, copied;
1949 :
1950 0 : props_count = obj->properties->count;
1951 0 : if (!atomic)
1952 0 : props_count -= obj->properties->atomic_count;
1953 :
1954 0 : if ((*arg_count_props >= props_count) && props_count) {
1955 0 : for (i = 0, copied = 0; copied < props_count; i++) {
1956 0 : struct drm_property *prop = obj->properties->properties[i];
1957 0 : uint64_t val;
1958 :
1959 0 : if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
1960 0 : continue;
1961 :
1962 0 : ret = drm_object_property_get_value(obj, prop, &val);
1963 0 : if (ret)
1964 0 : return ret;
1965 :
1966 0 : if (put_user(prop->base.id, prop_ptr + copied))
1967 0 : return -EFAULT;
1968 :
1969 0 : if (put_user(val, prop_values + copied))
1970 0 : return -EFAULT;
1971 :
1972 0 : copied++;
1973 0 : }
1974 : }
1975 0 : *arg_count_props = props_count;
1976 :
1977 0 : return 0;
1978 0 : }
1979 :
1980 : /**
1981 : * drm_mode_getconnector - get connector configuration
1982 : * @dev: drm device for the ioctl
1983 : * @data: data pointer for the ioctl
1984 : * @file_priv: drm file for the ioctl call
1985 : *
1986 : * Construct a connector configuration structure to return to the user.
1987 : *
1988 : * Called by the user via ioctl.
1989 : *
1990 : * Returns:
1991 : * Zero on success, negative errno on failure.
1992 : */
1993 0 : int drm_mode_getconnector(struct drm_device *dev, void *data,
1994 : struct drm_file *file_priv)
1995 : {
1996 0 : struct drm_mode_get_connector *out_resp = data;
1997 : struct drm_connector *connector;
1998 : struct drm_encoder *encoder;
1999 : struct drm_display_mode *mode;
2000 : int mode_count = 0;
2001 : int encoders_count = 0;
2002 : int ret = 0;
2003 : int copied = 0;
2004 : int i;
2005 0 : struct drm_mode_modeinfo u_mode;
2006 : struct drm_mode_modeinfo __user *mode_ptr;
2007 : uint32_t __user *encoder_ptr;
2008 :
2009 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
2010 0 : return -EINVAL;
2011 :
2012 0 : memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
2013 :
2014 : DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
2015 :
2016 0 : mutex_lock(&dev->mode_config.mutex);
2017 :
2018 0 : connector = drm_connector_find(dev, out_resp->connector_id);
2019 0 : if (!connector) {
2020 : ret = -ENOENT;
2021 0 : goto out_unlock;
2022 : }
2023 :
2024 0 : for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
2025 0 : if (connector->encoder_ids[i] != 0)
2026 0 : encoders_count++;
2027 :
2028 0 : if (out_resp->count_modes == 0) {
2029 0 : connector->funcs->fill_modes(connector,
2030 0 : dev->mode_config.max_width,
2031 0 : dev->mode_config.max_height);
2032 0 : }
2033 :
2034 : /* delayed so we get modes regardless of pre-fill_modes state */
2035 0 : list_for_each_entry(mode, &connector->modes, head)
2036 0 : if (drm_mode_expose_to_userspace(mode, file_priv))
2037 0 : mode_count++;
2038 :
2039 0 : out_resp->connector_id = connector->base.id;
2040 0 : out_resp->connector_type = connector->connector_type;
2041 0 : out_resp->connector_type_id = connector->connector_type_id;
2042 0 : out_resp->mm_width = connector->display_info.width_mm;
2043 0 : out_resp->mm_height = connector->display_info.height_mm;
2044 0 : out_resp->subpixel = connector->display_info.subpixel_order;
2045 0 : out_resp->connection = connector->status;
2046 :
2047 0 : drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2048 0 : encoder = drm_connector_get_encoder(connector);
2049 0 : if (encoder)
2050 0 : out_resp->encoder_id = encoder->base.id;
2051 : else
2052 0 : out_resp->encoder_id = 0;
2053 :
2054 : /*
2055 : * This ioctl is called twice, once to determine how much space is
2056 : * needed, and the 2nd time to fill it.
2057 : */
2058 0 : if ((out_resp->count_modes >= mode_count) && mode_count) {
2059 : copied = 0;
2060 0 : mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
2061 0 : list_for_each_entry(mode, &connector->modes, head) {
2062 0 : if (!drm_mode_expose_to_userspace(mode, file_priv))
2063 : continue;
2064 :
2065 0 : drm_mode_convert_to_umode(&u_mode, mode);
2066 0 : if (copy_to_user(mode_ptr + copied,
2067 : &u_mode, sizeof(u_mode))) {
2068 : ret = -EFAULT;
2069 0 : goto out;
2070 : }
2071 0 : copied++;
2072 0 : }
2073 : }
2074 0 : out_resp->count_modes = mode_count;
2075 :
2076 0 : ret = get_properties(&connector->base, file_priv->atomic,
2077 0 : (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
2078 0 : (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
2079 0 : &out_resp->count_props);
2080 0 : if (ret)
2081 : goto out;
2082 :
2083 0 : if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
2084 : copied = 0;
2085 0 : encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
2086 0 : for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2087 0 : if (connector->encoder_ids[i] != 0) {
2088 0 : if (put_user(connector->encoder_ids[i],
2089 : encoder_ptr + copied)) {
2090 : ret = -EFAULT;
2091 0 : goto out;
2092 : }
2093 0 : copied++;
2094 0 : }
2095 : }
2096 : }
2097 0 : out_resp->count_encoders = encoders_count;
2098 :
2099 : out:
2100 0 : drm_modeset_unlock(&dev->mode_config.connection_mutex);
2101 :
2102 : out_unlock:
2103 0 : mutex_unlock(&dev->mode_config.mutex);
2104 :
2105 0 : return ret;
2106 0 : }
2107 :
2108 0 : static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
2109 : {
2110 : struct drm_connector *connector;
2111 0 : struct drm_device *dev = encoder->dev;
2112 : bool uses_atomic = false;
2113 :
2114 : /* For atomic drivers only state objects are synchronously updated and
2115 : * protected by modeset locks, so check those first. */
2116 0 : drm_for_each_connector(connector, dev) {
2117 0 : if (!connector->state)
2118 : continue;
2119 :
2120 : uses_atomic = true;
2121 :
2122 0 : if (connector->state->best_encoder != encoder)
2123 : continue;
2124 :
2125 0 : return connector->state->crtc;
2126 : }
2127 :
2128 : /* Don't return stale data (e.g. pending async disable). */
2129 0 : if (uses_atomic)
2130 0 : return NULL;
2131 :
2132 0 : return encoder->crtc;
2133 0 : }
2134 :
2135 : /**
2136 : * drm_mode_getencoder - get encoder configuration
2137 : * @dev: drm device for the ioctl
2138 : * @data: data pointer for the ioctl
2139 : * @file_priv: drm file for the ioctl call
2140 : *
2141 : * Construct a encoder configuration structure to return to the user.
2142 : *
2143 : * Called by the user via ioctl.
2144 : *
2145 : * Returns:
2146 : * Zero on success, negative errno on failure.
2147 : */
2148 0 : int drm_mode_getencoder(struct drm_device *dev, void *data,
2149 : struct drm_file *file_priv)
2150 : {
2151 0 : struct drm_mode_get_encoder *enc_resp = data;
2152 : struct drm_encoder *encoder;
2153 : struct drm_crtc *crtc;
2154 :
2155 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
2156 0 : return -EINVAL;
2157 :
2158 0 : encoder = drm_encoder_find(dev, enc_resp->encoder_id);
2159 0 : if (!encoder)
2160 0 : return -ENOENT;
2161 :
2162 0 : drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2163 0 : crtc = drm_encoder_get_crtc(encoder);
2164 0 : if (crtc)
2165 0 : enc_resp->crtc_id = crtc->base.id;
2166 : else
2167 0 : enc_resp->crtc_id = 0;
2168 0 : drm_modeset_unlock(&dev->mode_config.connection_mutex);
2169 :
2170 0 : enc_resp->encoder_type = encoder->encoder_type;
2171 0 : enc_resp->encoder_id = encoder->base.id;
2172 0 : enc_resp->possible_crtcs = encoder->possible_crtcs;
2173 0 : enc_resp->possible_clones = encoder->possible_clones;
2174 :
2175 0 : return 0;
2176 0 : }
2177 :
2178 : /**
2179 : * drm_mode_getplane_res - enumerate all plane resources
2180 : * @dev: DRM device
2181 : * @data: ioctl data
2182 : * @file_priv: DRM file info
2183 : *
2184 : * Construct a list of plane ids to return to the user.
2185 : *
2186 : * Called by the user via ioctl.
2187 : *
2188 : * Returns:
2189 : * Zero on success, negative errno on failure.
2190 : */
2191 0 : int drm_mode_getplane_res(struct drm_device *dev, void *data,
2192 : struct drm_file *file_priv)
2193 : {
2194 0 : struct drm_mode_get_plane_res *plane_resp = data;
2195 : struct drm_mode_config *config;
2196 : struct drm_plane *plane;
2197 : uint32_t __user *plane_ptr;
2198 : int copied = 0;
2199 : unsigned num_planes;
2200 :
2201 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
2202 0 : return -EINVAL;
2203 :
2204 0 : config = &dev->mode_config;
2205 :
2206 0 : if (file_priv->universal_planes)
2207 0 : num_planes = config->num_total_plane;
2208 : else
2209 0 : num_planes = config->num_overlay_plane;
2210 :
2211 : /*
2212 : * This ioctl is called twice, once to determine how much space is
2213 : * needed, and the 2nd time to fill it.
2214 : */
2215 0 : if (num_planes &&
2216 0 : (plane_resp->count_planes >= num_planes)) {
2217 0 : plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
2218 :
2219 : /* Plane lists are invariant, no locking needed. */
2220 0 : drm_for_each_plane(plane, dev) {
2221 : /*
2222 : * Unless userspace set the 'universal planes'
2223 : * capability bit, only advertise overlays.
2224 : */
2225 0 : if (plane->type != DRM_PLANE_TYPE_OVERLAY &&
2226 0 : !file_priv->universal_planes)
2227 : continue;
2228 :
2229 0 : if (put_user(plane->base.id, plane_ptr + copied))
2230 0 : return -EFAULT;
2231 0 : copied++;
2232 0 : }
2233 : }
2234 0 : plane_resp->count_planes = num_planes;
2235 :
2236 0 : return 0;
2237 0 : }
2238 :
2239 : /**
2240 : * drm_mode_getplane - get plane configuration
2241 : * @dev: DRM device
2242 : * @data: ioctl data
2243 : * @file_priv: DRM file info
2244 : *
2245 : * Construct a plane configuration structure to return to the user.
2246 : *
2247 : * Called by the user via ioctl.
2248 : *
2249 : * Returns:
2250 : * Zero on success, negative errno on failure.
2251 : */
2252 0 : int drm_mode_getplane(struct drm_device *dev, void *data,
2253 : struct drm_file *file_priv)
2254 : {
2255 0 : struct drm_mode_get_plane *plane_resp = data;
2256 : struct drm_plane *plane;
2257 : uint32_t __user *format_ptr;
2258 :
2259 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
2260 0 : return -EINVAL;
2261 :
2262 0 : plane = drm_plane_find(dev, plane_resp->plane_id);
2263 0 : if (!plane)
2264 0 : return -ENOENT;
2265 :
2266 0 : drm_modeset_lock(&plane->mutex, NULL);
2267 0 : if (plane->crtc)
2268 0 : plane_resp->crtc_id = plane->crtc->base.id;
2269 : else
2270 0 : plane_resp->crtc_id = 0;
2271 :
2272 0 : if (plane->fb)
2273 0 : plane_resp->fb_id = plane->fb->base.id;
2274 : else
2275 0 : plane_resp->fb_id = 0;
2276 0 : drm_modeset_unlock(&plane->mutex);
2277 :
2278 0 : plane_resp->plane_id = plane->base.id;
2279 0 : plane_resp->possible_crtcs = plane->possible_crtcs;
2280 0 : plane_resp->gamma_size = 0;
2281 :
2282 : /*
2283 : * This ioctl is called twice, once to determine how much space is
2284 : * needed, and the 2nd time to fill it.
2285 : */
2286 0 : if (plane->format_count &&
2287 0 : (plane_resp->count_format_types >= plane->format_count)) {
2288 0 : format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
2289 0 : if (copy_to_user(format_ptr,
2290 0 : plane->format_types,
2291 0 : sizeof(uint32_t) * plane->format_count)) {
2292 0 : return -EFAULT;
2293 : }
2294 : }
2295 0 : plane_resp->count_format_types = plane->format_count;
2296 :
2297 0 : return 0;
2298 0 : }
2299 :
2300 : /**
2301 : * drm_plane_check_pixel_format - Check if the plane supports the pixel format
2302 : * @plane: plane to check for format support
2303 : * @format: the pixel format
2304 : *
2305 : * Returns:
2306 : * Zero of @plane has @format in its list of supported pixel formats, -EINVAL
2307 : * otherwise.
2308 : */
2309 0 : int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format)
2310 : {
2311 : unsigned int i;
2312 :
2313 0 : for (i = 0; i < plane->format_count; i++) {
2314 0 : if (format == plane->format_types[i])
2315 0 : return 0;
2316 : }
2317 :
2318 0 : return -EINVAL;
2319 0 : }
2320 :
2321 0 : static int check_src_coords(uint32_t src_x, uint32_t src_y,
2322 : uint32_t src_w, uint32_t src_h,
2323 : const struct drm_framebuffer *fb)
2324 : {
2325 : unsigned int fb_width, fb_height;
2326 :
2327 0 : fb_width = fb->width << 16;
2328 0 : fb_height = fb->height << 16;
2329 :
2330 : /* Make sure source coordinates are inside the fb. */
2331 0 : if (src_w > fb_width ||
2332 0 : src_x > fb_width - src_w ||
2333 0 : src_h > fb_height ||
2334 0 : src_y > fb_height - src_h) {
2335 : DRM_DEBUG_KMS("Invalid source coordinates "
2336 : "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
2337 : src_w >> 16, ((src_w & 0xffff) * 15625) >> 10,
2338 : src_h >> 16, ((src_h & 0xffff) * 15625) >> 10,
2339 : src_x >> 16, ((src_x & 0xffff) * 15625) >> 10,
2340 : src_y >> 16, ((src_y & 0xffff) * 15625) >> 10);
2341 0 : return -ENOSPC;
2342 : }
2343 :
2344 0 : return 0;
2345 0 : }
2346 :
2347 : /*
2348 : * setplane_internal - setplane handler for internal callers
2349 : *
2350 : * Note that we assume an extra reference has already been taken on fb. If the
2351 : * update fails, this reference will be dropped before return; if it succeeds,
2352 : * the previous framebuffer (if any) will be unreferenced instead.
2353 : *
2354 : * src_{x,y,w,h} are provided in 16.16 fixed point format
2355 : */
2356 0 : static int __setplane_internal(struct drm_plane *plane,
2357 : struct drm_crtc *crtc,
2358 : struct drm_framebuffer *fb,
2359 : int32_t crtc_x, int32_t crtc_y,
2360 : uint32_t crtc_w, uint32_t crtc_h,
2361 : /* src_{x,y,w,h} values are 16.16 fixed point */
2362 : uint32_t src_x, uint32_t src_y,
2363 : uint32_t src_w, uint32_t src_h)
2364 : {
2365 : int ret = 0;
2366 :
2367 : /* No fb means shut it down */
2368 0 : if (!fb) {
2369 0 : plane->old_fb = plane->fb;
2370 0 : ret = plane->funcs->disable_plane(plane);
2371 0 : if (!ret) {
2372 0 : plane->crtc = NULL;
2373 0 : plane->fb = NULL;
2374 0 : } else {
2375 0 : plane->old_fb = NULL;
2376 : }
2377 : goto out;
2378 : }
2379 :
2380 : /* Check whether this plane is usable on this CRTC */
2381 0 : if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
2382 : DRM_DEBUG_KMS("Invalid crtc for plane\n");
2383 : ret = -EINVAL;
2384 0 : goto out;
2385 : }
2386 :
2387 : /* Check whether this plane supports the fb pixel format. */
2388 0 : ret = drm_plane_check_pixel_format(plane, fb->pixel_format);
2389 0 : if (ret) {
2390 : DRM_DEBUG_KMS("Invalid pixel format %s\n",
2391 : drm_get_format_name(fb->pixel_format));
2392 : goto out;
2393 : }
2394 :
2395 : /* Give drivers some help against integer overflows */
2396 0 : if (crtc_w > INT_MAX ||
2397 0 : crtc_x > INT_MAX - (int32_t) crtc_w ||
2398 0 : crtc_h > INT_MAX ||
2399 0 : crtc_y > INT_MAX - (int32_t) crtc_h) {
2400 : DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
2401 : crtc_w, crtc_h, crtc_x, crtc_y);
2402 : ret = -ERANGE;
2403 0 : goto out;
2404 : }
2405 :
2406 0 : ret = check_src_coords(src_x, src_y, src_w, src_h, fb);
2407 0 : if (ret)
2408 : goto out;
2409 :
2410 0 : plane->old_fb = plane->fb;
2411 0 : ret = plane->funcs->update_plane(plane, crtc, fb,
2412 : crtc_x, crtc_y, crtc_w, crtc_h,
2413 : src_x, src_y, src_w, src_h);
2414 0 : if (!ret) {
2415 0 : plane->crtc = crtc;
2416 0 : plane->fb = fb;
2417 : fb = NULL;
2418 0 : } else {
2419 0 : plane->old_fb = NULL;
2420 : }
2421 :
2422 : out:
2423 0 : if (fb)
2424 0 : drm_framebuffer_unreference(fb);
2425 0 : if (plane->old_fb)
2426 0 : drm_framebuffer_unreference(plane->old_fb);
2427 0 : plane->old_fb = NULL;
2428 :
2429 0 : return ret;
2430 : }
2431 :
2432 0 : static int setplane_internal(struct drm_plane *plane,
2433 : struct drm_crtc *crtc,
2434 : struct drm_framebuffer *fb,
2435 : int32_t crtc_x, int32_t crtc_y,
2436 : uint32_t crtc_w, uint32_t crtc_h,
2437 : /* src_{x,y,w,h} values are 16.16 fixed point */
2438 : uint32_t src_x, uint32_t src_y,
2439 : uint32_t src_w, uint32_t src_h)
2440 : {
2441 : int ret;
2442 :
2443 0 : drm_modeset_lock_all(plane->dev);
2444 0 : ret = __setplane_internal(plane, crtc, fb,
2445 : crtc_x, crtc_y, crtc_w, crtc_h,
2446 : src_x, src_y, src_w, src_h);
2447 0 : drm_modeset_unlock_all(plane->dev);
2448 :
2449 0 : return ret;
2450 : }
2451 :
2452 : /**
2453 : * drm_mode_setplane - configure a plane's configuration
2454 : * @dev: DRM device
2455 : * @data: ioctl data*
2456 : * @file_priv: DRM file info
2457 : *
2458 : * Set plane configuration, including placement, fb, scaling, and other factors.
2459 : * Or pass a NULL fb to disable (planes may be disabled without providing a
2460 : * valid crtc).
2461 : *
2462 : * Returns:
2463 : * Zero on success, negative errno on failure.
2464 : */
2465 0 : int drm_mode_setplane(struct drm_device *dev, void *data,
2466 : struct drm_file *file_priv)
2467 : {
2468 0 : struct drm_mode_set_plane *plane_req = data;
2469 : struct drm_plane *plane;
2470 : struct drm_crtc *crtc = NULL;
2471 : struct drm_framebuffer *fb = NULL;
2472 :
2473 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
2474 0 : return -EINVAL;
2475 :
2476 : /*
2477 : * First, find the plane, crtc, and fb objects. If not available,
2478 : * we don't bother to call the driver.
2479 : */
2480 0 : plane = drm_plane_find(dev, plane_req->plane_id);
2481 0 : if (!plane) {
2482 : DRM_DEBUG_KMS("Unknown plane ID %d\n",
2483 : plane_req->plane_id);
2484 0 : return -ENOENT;
2485 : }
2486 :
2487 0 : if (plane_req->fb_id) {
2488 0 : fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
2489 0 : if (!fb) {
2490 : DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
2491 : plane_req->fb_id);
2492 0 : return -ENOENT;
2493 : }
2494 :
2495 0 : crtc = drm_crtc_find(dev, plane_req->crtc_id);
2496 0 : if (!crtc) {
2497 : DRM_DEBUG_KMS("Unknown crtc ID %d\n",
2498 : plane_req->crtc_id);
2499 0 : return -ENOENT;
2500 : }
2501 : }
2502 :
2503 : /*
2504 : * setplane_internal will take care of deref'ing either the old or new
2505 : * framebuffer depending on success.
2506 : */
2507 0 : return setplane_internal(plane, crtc, fb,
2508 0 : plane_req->crtc_x, plane_req->crtc_y,
2509 0 : plane_req->crtc_w, plane_req->crtc_h,
2510 0 : plane_req->src_x, plane_req->src_y,
2511 0 : plane_req->src_w, plane_req->src_h);
2512 0 : }
2513 :
2514 : /**
2515 : * drm_mode_set_config_internal - helper to call ->set_config
2516 : * @set: modeset config to set
2517 : *
2518 : * This is a little helper to wrap internal calls to the ->set_config driver
2519 : * interface. The only thing it adds is correct refcounting dance.
2520 : *
2521 : * Returns:
2522 : * Zero on success, negative errno on failure.
2523 : */
2524 0 : int drm_mode_set_config_internal(struct drm_mode_set *set)
2525 : {
2526 0 : struct drm_crtc *crtc = set->crtc;
2527 : struct drm_framebuffer *fb;
2528 : struct drm_crtc *tmp;
2529 : int ret;
2530 :
2531 : /*
2532 : * NOTE: ->set_config can also disable other crtcs (if we steal all
2533 : * connectors from it), hence we need to refcount the fbs across all
2534 : * crtcs. Atomic modeset will have saner semantics ...
2535 : */
2536 0 : drm_for_each_crtc(tmp, crtc->dev)
2537 0 : tmp->primary->old_fb = tmp->primary->fb;
2538 :
2539 0 : fb = set->fb;
2540 :
2541 0 : ret = crtc->funcs->set_config(set);
2542 0 : if (ret == 0) {
2543 0 : crtc->primary->crtc = crtc;
2544 0 : crtc->primary->fb = fb;
2545 0 : }
2546 :
2547 0 : drm_for_each_crtc(tmp, crtc->dev) {
2548 0 : if (tmp->primary->fb)
2549 0 : drm_framebuffer_reference(tmp->primary->fb);
2550 0 : if (tmp->primary->old_fb)
2551 0 : drm_framebuffer_unreference(tmp->primary->old_fb);
2552 0 : tmp->primary->old_fb = NULL;
2553 : }
2554 :
2555 0 : return ret;
2556 : }
2557 : EXPORT_SYMBOL(drm_mode_set_config_internal);
2558 :
2559 : /**
2560 : * drm_crtc_get_hv_timing - Fetches hdisplay/vdisplay for given mode
2561 : * @mode: mode to query
2562 : * @hdisplay: hdisplay value to fill in
2563 : * @vdisplay: vdisplay value to fill in
2564 : *
2565 : * The vdisplay value will be doubled if the specified mode is a stereo mode of
2566 : * the appropriate layout.
2567 : */
2568 0 : void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
2569 : int *hdisplay, int *vdisplay)
2570 : {
2571 0 : struct drm_display_mode adjusted;
2572 :
2573 0 : drm_mode_copy(&adjusted, mode);
2574 0 : drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE_ONLY);
2575 0 : *hdisplay = adjusted.crtc_hdisplay;
2576 0 : *vdisplay = adjusted.crtc_vdisplay;
2577 0 : }
2578 : EXPORT_SYMBOL(drm_crtc_get_hv_timing);
2579 :
2580 : /**
2581 : * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
2582 : * CRTC viewport
2583 : * @crtc: CRTC that framebuffer will be displayed on
2584 : * @x: x panning
2585 : * @y: y panning
2586 : * @mode: mode that framebuffer will be displayed under
2587 : * @fb: framebuffer to check size of
2588 : */
2589 0 : int drm_crtc_check_viewport(const struct drm_crtc *crtc,
2590 : int x, int y,
2591 : const struct drm_display_mode *mode,
2592 : const struct drm_framebuffer *fb)
2593 :
2594 : {
2595 0 : int hdisplay, vdisplay;
2596 :
2597 0 : drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
2598 :
2599 0 : if (crtc->state &&
2600 0 : crtc->primary->state->rotation & (BIT(DRM_ROTATE_90) |
2601 : BIT(DRM_ROTATE_270)))
2602 0 : swap(hdisplay, vdisplay);
2603 :
2604 0 : return check_src_coords(x << 16, y << 16,
2605 0 : hdisplay << 16, vdisplay << 16, fb);
2606 0 : }
2607 : EXPORT_SYMBOL(drm_crtc_check_viewport);
2608 :
2609 : /**
2610 : * drm_mode_setcrtc - set CRTC configuration
2611 : * @dev: drm device for the ioctl
2612 : * @data: data pointer for the ioctl
2613 : * @file_priv: drm file for the ioctl call
2614 : *
2615 : * Build a new CRTC configuration based on user request.
2616 : *
2617 : * Called by the user via ioctl.
2618 : *
2619 : * Returns:
2620 : * Zero on success, negative errno on failure.
2621 : */
2622 0 : int drm_mode_setcrtc(struct drm_device *dev, void *data,
2623 : struct drm_file *file_priv)
2624 : {
2625 0 : struct drm_mode_config *config = &dev->mode_config;
2626 0 : struct drm_mode_crtc *crtc_req = data;
2627 : struct drm_crtc *crtc;
2628 : struct drm_connector **connector_set = NULL, *connector;
2629 : struct drm_framebuffer *fb = NULL;
2630 : struct drm_display_mode *mode = NULL;
2631 0 : struct drm_mode_set set;
2632 : uint32_t __user *set_connectors_ptr;
2633 : int ret;
2634 : int i;
2635 :
2636 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
2637 0 : return -EINVAL;
2638 :
2639 : /*
2640 : * Universal plane src offsets are only 16.16, prevent havoc for
2641 : * drivers using universal plane code internally.
2642 : */
2643 0 : if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
2644 0 : return -ERANGE;
2645 :
2646 0 : drm_modeset_lock_all(dev);
2647 0 : crtc = drm_crtc_find(dev, crtc_req->crtc_id);
2648 0 : if (!crtc) {
2649 : DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
2650 : ret = -ENOENT;
2651 0 : goto out;
2652 : }
2653 : DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
2654 :
2655 0 : if (crtc_req->mode_valid) {
2656 : /* If we have a mode we need a framebuffer. */
2657 : /* If we pass -1, set the mode with the currently bound fb */
2658 0 : if (crtc_req->fb_id == -1) {
2659 0 : if (!crtc->primary->fb) {
2660 : DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
2661 : ret = -EINVAL;
2662 0 : goto out;
2663 : }
2664 : fb = crtc->primary->fb;
2665 : /* Make refcounting symmetric with the lookup path. */
2666 0 : drm_framebuffer_reference(fb);
2667 0 : } else {
2668 0 : fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
2669 0 : if (!fb) {
2670 : DRM_DEBUG_KMS("Unknown FB ID%d\n",
2671 : crtc_req->fb_id);
2672 : ret = -ENOENT;
2673 0 : goto out;
2674 : }
2675 : }
2676 :
2677 0 : mode = drm_mode_create(dev);
2678 0 : if (!mode) {
2679 : ret = -ENOMEM;
2680 0 : goto out;
2681 : }
2682 :
2683 0 : ret = drm_mode_convert_umode(mode, &crtc_req->mode);
2684 0 : if (ret) {
2685 : DRM_DEBUG_KMS("Invalid mode\n");
2686 : goto out;
2687 : }
2688 :
2689 : /*
2690 : * Check whether the primary plane supports the fb pixel format.
2691 : * Drivers not implementing the universal planes API use a
2692 : * default formats list provided by the DRM core which doesn't
2693 : * match real hardware capabilities. Skip the check in that
2694 : * case.
2695 : */
2696 0 : if (!crtc->primary->format_default) {
2697 0 : ret = drm_plane_check_pixel_format(crtc->primary,
2698 0 : fb->pixel_format);
2699 0 : if (ret) {
2700 : DRM_DEBUG_KMS("Invalid pixel format %s\n",
2701 : drm_get_format_name(fb->pixel_format));
2702 : goto out;
2703 : }
2704 : }
2705 :
2706 0 : ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
2707 : mode, fb);
2708 0 : if (ret)
2709 : goto out;
2710 :
2711 : }
2712 :
2713 0 : if (crtc_req->count_connectors == 0 && mode) {
2714 : DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
2715 : ret = -EINVAL;
2716 0 : goto out;
2717 : }
2718 :
2719 0 : if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
2720 : DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
2721 : crtc_req->count_connectors);
2722 : ret = -EINVAL;
2723 0 : goto out;
2724 : }
2725 :
2726 0 : if (crtc_req->count_connectors > 0) {
2727 0 : u32 out_id;
2728 :
2729 : /* Avoid unbounded kernel memory allocation */
2730 0 : if (crtc_req->count_connectors > config->num_connector) {
2731 : ret = -EINVAL;
2732 0 : goto out;
2733 : }
2734 :
2735 0 : connector_set = kmalloc_array(crtc_req->count_connectors,
2736 : sizeof(struct drm_connector *),
2737 : GFP_KERNEL);
2738 0 : if (!connector_set) {
2739 : ret = -ENOMEM;
2740 0 : goto out;
2741 : }
2742 :
2743 0 : for (i = 0; i < crtc_req->count_connectors; i++) {
2744 0 : set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
2745 0 : if (get_user(out_id, &set_connectors_ptr[i])) {
2746 : ret = -EFAULT;
2747 0 : goto out;
2748 : }
2749 :
2750 0 : connector = drm_connector_find(dev, out_id);
2751 0 : if (!connector) {
2752 : DRM_DEBUG_KMS("Connector id %d unknown\n",
2753 : out_id);
2754 : ret = -ENOENT;
2755 0 : goto out;
2756 : }
2757 : DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
2758 : connector->base.id,
2759 : connector->name);
2760 :
2761 0 : connector_set[i] = connector;
2762 : }
2763 0 : }
2764 :
2765 0 : set.crtc = crtc;
2766 0 : set.x = crtc_req->x;
2767 0 : set.y = crtc_req->y;
2768 0 : set.mode = mode;
2769 0 : set.connectors = connector_set;
2770 0 : set.num_connectors = crtc_req->count_connectors;
2771 0 : set.fb = fb;
2772 0 : ret = drm_mode_set_config_internal(&set);
2773 :
2774 : out:
2775 0 : if (fb)
2776 0 : drm_framebuffer_unreference(fb);
2777 :
2778 0 : kfree(connector_set);
2779 0 : drm_mode_destroy(dev, mode);
2780 0 : drm_modeset_unlock_all(dev);
2781 0 : return ret;
2782 0 : }
2783 :
2784 : /**
2785 : * drm_mode_cursor_universal - translate legacy cursor ioctl call into a
2786 : * universal plane handler call
2787 : * @crtc: crtc to update cursor for
2788 : * @req: data pointer for the ioctl
2789 : * @file_priv: drm file for the ioctl call
2790 : *
2791 : * Legacy cursor ioctl's work directly with driver buffer handles. To
2792 : * translate legacy ioctl calls into universal plane handler calls, we need to
2793 : * wrap the native buffer handle in a drm_framebuffer.
2794 : *
2795 : * Note that we assume any handle passed to the legacy ioctls was a 32-bit ARGB
2796 : * buffer with a pitch of 4*width; the universal plane interface should be used
2797 : * directly in cases where the hardware can support other buffer settings and
2798 : * userspace wants to make use of these capabilities.
2799 : *
2800 : * Returns:
2801 : * Zero on success, negative errno on failure.
2802 : */
2803 0 : static int drm_mode_cursor_universal(struct drm_crtc *crtc,
2804 : struct drm_mode_cursor2 *req,
2805 : struct drm_file *file_priv)
2806 : {
2807 0 : struct drm_device *dev = crtc->dev;
2808 : struct drm_framebuffer *fb = NULL;
2809 0 : struct drm_mode_fb_cmd2 fbreq = {
2810 0 : .width = req->width,
2811 0 : .height = req->height,
2812 : .pixel_format = DRM_FORMAT_ARGB8888,
2813 0 : .pitches = { req->width * 4 },
2814 0 : .handles = { req->handle },
2815 : };
2816 : int32_t crtc_x, crtc_y;
2817 : uint32_t crtc_w = 0, crtc_h = 0;
2818 : uint32_t src_w = 0, src_h = 0;
2819 : int ret = 0;
2820 :
2821 0 : BUG_ON(!crtc->cursor);
2822 0 : WARN_ON(crtc->cursor->crtc != crtc && crtc->cursor->crtc != NULL);
2823 :
2824 : /*
2825 : * Obtain fb we'll be using (either new or existing) and take an extra
2826 : * reference to it if fb != null. setplane will take care of dropping
2827 : * the reference if the plane update fails.
2828 : */
2829 0 : if (req->flags & DRM_MODE_CURSOR_BO) {
2830 0 : if (req->handle) {
2831 0 : fb = internal_framebuffer_create(dev, &fbreq, file_priv);
2832 0 : if (IS_ERR(fb)) {
2833 : DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
2834 0 : return PTR_ERR(fb);
2835 : }
2836 : } else {
2837 : fb = NULL;
2838 : }
2839 : } else {
2840 0 : fb = crtc->cursor->fb;
2841 0 : if (fb)
2842 0 : drm_framebuffer_reference(fb);
2843 : }
2844 :
2845 0 : if (req->flags & DRM_MODE_CURSOR_MOVE) {
2846 0 : crtc_x = req->x;
2847 0 : crtc_y = req->y;
2848 0 : } else {
2849 0 : crtc_x = crtc->cursor_x;
2850 0 : crtc_y = crtc->cursor_y;
2851 : }
2852 :
2853 0 : if (fb) {
2854 0 : crtc_w = fb->width;
2855 0 : crtc_h = fb->height;
2856 0 : src_w = fb->width << 16;
2857 0 : src_h = fb->height << 16;
2858 0 : }
2859 :
2860 : /*
2861 : * setplane_internal will take care of deref'ing either the old or new
2862 : * framebuffer depending on success.
2863 : */
2864 0 : ret = __setplane_internal(crtc->cursor, crtc, fb,
2865 : crtc_x, crtc_y, crtc_w, crtc_h,
2866 : 0, 0, src_w, src_h);
2867 :
2868 : /* Update successful; save new cursor position, if necessary */
2869 0 : if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) {
2870 0 : crtc->cursor_x = req->x;
2871 0 : crtc->cursor_y = req->y;
2872 0 : }
2873 :
2874 0 : return ret;
2875 0 : }
2876 :
2877 0 : static int drm_mode_cursor_common(struct drm_device *dev,
2878 : struct drm_mode_cursor2 *req,
2879 : struct drm_file *file_priv)
2880 : {
2881 : struct drm_crtc *crtc;
2882 : int ret = 0;
2883 :
2884 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
2885 0 : return -EINVAL;
2886 :
2887 0 : if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
2888 0 : return -EINVAL;
2889 :
2890 0 : crtc = drm_crtc_find(dev, req->crtc_id);
2891 0 : if (!crtc) {
2892 : DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
2893 0 : return -ENOENT;
2894 : }
2895 :
2896 : /*
2897 : * If this crtc has a universal cursor plane, call that plane's update
2898 : * handler rather than using legacy cursor handlers.
2899 : */
2900 0 : drm_modeset_lock_crtc(crtc, crtc->cursor);
2901 0 : if (crtc->cursor) {
2902 0 : ret = drm_mode_cursor_universal(crtc, req, file_priv);
2903 0 : goto out;
2904 : }
2905 :
2906 0 : if (req->flags & DRM_MODE_CURSOR_BO) {
2907 0 : if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
2908 : ret = -ENXIO;
2909 0 : goto out;
2910 : }
2911 : /* Turns off the cursor if handle is 0 */
2912 0 : if (crtc->funcs->cursor_set2)
2913 0 : ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
2914 0 : req->width, req->height, req->hot_x, req->hot_y);
2915 : else
2916 0 : ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
2917 0 : req->width, req->height);
2918 : }
2919 :
2920 0 : if (req->flags & DRM_MODE_CURSOR_MOVE) {
2921 0 : if (crtc->funcs->cursor_move) {
2922 0 : ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
2923 : } else {
2924 : ret = -EFAULT;
2925 0 : goto out;
2926 : }
2927 0 : }
2928 : out:
2929 0 : drm_modeset_unlock_crtc(crtc);
2930 :
2931 0 : return ret;
2932 :
2933 0 : }
2934 :
2935 :
2936 : /**
2937 : * drm_mode_cursor_ioctl - set CRTC's cursor configuration
2938 : * @dev: drm device for the ioctl
2939 : * @data: data pointer for the ioctl
2940 : * @file_priv: drm file for the ioctl call
2941 : *
2942 : * Set the cursor configuration based on user request.
2943 : *
2944 : * Called by the user via ioctl.
2945 : *
2946 : * Returns:
2947 : * Zero on success, negative errno on failure.
2948 : */
2949 0 : int drm_mode_cursor_ioctl(struct drm_device *dev,
2950 : void *data, struct drm_file *file_priv)
2951 : {
2952 0 : struct drm_mode_cursor *req = data;
2953 0 : struct drm_mode_cursor2 new_req;
2954 :
2955 0 : memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
2956 0 : new_req.hot_x = new_req.hot_y = 0;
2957 :
2958 0 : return drm_mode_cursor_common(dev, &new_req, file_priv);
2959 0 : }
2960 :
2961 : /**
2962 : * drm_mode_cursor2_ioctl - set CRTC's cursor configuration
2963 : * @dev: drm device for the ioctl
2964 : * @data: data pointer for the ioctl
2965 : * @file_priv: drm file for the ioctl call
2966 : *
2967 : * Set the cursor configuration based on user request. This implements the 2nd
2968 : * version of the cursor ioctl, which allows userspace to additionally specify
2969 : * the hotspot of the pointer.
2970 : *
2971 : * Called by the user via ioctl.
2972 : *
2973 : * Returns:
2974 : * Zero on success, negative errno on failure.
2975 : */
2976 0 : int drm_mode_cursor2_ioctl(struct drm_device *dev,
2977 : void *data, struct drm_file *file_priv)
2978 : {
2979 0 : struct drm_mode_cursor2 *req = data;
2980 :
2981 0 : return drm_mode_cursor_common(dev, req, file_priv);
2982 : }
2983 :
2984 : /**
2985 : * drm_mode_legacy_fb_format - compute drm fourcc code from legacy description
2986 : * @bpp: bits per pixels
2987 : * @depth: bit depth per pixel
2988 : *
2989 : * Computes a drm fourcc pixel format code for the given @bpp/@depth values.
2990 : * Useful in fbdev emulation code, since that deals in those values.
2991 : */
2992 0 : uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
2993 : {
2994 : uint32_t fmt;
2995 :
2996 0 : switch (bpp) {
2997 : case 8:
2998 : fmt = DRM_FORMAT_C8;
2999 0 : break;
3000 : case 16:
3001 0 : if (depth == 15)
3002 0 : fmt = DRM_FORMAT_XRGB1555;
3003 : else
3004 : fmt = DRM_FORMAT_RGB565;
3005 : break;
3006 : case 24:
3007 : fmt = DRM_FORMAT_RGB888;
3008 0 : break;
3009 : case 32:
3010 0 : if (depth == 24)
3011 0 : fmt = DRM_FORMAT_XRGB8888;
3012 0 : else if (depth == 30)
3013 0 : fmt = DRM_FORMAT_XRGB2101010;
3014 : else
3015 : fmt = DRM_FORMAT_ARGB8888;
3016 : break;
3017 : default:
3018 0 : DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
3019 : fmt = DRM_FORMAT_XRGB8888;
3020 0 : break;
3021 : }
3022 :
3023 0 : return fmt;
3024 : }
3025 : EXPORT_SYMBOL(drm_mode_legacy_fb_format);
3026 :
3027 : /**
3028 : * drm_mode_addfb - add an FB to the graphics configuration
3029 : * @dev: drm device for the ioctl
3030 : * @data: data pointer for the ioctl
3031 : * @file_priv: drm file for the ioctl call
3032 : *
3033 : * Add a new FB to the specified CRTC, given a user request. This is the
3034 : * original addfb ioctl which only supported RGB formats.
3035 : *
3036 : * Called by the user via ioctl.
3037 : *
3038 : * Returns:
3039 : * Zero on success, negative errno on failure.
3040 : */
3041 0 : int drm_mode_addfb(struct drm_device *dev,
3042 : void *data, struct drm_file *file_priv)
3043 : {
3044 0 : struct drm_mode_fb_cmd *or = data;
3045 0 : struct drm_mode_fb_cmd2 r = {};
3046 : int ret;
3047 :
3048 : /* convert to new format and call new ioctl */
3049 0 : r.fb_id = or->fb_id;
3050 0 : r.width = or->width;
3051 0 : r.height = or->height;
3052 0 : r.pitches[0] = or->pitch;
3053 0 : r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
3054 0 : r.handles[0] = or->handle;
3055 :
3056 0 : ret = drm_mode_addfb2(dev, &r, file_priv);
3057 0 : if (ret)
3058 0 : return ret;
3059 :
3060 0 : or->fb_id = r.fb_id;
3061 :
3062 0 : return 0;
3063 0 : }
3064 :
3065 0 : static int format_check(const struct drm_mode_fb_cmd2 *r)
3066 : {
3067 0 : uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN;
3068 :
3069 0 : switch (format) {
3070 : case DRM_FORMAT_C8:
3071 : case DRM_FORMAT_RGB332:
3072 : case DRM_FORMAT_BGR233:
3073 : case DRM_FORMAT_XRGB4444:
3074 : case DRM_FORMAT_XBGR4444:
3075 : case DRM_FORMAT_RGBX4444:
3076 : case DRM_FORMAT_BGRX4444:
3077 : case DRM_FORMAT_ARGB4444:
3078 : case DRM_FORMAT_ABGR4444:
3079 : case DRM_FORMAT_RGBA4444:
3080 : case DRM_FORMAT_BGRA4444:
3081 : case DRM_FORMAT_XRGB1555:
3082 : case DRM_FORMAT_XBGR1555:
3083 : case DRM_FORMAT_RGBX5551:
3084 : case DRM_FORMAT_BGRX5551:
3085 : case DRM_FORMAT_ARGB1555:
3086 : case DRM_FORMAT_ABGR1555:
3087 : case DRM_FORMAT_RGBA5551:
3088 : case DRM_FORMAT_BGRA5551:
3089 : case DRM_FORMAT_RGB565:
3090 : case DRM_FORMAT_BGR565:
3091 : case DRM_FORMAT_RGB888:
3092 : case DRM_FORMAT_BGR888:
3093 : case DRM_FORMAT_XRGB8888:
3094 : case DRM_FORMAT_XBGR8888:
3095 : case DRM_FORMAT_RGBX8888:
3096 : case DRM_FORMAT_BGRX8888:
3097 : case DRM_FORMAT_ARGB8888:
3098 : case DRM_FORMAT_ABGR8888:
3099 : case DRM_FORMAT_RGBA8888:
3100 : case DRM_FORMAT_BGRA8888:
3101 : case DRM_FORMAT_XRGB2101010:
3102 : case DRM_FORMAT_XBGR2101010:
3103 : case DRM_FORMAT_RGBX1010102:
3104 : case DRM_FORMAT_BGRX1010102:
3105 : case DRM_FORMAT_ARGB2101010:
3106 : case DRM_FORMAT_ABGR2101010:
3107 : case DRM_FORMAT_RGBA1010102:
3108 : case DRM_FORMAT_BGRA1010102:
3109 : case DRM_FORMAT_YUYV:
3110 : case DRM_FORMAT_YVYU:
3111 : case DRM_FORMAT_UYVY:
3112 : case DRM_FORMAT_VYUY:
3113 : case DRM_FORMAT_AYUV:
3114 : case DRM_FORMAT_NV12:
3115 : case DRM_FORMAT_NV21:
3116 : case DRM_FORMAT_NV16:
3117 : case DRM_FORMAT_NV61:
3118 : case DRM_FORMAT_NV24:
3119 : case DRM_FORMAT_NV42:
3120 : case DRM_FORMAT_YUV410:
3121 : case DRM_FORMAT_YVU410:
3122 : case DRM_FORMAT_YUV411:
3123 : case DRM_FORMAT_YVU411:
3124 : case DRM_FORMAT_YUV420:
3125 : case DRM_FORMAT_YVU420:
3126 : case DRM_FORMAT_YUV422:
3127 : case DRM_FORMAT_YVU422:
3128 : case DRM_FORMAT_YUV444:
3129 : case DRM_FORMAT_YVU444:
3130 0 : return 0;
3131 : default:
3132 : DRM_DEBUG_KMS("invalid pixel format %s\n",
3133 : drm_get_format_name(r->pixel_format));
3134 0 : return -EINVAL;
3135 : }
3136 0 : }
3137 :
3138 0 : static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
3139 : {
3140 : int ret, hsub, vsub, num_planes, i;
3141 :
3142 0 : ret = format_check(r);
3143 0 : if (ret) {
3144 : DRM_DEBUG_KMS("bad framebuffer format %s\n",
3145 : drm_get_format_name(r->pixel_format));
3146 0 : return ret;
3147 : }
3148 :
3149 0 : hsub = drm_format_horz_chroma_subsampling(r->pixel_format);
3150 0 : vsub = drm_format_vert_chroma_subsampling(r->pixel_format);
3151 0 : num_planes = drm_format_num_planes(r->pixel_format);
3152 :
3153 0 : if (r->width == 0 || r->width % hsub) {
3154 : DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
3155 0 : return -EINVAL;
3156 : }
3157 :
3158 0 : if (r->height == 0 || r->height % vsub) {
3159 : DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
3160 0 : return -EINVAL;
3161 : }
3162 :
3163 0 : for (i = 0; i < num_planes; i++) {
3164 0 : unsigned int width = r->width / (i != 0 ? hsub : 1);
3165 0 : unsigned int height = r->height / (i != 0 ? vsub : 1);
3166 0 : unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);
3167 :
3168 0 : if (!r->handles[i]) {
3169 : DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
3170 0 : return -EINVAL;
3171 : }
3172 :
3173 0 : if ((uint64_t) width * cpp > UINT_MAX)
3174 0 : return -ERANGE;
3175 :
3176 0 : if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
3177 0 : return -ERANGE;
3178 :
3179 0 : if (r->pitches[i] < width * cpp) {
3180 : DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
3181 0 : return -EINVAL;
3182 : }
3183 :
3184 0 : if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) {
3185 : DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n",
3186 : r->modifier[i], i);
3187 0 : return -EINVAL;
3188 : }
3189 :
3190 : /* modifier specific checks: */
3191 0 : switch (r->modifier[i]) {
3192 : case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
3193 : /* NOTE: the pitch restriction may be lifted later if it turns
3194 : * out that no hw has this restriction:
3195 : */
3196 0 : if (r->pixel_format != DRM_FORMAT_NV12 ||
3197 0 : width % 128 || height % 32 ||
3198 0 : r->pitches[i] % 128) {
3199 : DRM_DEBUG_KMS("bad modifier data for plane %d\n", i);
3200 0 : return -EINVAL;
3201 : }
3202 : break;
3203 :
3204 : default:
3205 : break;
3206 : }
3207 0 : }
3208 :
3209 0 : for (i = num_planes; i < 4; i++) {
3210 0 : if (r->modifier[i]) {
3211 : DRM_DEBUG_KMS("non-zero modifier for unused plane %d\n", i);
3212 0 : return -EINVAL;
3213 : }
3214 :
3215 : /* Pre-FB_MODIFIERS userspace didn't clear the structs properly. */
3216 0 : if (!(r->flags & DRM_MODE_FB_MODIFIERS))
3217 : continue;
3218 :
3219 0 : if (r->handles[i]) {
3220 : DRM_DEBUG_KMS("buffer object handle for unused plane %d\n", i);
3221 0 : return -EINVAL;
3222 : }
3223 :
3224 0 : if (r->pitches[i]) {
3225 : DRM_DEBUG_KMS("non-zero pitch for unused plane %d\n", i);
3226 0 : return -EINVAL;
3227 : }
3228 :
3229 0 : if (r->offsets[i]) {
3230 : DRM_DEBUG_KMS("non-zero offset for unused plane %d\n", i);
3231 0 : return -EINVAL;
3232 : }
3233 : }
3234 :
3235 0 : return 0;
3236 0 : }
3237 :
3238 : static struct drm_framebuffer *
3239 0 : internal_framebuffer_create(struct drm_device *dev,
3240 : struct drm_mode_fb_cmd2 *r,
3241 : struct drm_file *file_priv)
3242 : {
3243 0 : struct drm_mode_config *config = &dev->mode_config;
3244 : struct drm_framebuffer *fb;
3245 : int ret;
3246 :
3247 0 : if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) {
3248 : DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
3249 0 : return ERR_PTR(-EINVAL);
3250 : }
3251 :
3252 0 : if ((config->min_width > r->width) || (r->width > config->max_width)) {
3253 : DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
3254 : r->width, config->min_width, config->max_width);
3255 0 : return ERR_PTR(-EINVAL);
3256 : }
3257 0 : if ((config->min_height > r->height) || (r->height > config->max_height)) {
3258 : DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
3259 : r->height, config->min_height, config->max_height);
3260 0 : return ERR_PTR(-EINVAL);
3261 : }
3262 :
3263 0 : if (r->flags & DRM_MODE_FB_MODIFIERS &&
3264 0 : !dev->mode_config.allow_fb_modifiers) {
3265 : DRM_DEBUG_KMS("driver does not support fb modifiers\n");
3266 0 : return ERR_PTR(-EINVAL);
3267 : }
3268 :
3269 0 : ret = framebuffer_check(r);
3270 0 : if (ret)
3271 0 : return ERR_PTR(ret);
3272 :
3273 0 : fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
3274 0 : if (IS_ERR(fb)) {
3275 : DRM_DEBUG_KMS("could not create framebuffer\n");
3276 0 : return fb;
3277 : }
3278 :
3279 : return fb;
3280 0 : }
3281 :
3282 : /**
3283 : * drm_mode_addfb2 - add an FB to the graphics configuration
3284 : * @dev: drm device for the ioctl
3285 : * @data: data pointer for the ioctl
3286 : * @file_priv: drm file for the ioctl call
3287 : *
3288 : * Add a new FB to the specified CRTC, given a user request with format. This is
3289 : * the 2nd version of the addfb ioctl, which supports multi-planar framebuffers
3290 : * and uses fourcc codes as pixel format specifiers.
3291 : *
3292 : * Called by the user via ioctl.
3293 : *
3294 : * Returns:
3295 : * Zero on success, negative errno on failure.
3296 : */
3297 0 : int drm_mode_addfb2(struct drm_device *dev,
3298 : void *data, struct drm_file *file_priv)
3299 : {
3300 0 : struct drm_mode_fb_cmd2 *r = data;
3301 : struct drm_framebuffer *fb;
3302 :
3303 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
3304 0 : return -EINVAL;
3305 :
3306 0 : fb = internal_framebuffer_create(dev, r, file_priv);
3307 0 : if (IS_ERR(fb))
3308 0 : return PTR_ERR(fb);
3309 :
3310 : /* Transfer ownership to the filp for reaping on close */
3311 :
3312 : DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
3313 0 : mutex_lock(&file_priv->fbs_lock);
3314 0 : r->fb_id = fb->base.id;
3315 0 : list_add(&fb->filp_head, &file_priv->fbs);
3316 0 : mutex_unlock(&file_priv->fbs_lock);
3317 :
3318 0 : return 0;
3319 0 : }
3320 :
3321 : struct drm_mode_rmfb_work {
3322 : struct work_struct work;
3323 : struct list_head fbs;
3324 : };
3325 :
3326 0 : static void drm_mode_rmfb_work_fn(struct work_struct *w)
3327 : {
3328 0 : struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
3329 :
3330 0 : while (!list_empty(&arg->fbs)) {
3331 : struct drm_framebuffer *fb =
3332 0 : list_first_entry(&arg->fbs, typeof(*fb), filp_head);
3333 :
3334 0 : list_del_init(&fb->filp_head);
3335 0 : drm_framebuffer_remove(fb);
3336 : }
3337 0 : }
3338 :
3339 : /**
3340 : * drm_mode_rmfb - remove an FB from the configuration
3341 : * @dev: drm device for the ioctl
3342 : * @data: data pointer for the ioctl
3343 : * @file_priv: drm file for the ioctl call
3344 : *
3345 : * Remove the FB specified by the user.
3346 : *
3347 : * Called by the user via ioctl.
3348 : *
3349 : * Returns:
3350 : * Zero on success, negative errno on failure.
3351 : */
3352 0 : int drm_mode_rmfb(struct drm_device *dev,
3353 : void *data, struct drm_file *file_priv)
3354 : {
3355 : struct drm_framebuffer *fb = NULL;
3356 : struct drm_framebuffer *fbl = NULL;
3357 0 : uint32_t *id = data;
3358 : int found = 0;
3359 :
3360 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
3361 0 : return -EINVAL;
3362 :
3363 0 : mutex_lock(&file_priv->fbs_lock);
3364 0 : mutex_lock(&dev->mode_config.fb_lock);
3365 0 : fb = __drm_framebuffer_lookup(dev, *id);
3366 0 : if (!fb)
3367 : goto fail_lookup;
3368 :
3369 0 : list_for_each_entry(fbl, &file_priv->fbs, filp_head)
3370 0 : if (fb == fbl)
3371 0 : found = 1;
3372 0 : if (!found)
3373 : goto fail_lookup;
3374 :
3375 0 : list_del_init(&fb->filp_head);
3376 0 : mutex_unlock(&dev->mode_config.fb_lock);
3377 0 : mutex_unlock(&file_priv->fbs_lock);
3378 :
3379 : /*
3380 : * we now own the reference that was stored in the fbs list
3381 : *
3382 : * drm_framebuffer_remove may fail with -EINTR on pending signals,
3383 : * so run this in a separate stack as there's no way to correctly
3384 : * handle this after the fb is already removed from the lookup table.
3385 : */
3386 0 : if (atomic_read(&fb->refcount.refcount) > 1) {
3387 0 : struct drm_mode_rmfb_work arg;
3388 :
3389 0 : INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
3390 0 : INIT_LIST_HEAD(&arg.fbs);
3391 0 : list_add_tail(&fb->filp_head, &arg.fbs);
3392 :
3393 0 : schedule_work(&arg.work);
3394 0 : flush_work(&arg.work);
3395 : destroy_work_on_stack(&arg.work);
3396 0 : } else
3397 0 : drm_framebuffer_unreference(fb);
3398 :
3399 0 : return 0;
3400 :
3401 : fail_lookup:
3402 0 : mutex_unlock(&dev->mode_config.fb_lock);
3403 0 : mutex_unlock(&file_priv->fbs_lock);
3404 :
3405 0 : return -ENOENT;
3406 0 : }
3407 :
3408 : /**
3409 : * drm_mode_getfb - get FB info
3410 : * @dev: drm device for the ioctl
3411 : * @data: data pointer for the ioctl
3412 : * @file_priv: drm file for the ioctl call
3413 : *
3414 : * Lookup the FB given its ID and return info about it.
3415 : *
3416 : * Called by the user via ioctl.
3417 : *
3418 : * Returns:
3419 : * Zero on success, negative errno on failure.
3420 : */
3421 0 : int drm_mode_getfb(struct drm_device *dev,
3422 : void *data, struct drm_file *file_priv)
3423 : {
3424 0 : struct drm_mode_fb_cmd *r = data;
3425 : struct drm_framebuffer *fb;
3426 : int ret;
3427 :
3428 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
3429 0 : return -EINVAL;
3430 :
3431 0 : fb = drm_framebuffer_lookup(dev, r->fb_id);
3432 0 : if (!fb)
3433 0 : return -ENOENT;
3434 :
3435 0 : r->height = fb->height;
3436 0 : r->width = fb->width;
3437 0 : r->depth = fb->depth;
3438 0 : r->bpp = fb->bits_per_pixel;
3439 0 : r->pitch = fb->pitches[0];
3440 0 : if (fb->funcs->create_handle) {
3441 0 : if (file_priv->is_master || capable(CAP_SYS_ADMIN) ||
3442 0 : drm_is_control_client(file_priv)) {
3443 0 : ret = fb->funcs->create_handle(fb, file_priv,
3444 0 : &r->handle);
3445 0 : } else {
3446 : /* GET_FB() is an unprivileged ioctl so we must not
3447 : * return a buffer-handle to non-master processes! For
3448 : * backwards-compatibility reasons, we cannot make
3449 : * GET_FB() privileged, so just return an invalid handle
3450 : * for non-masters. */
3451 0 : r->handle = 0;
3452 : ret = 0;
3453 : }
3454 : } else {
3455 : ret = -ENODEV;
3456 : }
3457 :
3458 0 : drm_framebuffer_unreference(fb);
3459 :
3460 0 : return ret;
3461 0 : }
3462 :
3463 : /**
3464 : * drm_mode_dirtyfb_ioctl - flush frontbuffer rendering on an FB
3465 : * @dev: drm device for the ioctl
3466 : * @data: data pointer for the ioctl
3467 : * @file_priv: drm file for the ioctl call
3468 : *
3469 : * Lookup the FB and flush out the damaged area supplied by userspace as a clip
3470 : * rectangle list. Generic userspace which does frontbuffer rendering must call
3471 : * this ioctl to flush out the changes on manual-update display outputs, e.g.
3472 : * usb display-link, mipi manual update panels or edp panel self refresh modes.
3473 : *
3474 : * Modesetting drivers which always update the frontbuffer do not need to
3475 : * implement the corresponding ->dirty framebuffer callback.
3476 : *
3477 : * Called by the user via ioctl.
3478 : *
3479 : * Returns:
3480 : * Zero on success, negative errno on failure.
3481 : */
3482 0 : int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
3483 : void *data, struct drm_file *file_priv)
3484 : {
3485 : struct drm_clip_rect __user *clips_ptr;
3486 : struct drm_clip_rect *clips = NULL;
3487 0 : struct drm_mode_fb_dirty_cmd *r = data;
3488 : struct drm_framebuffer *fb;
3489 : unsigned flags;
3490 : int num_clips;
3491 : int ret;
3492 :
3493 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
3494 0 : return -EINVAL;
3495 :
3496 0 : fb = drm_framebuffer_lookup(dev, r->fb_id);
3497 0 : if (!fb)
3498 0 : return -ENOENT;
3499 :
3500 0 : num_clips = r->num_clips;
3501 0 : clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
3502 :
3503 0 : if (!num_clips != !clips_ptr) {
3504 : ret = -EINVAL;
3505 0 : goto out_err1;
3506 : }
3507 :
3508 0 : flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
3509 :
3510 : /* If userspace annotates copy, clips must come in pairs */
3511 0 : if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
3512 : ret = -EINVAL;
3513 0 : goto out_err1;
3514 : }
3515 :
3516 0 : if (num_clips && clips_ptr) {
3517 0 : if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
3518 : ret = -EINVAL;
3519 0 : goto out_err1;
3520 : }
3521 0 : clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
3522 0 : if (!clips) {
3523 : ret = -ENOMEM;
3524 0 : goto out_err1;
3525 : }
3526 :
3527 0 : ret = copy_from_user(clips, clips_ptr,
3528 0 : num_clips * sizeof(*clips));
3529 0 : if (ret) {
3530 : ret = -EFAULT;
3531 0 : goto out_err2;
3532 : }
3533 : }
3534 :
3535 0 : if (fb->funcs->dirty) {
3536 0 : ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
3537 : clips, num_clips);
3538 0 : } else {
3539 : ret = -ENOSYS;
3540 : }
3541 :
3542 : out_err2:
3543 0 : kfree(clips);
3544 : out_err1:
3545 0 : drm_framebuffer_unreference(fb);
3546 :
3547 0 : return ret;
3548 0 : }
3549 :
3550 : /**
3551 : * drm_fb_release - remove and free the FBs on this file
3552 : * @priv: drm file for the ioctl
3553 : *
3554 : * Destroy all the FBs associated with @filp.
3555 : *
3556 : * Called by the user via ioctl.
3557 : *
3558 : * Returns:
3559 : * Zero on success, negative errno on failure.
3560 : */
3561 0 : void drm_fb_release(struct drm_file *priv)
3562 : {
3563 : struct drm_framebuffer *fb, *tfb;
3564 0 : struct drm_mode_rmfb_work arg;
3565 :
3566 0 : INIT_LIST_HEAD(&arg.fbs);
3567 :
3568 : /*
3569 : * When the file gets released that means no one else can access the fb
3570 : * list any more, so no need to grab fpriv->fbs_lock. And we need to
3571 : * avoid upsetting lockdep since the universal cursor code adds a
3572 : * framebuffer while holding mutex locks.
3573 : *
3574 : * Note that a real deadlock between fpriv->fbs_lock and the modeset
3575 : * locks is impossible here since no one else but this function can get
3576 : * at it any more.
3577 : */
3578 0 : list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
3579 0 : if (atomic_read(&fb->refcount.refcount) > 1) {
3580 0 : list_move_tail(&fb->filp_head, &arg.fbs);
3581 0 : } else {
3582 0 : list_del_init(&fb->filp_head);
3583 :
3584 : /* This drops the fpriv->fbs reference. */
3585 0 : drm_framebuffer_unreference(fb);
3586 : }
3587 : }
3588 :
3589 0 : if (!list_empty(&arg.fbs)) {
3590 0 : INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
3591 :
3592 0 : schedule_work(&arg.work);
3593 0 : flush_work(&arg.work);
3594 : destroy_work_on_stack(&arg.work);
3595 0 : }
3596 0 : }
3597 :
3598 : /**
3599 : * drm_property_create - create a new property type
3600 : * @dev: drm device
3601 : * @flags: flags specifying the property type
3602 : * @name: name of the property
3603 : * @num_values: number of pre-defined values
3604 : *
3605 : * This creates a new generic drm property which can then be attached to a drm
3606 : * object with drm_object_attach_property. The returned property object must be
3607 : * freed with drm_property_destroy.
3608 : *
3609 : * Note that the DRM core keeps a per-device list of properties and that, if
3610 : * drm_mode_config_cleanup() is called, it will destroy all properties created
3611 : * by the driver.
3612 : *
3613 : * Returns:
3614 : * A pointer to the newly created property on success, NULL on failure.
3615 : */
3616 0 : struct drm_property *drm_property_create(struct drm_device *dev, int flags,
3617 : const char *name, int num_values)
3618 : {
3619 : struct drm_property *property = NULL;
3620 : int ret;
3621 :
3622 0 : property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
3623 0 : if (!property)
3624 0 : return NULL;
3625 :
3626 0 : property->dev = dev;
3627 :
3628 0 : if (num_values) {
3629 0 : property->values = kcalloc(num_values, sizeof(uint64_t),
3630 : GFP_KERNEL);
3631 0 : if (!property->values)
3632 : goto fail;
3633 : }
3634 :
3635 0 : ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
3636 0 : if (ret)
3637 : goto fail;
3638 :
3639 0 : property->flags = flags;
3640 0 : property->num_values = num_values;
3641 0 : INIT_LIST_HEAD(&property->enum_list);
3642 :
3643 0 : if (name) {
3644 0 : strncpy(property->name, name, DRM_PROP_NAME_LEN);
3645 0 : property->name[DRM_PROP_NAME_LEN-1] = '\0';
3646 0 : }
3647 :
3648 0 : list_add_tail(&property->head, &dev->mode_config.property_list);
3649 :
3650 0 : WARN_ON(!drm_property_type_valid(property));
3651 :
3652 0 : return property;
3653 : fail:
3654 0 : kfree(property->values);
3655 0 : kfree(property);
3656 0 : return NULL;
3657 0 : }
3658 : EXPORT_SYMBOL(drm_property_create);
3659 :
3660 : /**
3661 : * drm_property_create_enum - create a new enumeration property type
3662 : * @dev: drm device
3663 : * @flags: flags specifying the property type
3664 : * @name: name of the property
3665 : * @props: enumeration lists with property values
3666 : * @num_values: number of pre-defined values
3667 : *
3668 : * This creates a new generic drm property which can then be attached to a drm
3669 : * object with drm_object_attach_property. The returned property object must be
3670 : * freed with drm_property_destroy.
3671 : *
3672 : * Userspace is only allowed to set one of the predefined values for enumeration
3673 : * properties.
3674 : *
3675 : * Returns:
3676 : * A pointer to the newly created property on success, NULL on failure.
3677 : */
3678 0 : struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
3679 : const char *name,
3680 : const struct drm_prop_enum_list *props,
3681 : int num_values)
3682 : {
3683 : struct drm_property *property;
3684 : int i, ret;
3685 :
3686 0 : flags |= DRM_MODE_PROP_ENUM;
3687 :
3688 0 : property = drm_property_create(dev, flags, name, num_values);
3689 0 : if (!property)
3690 0 : return NULL;
3691 :
3692 0 : for (i = 0; i < num_values; i++) {
3693 0 : ret = drm_property_add_enum(property, i,
3694 0 : props[i].type,
3695 0 : props[i].name);
3696 0 : if (ret) {
3697 0 : drm_property_destroy(dev, property);
3698 0 : return NULL;
3699 : }
3700 : }
3701 :
3702 0 : return property;
3703 0 : }
3704 : EXPORT_SYMBOL(drm_property_create_enum);
3705 :
3706 : /**
3707 : * drm_property_create_bitmask - create a new bitmask property type
3708 : * @dev: drm device
3709 : * @flags: flags specifying the property type
3710 : * @name: name of the property
3711 : * @props: enumeration lists with property bitflags
3712 : * @num_props: size of the @props array
3713 : * @supported_bits: bitmask of all supported enumeration values
3714 : *
3715 : * This creates a new bitmask drm property which can then be attached to a drm
3716 : * object with drm_object_attach_property. The returned property object must be
3717 : * freed with drm_property_destroy.
3718 : *
3719 : * Compared to plain enumeration properties userspace is allowed to set any
3720 : * or'ed together combination of the predefined property bitflag values
3721 : *
3722 : * Returns:
3723 : * A pointer to the newly created property on success, NULL on failure.
3724 : */
3725 0 : struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
3726 : int flags, const char *name,
3727 : const struct drm_prop_enum_list *props,
3728 : int num_props,
3729 : uint64_t supported_bits)
3730 : {
3731 : struct drm_property *property;
3732 : int i, ret, index = 0;
3733 0 : int num_values = hweight64(supported_bits);
3734 :
3735 0 : flags |= DRM_MODE_PROP_BITMASK;
3736 :
3737 0 : property = drm_property_create(dev, flags, name, num_values);
3738 0 : if (!property)
3739 0 : return NULL;
3740 0 : for (i = 0; i < num_props; i++) {
3741 0 : if (!(supported_bits & (1ULL << props[i].type)))
3742 : continue;
3743 :
3744 0 : if (WARN_ON(index >= num_values)) {
3745 0 : drm_property_destroy(dev, property);
3746 0 : return NULL;
3747 : }
3748 :
3749 0 : ret = drm_property_add_enum(property, index++,
3750 0 : props[i].type,
3751 0 : props[i].name);
3752 0 : if (ret) {
3753 0 : drm_property_destroy(dev, property);
3754 0 : return NULL;
3755 : }
3756 : }
3757 :
3758 0 : return property;
3759 0 : }
3760 : EXPORT_SYMBOL(drm_property_create_bitmask);
3761 :
3762 0 : static struct drm_property *property_create_range(struct drm_device *dev,
3763 : int flags, const char *name,
3764 : uint64_t min, uint64_t max)
3765 : {
3766 : struct drm_property *property;
3767 :
3768 0 : property = drm_property_create(dev, flags, name, 2);
3769 0 : if (!property)
3770 0 : return NULL;
3771 :
3772 0 : property->values[0] = min;
3773 0 : property->values[1] = max;
3774 :
3775 0 : return property;
3776 0 : }
3777 :
3778 : /**
3779 : * drm_property_create_range - create a new unsigned ranged property type
3780 : * @dev: drm device
3781 : * @flags: flags specifying the property type
3782 : * @name: name of the property
3783 : * @min: minimum value of the property
3784 : * @max: maximum value of the property
3785 : *
3786 : * This creates a new generic drm property which can then be attached to a drm
3787 : * object with drm_object_attach_property. The returned property object must be
3788 : * freed with drm_property_destroy.
3789 : *
3790 : * Userspace is allowed to set any unsigned integer value in the (min, max)
3791 : * range inclusive.
3792 : *
3793 : * Returns:
3794 : * A pointer to the newly created property on success, NULL on failure.
3795 : */
3796 0 : struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
3797 : const char *name,
3798 : uint64_t min, uint64_t max)
3799 : {
3800 0 : return property_create_range(dev, DRM_MODE_PROP_RANGE | flags,
3801 : name, min, max);
3802 : }
3803 : EXPORT_SYMBOL(drm_property_create_range);
3804 :
3805 : /**
3806 : * drm_property_create_signed_range - create a new signed ranged property type
3807 : * @dev: drm device
3808 : * @flags: flags specifying the property type
3809 : * @name: name of the property
3810 : * @min: minimum value of the property
3811 : * @max: maximum value of the property
3812 : *
3813 : * This creates a new generic drm property which can then be attached to a drm
3814 : * object with drm_object_attach_property. The returned property object must be
3815 : * freed with drm_property_destroy.
3816 : *
3817 : * Userspace is allowed to set any signed integer value in the (min, max)
3818 : * range inclusive.
3819 : *
3820 : * Returns:
3821 : * A pointer to the newly created property on success, NULL on failure.
3822 : */
3823 0 : struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
3824 : int flags, const char *name,
3825 : int64_t min, int64_t max)
3826 : {
3827 0 : return property_create_range(dev, DRM_MODE_PROP_SIGNED_RANGE | flags,
3828 0 : name, I642U64(min), I642U64(max));
3829 : }
3830 : EXPORT_SYMBOL(drm_property_create_signed_range);
3831 :
3832 : /**
3833 : * drm_property_create_object - create a new object property type
3834 : * @dev: drm device
3835 : * @flags: flags specifying the property type
3836 : * @name: name of the property
3837 : * @type: object type from DRM_MODE_OBJECT_* defines
3838 : *
3839 : * This creates a new generic drm property which can then be attached to a drm
3840 : * object with drm_object_attach_property. The returned property object must be
3841 : * freed with drm_property_destroy.
3842 : *
3843 : * Userspace is only allowed to set this to any property value of the given
3844 : * @type. Only useful for atomic properties, which is enforced.
3845 : *
3846 : * Returns:
3847 : * A pointer to the newly created property on success, NULL on failure.
3848 : */
3849 0 : struct drm_property *drm_property_create_object(struct drm_device *dev,
3850 : int flags, const char *name, uint32_t type)
3851 : {
3852 : struct drm_property *property;
3853 :
3854 0 : flags |= DRM_MODE_PROP_OBJECT;
3855 :
3856 0 : if (WARN_ON(!(flags & DRM_MODE_PROP_ATOMIC)))
3857 0 : return NULL;
3858 :
3859 0 : property = drm_property_create(dev, flags, name, 1);
3860 0 : if (!property)
3861 0 : return NULL;
3862 :
3863 0 : property->values[0] = type;
3864 :
3865 0 : return property;
3866 0 : }
3867 : EXPORT_SYMBOL(drm_property_create_object);
3868 :
3869 : /**
3870 : * drm_property_create_bool - create a new boolean property type
3871 : * @dev: drm device
3872 : * @flags: flags specifying the property type
3873 : * @name: name of the property
3874 : *
3875 : * This creates a new generic drm property which can then be attached to a drm
3876 : * object with drm_object_attach_property. The returned property object must be
3877 : * freed with drm_property_destroy.
3878 : *
3879 : * This is implemented as a ranged property with only {0, 1} as valid values.
3880 : *
3881 : * Returns:
3882 : * A pointer to the newly created property on success, NULL on failure.
3883 : */
3884 0 : struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
3885 : const char *name)
3886 : {
3887 0 : return drm_property_create_range(dev, flags, name, 0, 1);
3888 : }
3889 : EXPORT_SYMBOL(drm_property_create_bool);
3890 :
3891 : /**
3892 : * drm_property_add_enum - add a possible value to an enumeration property
3893 : * @property: enumeration property to change
3894 : * @index: index of the new enumeration
3895 : * @value: value of the new enumeration
3896 : * @name: symbolic name of the new enumeration
3897 : *
3898 : * This functions adds enumerations to a property.
3899 : *
3900 : * It's use is deprecated, drivers should use one of the more specific helpers
3901 : * to directly create the property with all enumerations already attached.
3902 : *
3903 : * Returns:
3904 : * Zero on success, error code on failure.
3905 : */
3906 0 : int drm_property_add_enum(struct drm_property *property, int index,
3907 : uint64_t value, const char *name)
3908 : {
3909 : struct drm_property_enum *prop_enum;
3910 :
3911 0 : if (!(drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3912 0 : drm_property_type_is(property, DRM_MODE_PROP_BITMASK)))
3913 0 : return -EINVAL;
3914 :
3915 : /*
3916 : * Bitmask enum properties have the additional constraint of values
3917 : * from 0 to 63
3918 : */
3919 0 : if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK) &&
3920 0 : (value > 63))
3921 0 : return -EINVAL;
3922 :
3923 0 : if (!list_empty(&property->enum_list)) {
3924 0 : list_for_each_entry(prop_enum, &property->enum_list, head) {
3925 0 : if (prop_enum->value == value) {
3926 0 : strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
3927 0 : prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
3928 0 : return 0;
3929 : }
3930 : }
3931 : }
3932 :
3933 0 : prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
3934 0 : if (!prop_enum)
3935 0 : return -ENOMEM;
3936 :
3937 0 : strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
3938 0 : prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
3939 0 : prop_enum->value = value;
3940 :
3941 0 : property->values[index] = value;
3942 0 : list_add_tail(&prop_enum->head, &property->enum_list);
3943 0 : return 0;
3944 0 : }
3945 : EXPORT_SYMBOL(drm_property_add_enum);
3946 :
3947 : /**
3948 : * drm_property_destroy - destroy a drm property
3949 : * @dev: drm device
3950 : * @property: property to destry
3951 : *
3952 : * This function frees a property including any attached resources like
3953 : * enumeration values.
3954 : */
3955 0 : void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
3956 : {
3957 : struct drm_property_enum *prop_enum, *pt;
3958 :
3959 0 : list_for_each_entry_safe(prop_enum, pt, &property->enum_list, head) {
3960 0 : list_del(&prop_enum->head);
3961 0 : kfree(prop_enum);
3962 : }
3963 :
3964 0 : if (property->num_values)
3965 0 : kfree(property->values);
3966 0 : drm_mode_object_put(dev, &property->base);
3967 0 : list_del(&property->head);
3968 0 : kfree(property);
3969 0 : }
3970 : EXPORT_SYMBOL(drm_property_destroy);
3971 :
3972 : /**
3973 : * drm_object_attach_property - attach a property to a modeset object
3974 : * @obj: drm modeset object
3975 : * @property: property to attach
3976 : * @init_val: initial value of the property
3977 : *
3978 : * This attaches the given property to the modeset object with the given initial
3979 : * value. Currently this function cannot fail since the properties are stored in
3980 : * a statically sized array.
3981 : */
3982 0 : void drm_object_attach_property(struct drm_mode_object *obj,
3983 : struct drm_property *property,
3984 : uint64_t init_val)
3985 : {
3986 0 : int count = obj->properties->count;
3987 :
3988 0 : if (count == DRM_OBJECT_MAX_PROPERTY) {
3989 0 : WARN(1, "Failed to attach object property (type: 0x%x). Please "
3990 : "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
3991 : "you see this message on the same object type.\n",
3992 : obj->type);
3993 0 : return;
3994 : }
3995 :
3996 0 : obj->properties->properties[count] = property;
3997 0 : obj->properties->values[count] = init_val;
3998 0 : obj->properties->count++;
3999 0 : if (property->flags & DRM_MODE_PROP_ATOMIC)
4000 0 : obj->properties->atomic_count++;
4001 0 : }
4002 : EXPORT_SYMBOL(drm_object_attach_property);
4003 :
4004 : /**
4005 : * drm_object_property_set_value - set the value of a property
4006 : * @obj: drm mode object to set property value for
4007 : * @property: property to set
4008 : * @val: value the property should be set to
4009 : *
4010 : * This functions sets a given property on a given object. This function only
4011 : * changes the software state of the property, it does not call into the
4012 : * driver's ->set_property callback.
4013 : *
4014 : * Returns:
4015 : * Zero on success, error code on failure.
4016 : */
4017 0 : int drm_object_property_set_value(struct drm_mode_object *obj,
4018 : struct drm_property *property, uint64_t val)
4019 : {
4020 : int i;
4021 :
4022 0 : for (i = 0; i < obj->properties->count; i++) {
4023 0 : if (obj->properties->properties[i] == property) {
4024 0 : obj->properties->values[i] = val;
4025 0 : return 0;
4026 : }
4027 : }
4028 :
4029 0 : return -EINVAL;
4030 0 : }
4031 : EXPORT_SYMBOL(drm_object_property_set_value);
4032 :
4033 : /**
4034 : * drm_object_property_get_value - retrieve the value of a property
4035 : * @obj: drm mode object to get property value from
4036 : * @property: property to retrieve
4037 : * @val: storage for the property value
4038 : *
4039 : * This function retrieves the softare state of the given property for the given
4040 : * property. Since there is no driver callback to retrieve the current property
4041 : * value this might be out of sync with the hardware, depending upon the driver
4042 : * and property.
4043 : *
4044 : * Returns:
4045 : * Zero on success, error code on failure.
4046 : */
4047 0 : int drm_object_property_get_value(struct drm_mode_object *obj,
4048 : struct drm_property *property, uint64_t *val)
4049 : {
4050 : int i;
4051 :
4052 : #ifdef __OpenBSD__
4053 0 : if (obj->type == DRM_MODE_OBJECT_CONNECTOR) {
4054 0 : struct drm_connector *connector = obj_to_connector(obj);
4055 :
4056 0 : if (property == connector->backlight_property) {
4057 : struct backlight_device *bd =
4058 0 : connector->backlight_device;
4059 :
4060 0 : if (bd->props.type == BACKLIGHT_FIRMWARE)
4061 0 : *val = bd->ops->get_brightness(bd);
4062 : else
4063 0 : *val = bd->props.brightness;
4064 : return 0;
4065 : }
4066 0 : }
4067 : #endif
4068 :
4069 : /* read-only properties bypass atomic mechanism and still store
4070 : * their value in obj->properties->values[].. mostly to avoid
4071 : * having to deal w/ EDID and similar props in atomic paths:
4072 : */
4073 0 : if (drm_core_check_feature(property->dev, DRIVER_ATOMIC) &&
4074 0 : !(property->flags & DRM_MODE_PROP_IMMUTABLE))
4075 0 : return drm_atomic_get_property(obj, property, val);
4076 :
4077 0 : for (i = 0; i < obj->properties->count; i++) {
4078 0 : if (obj->properties->properties[i] == property) {
4079 0 : *val = obj->properties->values[i];
4080 0 : return 0;
4081 : }
4082 : }
4083 :
4084 0 : return -EINVAL;
4085 0 : }
4086 : EXPORT_SYMBOL(drm_object_property_get_value);
4087 :
4088 : /**
4089 : * drm_mode_getproperty_ioctl - get the property metadata
4090 : * @dev: DRM device
4091 : * @data: ioctl data
4092 : * @file_priv: DRM file info
4093 : *
4094 : * This function retrieves the metadata for a given property, like the different
4095 : * possible values for an enum property or the limits for a range property.
4096 : *
4097 : * Blob properties are special
4098 : *
4099 : * Called by the user via ioctl.
4100 : *
4101 : * Returns:
4102 : * Zero on success, negative errno on failure.
4103 : */
4104 0 : int drm_mode_getproperty_ioctl(struct drm_device *dev,
4105 : void *data, struct drm_file *file_priv)
4106 : {
4107 0 : struct drm_mode_get_property *out_resp = data;
4108 : struct drm_property *property;
4109 : int enum_count = 0;
4110 : int value_count = 0;
4111 : int ret = 0, i;
4112 : int copied;
4113 : struct drm_property_enum *prop_enum;
4114 : struct drm_mode_property_enum __user *enum_ptr;
4115 : uint64_t __user *values_ptr;
4116 :
4117 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
4118 0 : return -EINVAL;
4119 :
4120 0 : drm_modeset_lock_all(dev);
4121 0 : property = drm_property_find(dev, out_resp->prop_id);
4122 0 : if (!property) {
4123 : ret = -ENOENT;
4124 0 : goto done;
4125 : }
4126 :
4127 0 : if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
4128 0 : drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
4129 0 : list_for_each_entry(prop_enum, &property->enum_list, head)
4130 0 : enum_count++;
4131 : }
4132 :
4133 0 : value_count = property->num_values;
4134 :
4135 0 : strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
4136 0 : out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
4137 0 : out_resp->flags = property->flags;
4138 :
4139 0 : if ((out_resp->count_values >= value_count) && value_count) {
4140 0 : values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr;
4141 0 : for (i = 0; i < value_count; i++) {
4142 0 : if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
4143 : ret = -EFAULT;
4144 0 : goto done;
4145 : }
4146 : }
4147 : }
4148 0 : out_resp->count_values = value_count;
4149 :
4150 0 : if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
4151 0 : drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
4152 0 : if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
4153 : copied = 0;
4154 0 : enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
4155 0 : list_for_each_entry(prop_enum, &property->enum_list, head) {
4156 :
4157 0 : if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
4158 : ret = -EFAULT;
4159 0 : goto done;
4160 : }
4161 :
4162 0 : if (copy_to_user(&enum_ptr[copied].name,
4163 0 : &prop_enum->name, DRM_PROP_NAME_LEN)) {
4164 : ret = -EFAULT;
4165 0 : goto done;
4166 : }
4167 0 : copied++;
4168 : }
4169 : }
4170 0 : out_resp->count_enum_blobs = enum_count;
4171 0 : }
4172 :
4173 : /*
4174 : * NOTE: The idea seems to have been to use this to read all the blob
4175 : * property values. But nothing ever added them to the corresponding
4176 : * list, userspace always used the special-purpose get_blob ioctl to
4177 : * read the value for a blob property. It also doesn't make a lot of
4178 : * sense to return values here when everything else is just metadata for
4179 : * the property itself.
4180 : */
4181 0 : if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
4182 0 : out_resp->count_enum_blobs = 0;
4183 : done:
4184 0 : drm_modeset_unlock_all(dev);
4185 0 : return ret;
4186 0 : }
4187 :
4188 : /**
4189 : * drm_property_create_blob - Create new blob property
4190 : *
4191 : * Creates a new blob property for a specified DRM device, optionally
4192 : * copying data.
4193 : *
4194 : * @dev: DRM device to create property for
4195 : * @length: Length to allocate for blob data
4196 : * @data: If specified, copies data into blob
4197 : *
4198 : * Returns:
4199 : * New blob property with a single reference on success, or an ERR_PTR
4200 : * value on failure.
4201 : */
4202 : struct drm_property_blob *
4203 0 : drm_property_create_blob(struct drm_device *dev, size_t length,
4204 : const void *data)
4205 : {
4206 : struct drm_property_blob *blob;
4207 : int ret;
4208 :
4209 0 : if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
4210 0 : return ERR_PTR(-EINVAL);
4211 :
4212 0 : blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
4213 0 : if (!blob)
4214 0 : return ERR_PTR(-ENOMEM);
4215 :
4216 : /* This must be explicitly initialised, so we can safely call list_del
4217 : * on it in the removal handler, even if it isn't in a file list. */
4218 0 : INIT_LIST_HEAD(&blob->head_file);
4219 0 : blob->length = length;
4220 0 : blob->dev = dev;
4221 :
4222 0 : if (data)
4223 0 : memcpy(blob->data, data, length);
4224 :
4225 0 : mutex_lock(&dev->mode_config.blob_lock);
4226 :
4227 0 : ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
4228 0 : if (ret) {
4229 0 : kfree(blob);
4230 0 : mutex_unlock(&dev->mode_config.blob_lock);
4231 0 : return ERR_PTR(-EINVAL);
4232 : }
4233 :
4234 0 : kref_init(&blob->refcount);
4235 :
4236 0 : list_add_tail(&blob->head_global,
4237 0 : &dev->mode_config.property_blob_list);
4238 :
4239 0 : mutex_unlock(&dev->mode_config.blob_lock);
4240 :
4241 0 : return blob;
4242 0 : }
4243 : EXPORT_SYMBOL(drm_property_create_blob);
4244 :
4245 : /**
4246 : * drm_property_free_blob - Blob property destructor
4247 : *
4248 : * Internal free function for blob properties; must not be used directly.
4249 : *
4250 : * @kref: Reference
4251 : */
4252 0 : static void drm_property_free_blob(struct kref *kref)
4253 : {
4254 : struct drm_property_blob *blob =
4255 0 : container_of(kref, struct drm_property_blob, refcount);
4256 :
4257 0 : WARN_ON(!mutex_is_locked(&blob->dev->mode_config.blob_lock));
4258 :
4259 0 : list_del(&blob->head_global);
4260 0 : list_del(&blob->head_file);
4261 0 : drm_mode_object_put(blob->dev, &blob->base);
4262 :
4263 0 : kfree(blob);
4264 0 : }
4265 :
4266 : /**
4267 : * drm_property_unreference_blob - Unreference a blob property
4268 : *
4269 : * Drop a reference on a blob property. May free the object.
4270 : *
4271 : * @blob: Pointer to blob property
4272 : */
4273 0 : void drm_property_unreference_blob(struct drm_property_blob *blob)
4274 : {
4275 : struct drm_device *dev;
4276 :
4277 0 : if (!blob)
4278 0 : return;
4279 :
4280 0 : dev = blob->dev;
4281 :
4282 : DRM_DEBUG("%p: blob ID: %d (%d)\n", blob, blob->base.id, atomic_read(&blob->refcount.refcount));
4283 :
4284 0 : if (kref_put_mutex(&blob->refcount, drm_property_free_blob,
4285 0 : &dev->mode_config.blob_lock))
4286 0 : mutex_unlock(&dev->mode_config.blob_lock);
4287 : else
4288 : might_lock(&dev->mode_config.blob_lock);
4289 0 : }
4290 : EXPORT_SYMBOL(drm_property_unreference_blob);
4291 :
4292 : /**
4293 : * drm_property_unreference_blob_locked - Unreference a blob property with blob_lock held
4294 : *
4295 : * Drop a reference on a blob property. May free the object. This must be
4296 : * called with blob_lock held.
4297 : *
4298 : * @blob: Pointer to blob property
4299 : */
4300 0 : static void drm_property_unreference_blob_locked(struct drm_property_blob *blob)
4301 : {
4302 0 : if (!blob)
4303 : return;
4304 :
4305 : DRM_DEBUG("%p: blob ID: %d (%d)\n", blob, blob->base.id, atomic_read(&blob->refcount.refcount));
4306 :
4307 0 : kref_put(&blob->refcount, drm_property_free_blob);
4308 0 : }
4309 :
4310 : /**
4311 : * drm_property_destroy_user_blobs - destroy all blobs created by this client
4312 : * @dev: DRM device
4313 : * @file_priv: destroy all blobs owned by this file handle
4314 : */
4315 0 : void drm_property_destroy_user_blobs(struct drm_device *dev,
4316 : struct drm_file *file_priv)
4317 : {
4318 : struct drm_property_blob *blob, *bt;
4319 :
4320 0 : mutex_lock(&dev->mode_config.blob_lock);
4321 :
4322 0 : list_for_each_entry_safe(blob, bt, &file_priv->blobs, head_file) {
4323 0 : list_del_init(&blob->head_file);
4324 0 : drm_property_unreference_blob_locked(blob);
4325 : }
4326 :
4327 0 : mutex_unlock(&dev->mode_config.blob_lock);
4328 0 : }
4329 :
4330 : /**
4331 : * drm_property_reference_blob - Take a reference on an existing property
4332 : *
4333 : * Take a new reference on an existing blob property.
4334 : *
4335 : * @blob: Pointer to blob property
4336 : */
4337 0 : struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob)
4338 : {
4339 : DRM_DEBUG("%p: blob ID: %d (%d)\n", blob, blob->base.id, atomic_read(&blob->refcount.refcount));
4340 0 : kref_get(&blob->refcount);
4341 0 : return blob;
4342 : }
4343 : EXPORT_SYMBOL(drm_property_reference_blob);
4344 :
4345 : /*
4346 : * Like drm_property_lookup_blob, but does not return an additional reference.
4347 : * Must be called with blob_lock held.
4348 : */
4349 0 : static struct drm_property_blob *__drm_property_lookup_blob(struct drm_device *dev,
4350 : uint32_t id)
4351 : {
4352 : struct drm_mode_object *obj = NULL;
4353 : struct drm_property_blob *blob;
4354 :
4355 0 : WARN_ON(!mutex_is_locked(&dev->mode_config.blob_lock));
4356 :
4357 0 : mutex_lock(&dev->mode_config.idr_mutex);
4358 0 : obj = idr_find(&dev->mode_config.crtc_idr, id);
4359 0 : if (!obj || (obj->type != DRM_MODE_OBJECT_BLOB) || (obj->id != id))
4360 0 : blob = NULL;
4361 : else
4362 0 : blob = obj_to_blob(obj);
4363 0 : mutex_unlock(&dev->mode_config.idr_mutex);
4364 :
4365 0 : return blob;
4366 : }
4367 :
4368 : /**
4369 : * drm_property_lookup_blob - look up a blob property and take a reference
4370 : * @dev: drm device
4371 : * @id: id of the blob property
4372 : *
4373 : * If successful, this takes an additional reference to the blob property.
4374 : * callers need to make sure to eventually unreference the returned property
4375 : * again, using @drm_property_unreference_blob.
4376 : */
4377 0 : struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
4378 : uint32_t id)
4379 : {
4380 : struct drm_property_blob *blob;
4381 :
4382 0 : mutex_lock(&dev->mode_config.blob_lock);
4383 0 : blob = __drm_property_lookup_blob(dev, id);
4384 0 : if (blob) {
4385 0 : if (!kref_get_unless_zero(&blob->refcount))
4386 0 : blob = NULL;
4387 : }
4388 0 : mutex_unlock(&dev->mode_config.blob_lock);
4389 :
4390 0 : return blob;
4391 : }
4392 : EXPORT_SYMBOL(drm_property_lookup_blob);
4393 :
4394 : /**
4395 : * drm_property_replace_global_blob - atomically replace existing blob property
4396 : * @dev: drm device
4397 : * @replace: location of blob property pointer to be replaced
4398 : * @length: length of data for new blob, or 0 for no data
4399 : * @data: content for new blob, or NULL for no data
4400 : * @obj_holds_id: optional object for property holding blob ID
4401 : * @prop_holds_id: optional property holding blob ID
4402 : * @return 0 on success or error on failure
4403 : *
4404 : * This function will atomically replace a global property in the blob list,
4405 : * optionally updating a property which holds the ID of that property. It is
4406 : * guaranteed to be atomic: no caller will be allowed to see intermediate
4407 : * results, and either the entire operation will succeed and clean up the
4408 : * previous property, or it will fail and the state will be unchanged.
4409 : *
4410 : * If length is 0 or data is NULL, no new blob will be created, and the holding
4411 : * property, if specified, will be set to 0.
4412 : *
4413 : * Access to the replace pointer is assumed to be protected by the caller, e.g.
4414 : * by holding the relevant modesetting object lock for its parent.
4415 : *
4416 : * For example, a drm_connector has a 'PATH' property, which contains the ID
4417 : * of a blob property with the value of the MST path information. Calling this
4418 : * function with replace pointing to the connector's path_blob_ptr, length and
4419 : * data set for the new path information, obj_holds_id set to the connector's
4420 : * base object, and prop_holds_id set to the path property name, will perform
4421 : * a completely atomic update. The access to path_blob_ptr is protected by the
4422 : * caller holding a lock on the connector.
4423 : */
4424 0 : static int drm_property_replace_global_blob(struct drm_device *dev,
4425 : struct drm_property_blob **replace,
4426 : size_t length,
4427 : const void *data,
4428 : struct drm_mode_object *obj_holds_id,
4429 : struct drm_property *prop_holds_id)
4430 : {
4431 : struct drm_property_blob *new_blob = NULL;
4432 : struct drm_property_blob *old_blob = NULL;
4433 : int ret;
4434 :
4435 0 : WARN_ON(replace == NULL);
4436 :
4437 0 : old_blob = *replace;
4438 :
4439 0 : if (length && data) {
4440 0 : new_blob = drm_property_create_blob(dev, length, data);
4441 0 : if (IS_ERR(new_blob))
4442 0 : return PTR_ERR(new_blob);
4443 : }
4444 :
4445 : /* This does not need to be synchronised with blob_lock, as the
4446 : * get_properties ioctl locks all modesetting objects, and
4447 : * obj_holds_id must be locked before calling here, so we cannot
4448 : * have its value out of sync with the list membership modified
4449 : * below under blob_lock. */
4450 0 : if (obj_holds_id) {
4451 0 : ret = drm_object_property_set_value(obj_holds_id,
4452 : prop_holds_id,
4453 0 : new_blob ?
4454 0 : new_blob->base.id : 0);
4455 0 : if (ret != 0)
4456 : goto err_created;
4457 : }
4458 :
4459 0 : drm_property_unreference_blob(old_blob);
4460 0 : *replace = new_blob;
4461 :
4462 0 : return 0;
4463 :
4464 : err_created:
4465 0 : drm_property_unreference_blob(new_blob);
4466 0 : return ret;
4467 0 : }
4468 :
4469 : /**
4470 : * drm_mode_getblob_ioctl - get the contents of a blob property value
4471 : * @dev: DRM device
4472 : * @data: ioctl data
4473 : * @file_priv: DRM file info
4474 : *
4475 : * This function retrieves the contents of a blob property. The value stored in
4476 : * an object's blob property is just a normal modeset object id.
4477 : *
4478 : * Called by the user via ioctl.
4479 : *
4480 : * Returns:
4481 : * Zero on success, negative errno on failure.
4482 : */
4483 0 : int drm_mode_getblob_ioctl(struct drm_device *dev,
4484 : void *data, struct drm_file *file_priv)
4485 : {
4486 0 : struct drm_mode_get_blob *out_resp = data;
4487 : struct drm_property_blob *blob;
4488 : int ret = 0;
4489 : void __user *blob_ptr;
4490 :
4491 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
4492 0 : return -EINVAL;
4493 :
4494 0 : drm_modeset_lock_all(dev);
4495 0 : mutex_lock(&dev->mode_config.blob_lock);
4496 0 : blob = __drm_property_lookup_blob(dev, out_resp->blob_id);
4497 0 : if (!blob) {
4498 : ret = -ENOENT;
4499 0 : goto done;
4500 : }
4501 :
4502 0 : if (out_resp->length == blob->length) {
4503 0 : blob_ptr = (void __user *)(unsigned long)out_resp->data;
4504 0 : if (copy_to_user(blob_ptr, blob->data, blob->length)) {
4505 : ret = -EFAULT;
4506 0 : goto done;
4507 : }
4508 : }
4509 0 : out_resp->length = blob->length;
4510 :
4511 : done:
4512 0 : mutex_unlock(&dev->mode_config.blob_lock);
4513 0 : drm_modeset_unlock_all(dev);
4514 0 : return ret;
4515 0 : }
4516 :
4517 : /**
4518 : * drm_mode_createblob_ioctl - create a new blob property
4519 : * @dev: DRM device
4520 : * @data: ioctl data
4521 : * @file_priv: DRM file info
4522 : *
4523 : * This function creates a new blob property with user-defined values. In order
4524 : * to give us sensible validation and checking when creating, rather than at
4525 : * every potential use, we also require a type to be provided upfront.
4526 : *
4527 : * Called by the user via ioctl.
4528 : *
4529 : * Returns:
4530 : * Zero on success, negative errno on failure.
4531 : */
4532 0 : int drm_mode_createblob_ioctl(struct drm_device *dev,
4533 : void *data, struct drm_file *file_priv)
4534 : {
4535 0 : struct drm_mode_create_blob *out_resp = data;
4536 : struct drm_property_blob *blob;
4537 : void __user *blob_ptr;
4538 : int ret = 0;
4539 :
4540 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
4541 0 : return -EINVAL;
4542 :
4543 0 : blob = drm_property_create_blob(dev, out_resp->length, NULL);
4544 0 : if (IS_ERR(blob))
4545 0 : return PTR_ERR(blob);
4546 :
4547 0 : blob_ptr = (void __user *)(unsigned long)out_resp->data;
4548 0 : if (copy_from_user(blob->data, blob_ptr, out_resp->length)) {
4549 : ret = -EFAULT;
4550 : goto out_blob;
4551 : }
4552 :
4553 : /* Dropping the lock between create_blob and our access here is safe
4554 : * as only the same file_priv can remove the blob; at this point, it is
4555 : * not associated with any file_priv. */
4556 0 : mutex_lock(&dev->mode_config.blob_lock);
4557 0 : out_resp->blob_id = blob->base.id;
4558 0 : list_add_tail(&blob->head_file, &file_priv->blobs);
4559 0 : mutex_unlock(&dev->mode_config.blob_lock);
4560 :
4561 0 : return 0;
4562 :
4563 : out_blob:
4564 0 : drm_property_unreference_blob(blob);
4565 0 : return ret;
4566 0 : }
4567 :
4568 : /**
4569 : * drm_mode_destroyblob_ioctl - destroy a user blob property
4570 : * @dev: DRM device
4571 : * @data: ioctl data
4572 : * @file_priv: DRM file info
4573 : *
4574 : * Destroy an existing user-defined blob property.
4575 : *
4576 : * Called by the user via ioctl.
4577 : *
4578 : * Returns:
4579 : * Zero on success, negative errno on failure.
4580 : */
4581 0 : int drm_mode_destroyblob_ioctl(struct drm_device *dev,
4582 : void *data, struct drm_file *file_priv)
4583 : {
4584 0 : struct drm_mode_destroy_blob *out_resp = data;
4585 : struct drm_property_blob *blob = NULL, *bt;
4586 : bool found = false;
4587 : int ret = 0;
4588 :
4589 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
4590 0 : return -EINVAL;
4591 :
4592 0 : mutex_lock(&dev->mode_config.blob_lock);
4593 0 : blob = __drm_property_lookup_blob(dev, out_resp->blob_id);
4594 0 : if (!blob) {
4595 : ret = -ENOENT;
4596 0 : goto err;
4597 : }
4598 :
4599 : /* Ensure the property was actually created by this user. */
4600 0 : list_for_each_entry(bt, &file_priv->blobs, head_file) {
4601 0 : if (bt == blob) {
4602 : found = true;
4603 0 : break;
4604 : }
4605 : }
4606 :
4607 0 : if (!found) {
4608 : ret = -EPERM;
4609 0 : goto err;
4610 : }
4611 :
4612 : /* We must drop head_file here, because we may not be the last
4613 : * reference on the blob. */
4614 0 : list_del_init(&blob->head_file);
4615 0 : drm_property_unreference_blob_locked(blob);
4616 0 : mutex_unlock(&dev->mode_config.blob_lock);
4617 :
4618 0 : return 0;
4619 :
4620 : err:
4621 0 : mutex_unlock(&dev->mode_config.blob_lock);
4622 0 : return ret;
4623 0 : }
4624 :
4625 : /**
4626 : * drm_mode_connector_set_path_property - set tile property on connector
4627 : * @connector: connector to set property on.
4628 : * @path: path to use for property; must not be NULL.
4629 : *
4630 : * This creates a property to expose to userspace to specify a
4631 : * connector path. This is mainly used for DisplayPort MST where
4632 : * connectors have a topology and we want to allow userspace to give
4633 : * them more meaningful names.
4634 : *
4635 : * Returns:
4636 : * Zero on success, negative errno on failure.
4637 : */
4638 0 : int drm_mode_connector_set_path_property(struct drm_connector *connector,
4639 : const char *path)
4640 : {
4641 0 : struct drm_device *dev = connector->dev;
4642 : int ret;
4643 :
4644 0 : ret = drm_property_replace_global_blob(dev,
4645 0 : &connector->path_blob_ptr,
4646 0 : strlen(path) + 1,
4647 : path,
4648 0 : &connector->base,
4649 0 : dev->mode_config.path_property);
4650 0 : return ret;
4651 : }
4652 : EXPORT_SYMBOL(drm_mode_connector_set_path_property);
4653 :
4654 : /**
4655 : * drm_mode_connector_set_tile_property - set tile property on connector
4656 : * @connector: connector to set property on.
4657 : *
4658 : * This looks up the tile information for a connector, and creates a
4659 : * property for userspace to parse if it exists. The property is of
4660 : * the form of 8 integers using ':' as a separator.
4661 : *
4662 : * Returns:
4663 : * Zero on success, errno on failure.
4664 : */
4665 0 : int drm_mode_connector_set_tile_property(struct drm_connector *connector)
4666 : {
4667 0 : struct drm_device *dev = connector->dev;
4668 0 : char tile[256];
4669 : int ret;
4670 :
4671 0 : if (!connector->has_tile) {
4672 0 : ret = drm_property_replace_global_blob(dev,
4673 0 : &connector->tile_blob_ptr,
4674 : 0,
4675 : NULL,
4676 0 : &connector->base,
4677 0 : dev->mode_config.tile_property);
4678 0 : return ret;
4679 : }
4680 :
4681 0 : snprintf(tile, 256, "%d:%d:%d:%d:%d:%d:%d:%d",
4682 0 : connector->tile_group->id, connector->tile_is_single_monitor,
4683 0 : connector->num_h_tile, connector->num_v_tile,
4684 0 : connector->tile_h_loc, connector->tile_v_loc,
4685 0 : connector->tile_h_size, connector->tile_v_size);
4686 :
4687 0 : ret = drm_property_replace_global_blob(dev,
4688 0 : &connector->tile_blob_ptr,
4689 0 : strlen(tile) + 1,
4690 : tile,
4691 0 : &connector->base,
4692 0 : dev->mode_config.tile_property);
4693 0 : return ret;
4694 0 : }
4695 : EXPORT_SYMBOL(drm_mode_connector_set_tile_property);
4696 :
4697 : /**
4698 : * drm_mode_connector_update_edid_property - update the edid property of a connector
4699 : * @connector: drm connector
4700 : * @edid: new value of the edid property
4701 : *
4702 : * This function creates a new blob modeset object and assigns its id to the
4703 : * connector's edid property.
4704 : *
4705 : * Returns:
4706 : * Zero on success, negative errno on failure.
4707 : */
4708 0 : int drm_mode_connector_update_edid_property(struct drm_connector *connector,
4709 : const struct edid *edid)
4710 : {
4711 0 : struct drm_device *dev = connector->dev;
4712 : size_t size = 0;
4713 : int ret;
4714 :
4715 : /* ignore requests to set edid when overridden */
4716 0 : if (connector->override_edid)
4717 0 : return 0;
4718 :
4719 0 : if (edid)
4720 0 : size = EDID_LENGTH * (1 + edid->extensions);
4721 :
4722 0 : ret = drm_property_replace_global_blob(dev,
4723 0 : &connector->edid_blob_ptr,
4724 : size,
4725 0 : edid,
4726 0 : &connector->base,
4727 0 : dev->mode_config.edid_property);
4728 0 : return ret;
4729 0 : }
4730 : EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
4731 :
4732 : /* Some properties could refer to dynamic refcnt'd objects, or things that
4733 : * need special locking to handle lifetime issues (ie. to ensure the prop
4734 : * value doesn't become invalid part way through the property update due to
4735 : * race). The value returned by reference via 'obj' should be passed back
4736 : * to drm_property_change_valid_put() after the property is set (and the
4737 : * object to which the property is attached has a chance to take it's own
4738 : * reference).
4739 : */
4740 0 : bool drm_property_change_valid_get(struct drm_property *property,
4741 : uint64_t value, struct drm_mode_object **ref)
4742 : {
4743 : int i;
4744 :
4745 0 : if (property->flags & DRM_MODE_PROP_IMMUTABLE)
4746 0 : return false;
4747 :
4748 0 : *ref = NULL;
4749 :
4750 0 : if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) {
4751 0 : if (value < property->values[0] || value > property->values[1])
4752 0 : return false;
4753 0 : return true;
4754 0 : } else if (drm_property_type_is(property, DRM_MODE_PROP_SIGNED_RANGE)) {
4755 0 : int64_t svalue = U642I64(value);
4756 :
4757 0 : if (svalue < U642I64(property->values[0]) ||
4758 0 : svalue > U642I64(property->values[1]))
4759 0 : return false;
4760 0 : return true;
4761 0 : } else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
4762 : uint64_t valid_mask = 0;
4763 :
4764 0 : for (i = 0; i < property->num_values; i++)
4765 0 : valid_mask |= (1ULL << property->values[i]);
4766 0 : return !(value & ~valid_mask);
4767 0 : } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
4768 : struct drm_property_blob *blob;
4769 :
4770 0 : if (value == 0)
4771 0 : return true;
4772 :
4773 0 : blob = drm_property_lookup_blob(property->dev, value);
4774 0 : if (blob) {
4775 0 : *ref = &blob->base;
4776 0 : return true;
4777 : } else {
4778 0 : return false;
4779 : }
4780 0 : } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
4781 : /* a zero value for an object property translates to null: */
4782 0 : if (value == 0)
4783 0 : return true;
4784 :
4785 : /* handle refcnt'd objects specially: */
4786 0 : if (property->values[0] == DRM_MODE_OBJECT_FB) {
4787 : struct drm_framebuffer *fb;
4788 0 : fb = drm_framebuffer_lookup(property->dev, value);
4789 0 : if (fb) {
4790 0 : *ref = &fb->base;
4791 0 : return true;
4792 : } else {
4793 0 : return false;
4794 : }
4795 : } else {
4796 0 : return _object_find(property->dev, value, property->values[0]) != NULL;
4797 : }
4798 : }
4799 :
4800 0 : for (i = 0; i < property->num_values; i++)
4801 0 : if (property->values[i] == value)
4802 0 : return true;
4803 0 : return false;
4804 0 : }
4805 :
4806 0 : void drm_property_change_valid_put(struct drm_property *property,
4807 : struct drm_mode_object *ref)
4808 : {
4809 0 : if (!ref)
4810 : return;
4811 :
4812 0 : if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
4813 0 : if (property->values[0] == DRM_MODE_OBJECT_FB)
4814 0 : drm_framebuffer_unreference(obj_to_fb(ref));
4815 0 : } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
4816 0 : drm_property_unreference_blob(obj_to_blob(ref));
4817 0 : }
4818 :
4819 : /**
4820 : * drm_mode_connector_property_set_ioctl - set the current value of a connector property
4821 : * @dev: DRM device
4822 : * @data: ioctl data
4823 : * @file_priv: DRM file info
4824 : *
4825 : * This function sets the current value for a connectors's property. It also
4826 : * calls into a driver's ->set_property callback to update the hardware state
4827 : *
4828 : * Called by the user via ioctl.
4829 : *
4830 : * Returns:
4831 : * Zero on success, negative errno on failure.
4832 : */
4833 0 : int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
4834 : void *data, struct drm_file *file_priv)
4835 : {
4836 0 : struct drm_mode_connector_set_property *conn_set_prop = data;
4837 0 : struct drm_mode_obj_set_property obj_set_prop = {
4838 0 : .value = conn_set_prop->value,
4839 0 : .prop_id = conn_set_prop->prop_id,
4840 0 : .obj_id = conn_set_prop->connector_id,
4841 : .obj_type = DRM_MODE_OBJECT_CONNECTOR
4842 : };
4843 :
4844 : /* It does all the locking and checking we need */
4845 0 : return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv);
4846 0 : }
4847 :
4848 0 : static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
4849 : struct drm_property *property,
4850 : uint64_t value)
4851 : {
4852 : int ret = -EINVAL;
4853 0 : struct drm_connector *connector = obj_to_connector(obj);
4854 :
4855 : /* Do DPMS ourselves */
4856 0 : if (property == connector->dev->mode_config.dpms_property) {
4857 : ret = 0;
4858 0 : if (connector->funcs->dpms)
4859 0 : ret = (*connector->funcs->dpms)(connector, (int)value);
4860 : #ifdef __OpenBSD__
4861 0 : } else if (property == connector->backlight_property) {
4862 : ret = 0;
4863 0 : connector->backlight_device->props.brightness = value;
4864 0 : backlight_schedule_update_status(connector->backlight_device);
4865 : #endif
4866 0 : } else if (connector->funcs->set_property)
4867 0 : ret = connector->funcs->set_property(connector, property, value);
4868 :
4869 : /* store the property value if successful */
4870 0 : if (!ret)
4871 0 : drm_object_property_set_value(&connector->base, property, value);
4872 0 : return ret;
4873 : }
4874 :
4875 0 : static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
4876 : struct drm_property *property,
4877 : uint64_t value)
4878 : {
4879 : int ret = -EINVAL;
4880 0 : struct drm_crtc *crtc = obj_to_crtc(obj);
4881 :
4882 0 : if (crtc->funcs->set_property)
4883 0 : ret = crtc->funcs->set_property(crtc, property, value);
4884 0 : if (!ret)
4885 0 : drm_object_property_set_value(obj, property, value);
4886 :
4887 0 : return ret;
4888 : }
4889 :
4890 : /**
4891 : * drm_mode_plane_set_obj_prop - set the value of a property
4892 : * @plane: drm plane object to set property value for
4893 : * @property: property to set
4894 : * @value: value the property should be set to
4895 : *
4896 : * This functions sets a given property on a given plane object. This function
4897 : * calls the driver's ->set_property callback and changes the software state of
4898 : * the property if the callback succeeds.
4899 : *
4900 : * Returns:
4901 : * Zero on success, error code on failure.
4902 : */
4903 0 : int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
4904 : struct drm_property *property,
4905 : uint64_t value)
4906 : {
4907 : int ret = -EINVAL;
4908 0 : struct drm_mode_object *obj = &plane->base;
4909 :
4910 0 : if (plane->funcs->set_property)
4911 0 : ret = plane->funcs->set_property(plane, property, value);
4912 0 : if (!ret)
4913 0 : drm_object_property_set_value(obj, property, value);
4914 :
4915 0 : return ret;
4916 : }
4917 : EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
4918 :
4919 : /**
4920 : * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
4921 : * @dev: DRM device
4922 : * @data: ioctl data
4923 : * @file_priv: DRM file info
4924 : *
4925 : * This function retrieves the current value for an object's property. Compared
4926 : * to the connector specific ioctl this one is extended to also work on crtc and
4927 : * plane objects.
4928 : *
4929 : * Called by the user via ioctl.
4930 : *
4931 : * Returns:
4932 : * Zero on success, negative errno on failure.
4933 : */
4934 0 : int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
4935 : struct drm_file *file_priv)
4936 : {
4937 0 : struct drm_mode_obj_get_properties *arg = data;
4938 : struct drm_mode_object *obj;
4939 : int ret = 0;
4940 :
4941 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
4942 0 : return -EINVAL;
4943 :
4944 0 : drm_modeset_lock_all(dev);
4945 :
4946 0 : obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
4947 0 : if (!obj) {
4948 : ret = -ENOENT;
4949 0 : goto out;
4950 : }
4951 0 : if (!obj->properties) {
4952 : ret = -EINVAL;
4953 0 : goto out;
4954 : }
4955 :
4956 0 : ret = get_properties(obj, file_priv->atomic,
4957 0 : (uint32_t __user *)(unsigned long)(arg->props_ptr),
4958 0 : (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
4959 0 : &arg->count_props);
4960 :
4961 : out:
4962 0 : drm_modeset_unlock_all(dev);
4963 0 : return ret;
4964 0 : }
4965 :
4966 : /**
4967 : * drm_mode_obj_set_property_ioctl - set the current value of an object's property
4968 : * @dev: DRM device
4969 : * @data: ioctl data
4970 : * @file_priv: DRM file info
4971 : *
4972 : * This function sets the current value for an object's property. It also calls
4973 : * into a driver's ->set_property callback to update the hardware state.
4974 : * Compared to the connector specific ioctl this one is extended to also work on
4975 : * crtc and plane objects.
4976 : *
4977 : * Called by the user via ioctl.
4978 : *
4979 : * Returns:
4980 : * Zero on success, negative errno on failure.
4981 : */
4982 0 : int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4983 : struct drm_file *file_priv)
4984 : {
4985 0 : struct drm_mode_obj_set_property *arg = data;
4986 : struct drm_mode_object *arg_obj;
4987 : struct drm_mode_object *prop_obj;
4988 : struct drm_property *property;
4989 : int i, ret = -EINVAL;
4990 0 : struct drm_mode_object *ref;
4991 :
4992 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
4993 0 : return -EINVAL;
4994 :
4995 0 : drm_modeset_lock_all(dev);
4996 :
4997 0 : arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
4998 0 : if (!arg_obj) {
4999 : ret = -ENOENT;
5000 0 : goto out;
5001 : }
5002 0 : if (!arg_obj->properties)
5003 : goto out;
5004 :
5005 0 : for (i = 0; i < arg_obj->properties->count; i++)
5006 0 : if (arg_obj->properties->properties[i]->base.id == arg->prop_id)
5007 : break;
5008 :
5009 0 : if (i == arg_obj->properties->count)
5010 : goto out;
5011 :
5012 0 : prop_obj = drm_mode_object_find(dev, arg->prop_id,
5013 : DRM_MODE_OBJECT_PROPERTY);
5014 0 : if (!prop_obj) {
5015 : ret = -ENOENT;
5016 0 : goto out;
5017 : }
5018 0 : property = obj_to_property(prop_obj);
5019 :
5020 0 : if (!drm_property_change_valid_get(property, arg->value, &ref))
5021 : goto out;
5022 :
5023 0 : switch (arg_obj->type) {
5024 : case DRM_MODE_OBJECT_CONNECTOR:
5025 0 : ret = drm_mode_connector_set_obj_prop(arg_obj, property,
5026 0 : arg->value);
5027 0 : break;
5028 : case DRM_MODE_OBJECT_CRTC:
5029 0 : ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
5030 0 : break;
5031 : case DRM_MODE_OBJECT_PLANE:
5032 0 : ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
5033 0 : property, arg->value);
5034 0 : break;
5035 : }
5036 :
5037 0 : drm_property_change_valid_put(property, ref);
5038 :
5039 : out:
5040 0 : drm_modeset_unlock_all(dev);
5041 0 : return ret;
5042 0 : }
5043 :
5044 : /**
5045 : * drm_mode_connector_attach_encoder - attach a connector to an encoder
5046 : * @connector: connector to attach
5047 : * @encoder: encoder to attach @connector to
5048 : *
5049 : * This function links up a connector to an encoder. Note that the routing
5050 : * restrictions between encoders and crtcs are exposed to userspace through the
5051 : * possible_clones and possible_crtcs bitmasks.
5052 : *
5053 : * Returns:
5054 : * Zero on success, negative errno on failure.
5055 : */
5056 0 : int drm_mode_connector_attach_encoder(struct drm_connector *connector,
5057 : struct drm_encoder *encoder)
5058 : {
5059 : int i;
5060 :
5061 0 : for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
5062 0 : if (connector->encoder_ids[i] == 0) {
5063 0 : connector->encoder_ids[i] = encoder->base.id;
5064 0 : return 0;
5065 : }
5066 : }
5067 0 : return -ENOMEM;
5068 0 : }
5069 : EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
5070 :
5071 : /**
5072 : * drm_mode_crtc_set_gamma_size - set the gamma table size
5073 : * @crtc: CRTC to set the gamma table size for
5074 : * @gamma_size: size of the gamma table
5075 : *
5076 : * Drivers which support gamma tables should set this to the supported gamma
5077 : * table size when initializing the CRTC. Currently the drm core only supports a
5078 : * fixed gamma table size.
5079 : *
5080 : * Returns:
5081 : * Zero on success, negative errno on failure.
5082 : */
5083 0 : int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
5084 : int gamma_size)
5085 : {
5086 0 : crtc->gamma_size = gamma_size;
5087 :
5088 0 : crtc->gamma_store = kcalloc(gamma_size, sizeof(uint16_t) * 3,
5089 : GFP_KERNEL);
5090 0 : if (!crtc->gamma_store) {
5091 0 : crtc->gamma_size = 0;
5092 0 : return -ENOMEM;
5093 : }
5094 :
5095 0 : return 0;
5096 0 : }
5097 : EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
5098 :
5099 : /**
5100 : * drm_mode_gamma_set_ioctl - set the gamma table
5101 : * @dev: DRM device
5102 : * @data: ioctl data
5103 : * @file_priv: DRM file info
5104 : *
5105 : * Set the gamma table of a CRTC to the one passed in by the user. Userspace can
5106 : * inquire the required gamma table size through drm_mode_gamma_get_ioctl.
5107 : *
5108 : * Called by the user via ioctl.
5109 : *
5110 : * Returns:
5111 : * Zero on success, negative errno on failure.
5112 : */
5113 0 : int drm_mode_gamma_set_ioctl(struct drm_device *dev,
5114 : void *data, struct drm_file *file_priv)
5115 : {
5116 0 : struct drm_mode_crtc_lut *crtc_lut = data;
5117 : struct drm_crtc *crtc;
5118 : void *r_base, *g_base, *b_base;
5119 : int size;
5120 : int ret = 0;
5121 :
5122 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
5123 0 : return -EINVAL;
5124 :
5125 0 : drm_modeset_lock_all(dev);
5126 0 : crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
5127 0 : if (!crtc) {
5128 : ret = -ENOENT;
5129 0 : goto out;
5130 : }
5131 :
5132 0 : if (crtc->funcs->gamma_set == NULL) {
5133 : ret = -ENOSYS;
5134 0 : goto out;
5135 : }
5136 :
5137 : /* memcpy into gamma store */
5138 0 : if (crtc_lut->gamma_size != crtc->gamma_size) {
5139 : ret = -EINVAL;
5140 0 : goto out;
5141 : }
5142 :
5143 0 : size = crtc_lut->gamma_size * (sizeof(uint16_t));
5144 0 : r_base = crtc->gamma_store;
5145 0 : if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
5146 : ret = -EFAULT;
5147 0 : goto out;
5148 : }
5149 :
5150 0 : g_base = r_base + size;
5151 0 : if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
5152 : ret = -EFAULT;
5153 0 : goto out;
5154 : }
5155 :
5156 0 : b_base = g_base + size;
5157 0 : if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
5158 : ret = -EFAULT;
5159 0 : goto out;
5160 : }
5161 :
5162 0 : crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
5163 :
5164 : out:
5165 0 : drm_modeset_unlock_all(dev);
5166 0 : return ret;
5167 :
5168 0 : }
5169 :
5170 : /**
5171 : * drm_mode_gamma_get_ioctl - get the gamma table
5172 : * @dev: DRM device
5173 : * @data: ioctl data
5174 : * @file_priv: DRM file info
5175 : *
5176 : * Copy the current gamma table into the storage provided. This also provides
5177 : * the gamma table size the driver expects, which can be used to size the
5178 : * allocated storage.
5179 : *
5180 : * Called by the user via ioctl.
5181 : *
5182 : * Returns:
5183 : * Zero on success, negative errno on failure.
5184 : */
5185 0 : int drm_mode_gamma_get_ioctl(struct drm_device *dev,
5186 : void *data, struct drm_file *file_priv)
5187 : {
5188 0 : struct drm_mode_crtc_lut *crtc_lut = data;
5189 : struct drm_crtc *crtc;
5190 : void *r_base, *g_base, *b_base;
5191 : int size;
5192 : int ret = 0;
5193 :
5194 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
5195 0 : return -EINVAL;
5196 :
5197 0 : drm_modeset_lock_all(dev);
5198 0 : crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
5199 0 : if (!crtc) {
5200 : ret = -ENOENT;
5201 0 : goto out;
5202 : }
5203 :
5204 : /* memcpy into gamma store */
5205 0 : if (crtc_lut->gamma_size != crtc->gamma_size) {
5206 : ret = -EINVAL;
5207 0 : goto out;
5208 : }
5209 :
5210 0 : size = crtc_lut->gamma_size * (sizeof(uint16_t));
5211 0 : r_base = crtc->gamma_store;
5212 0 : if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
5213 : ret = -EFAULT;
5214 0 : goto out;
5215 : }
5216 :
5217 0 : g_base = r_base + size;
5218 0 : if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
5219 : ret = -EFAULT;
5220 0 : goto out;
5221 : }
5222 :
5223 0 : b_base = g_base + size;
5224 0 : if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
5225 : ret = -EFAULT;
5226 0 : goto out;
5227 : }
5228 : out:
5229 0 : drm_modeset_unlock_all(dev);
5230 0 : return ret;
5231 0 : }
5232 :
5233 : /**
5234 : * drm_mode_page_flip_ioctl - schedule an asynchronous fb update
5235 : * @dev: DRM device
5236 : * @data: ioctl data
5237 : * @file_priv: DRM file info
5238 : *
5239 : * This schedules an asynchronous update on a given CRTC, called page flip.
5240 : * Optionally a drm event is generated to signal the completion of the event.
5241 : * Generic drivers cannot assume that a pageflip with changed framebuffer
5242 : * properties (including driver specific metadata like tiling layout) will work,
5243 : * but some drivers support e.g. pixel format changes through the pageflip
5244 : * ioctl.
5245 : *
5246 : * Called by the user via ioctl.
5247 : *
5248 : * Returns:
5249 : * Zero on success, negative errno on failure.
5250 : */
5251 0 : int drm_mode_page_flip_ioctl(struct drm_device *dev,
5252 : void *data, struct drm_file *file_priv)
5253 : {
5254 0 : struct drm_mode_crtc_page_flip *page_flip = data;
5255 : struct drm_crtc *crtc;
5256 : struct drm_framebuffer *fb = NULL;
5257 : struct drm_pending_vblank_event *e = NULL;
5258 : unsigned long flags;
5259 : int ret = -EINVAL;
5260 :
5261 0 : if (!drm_core_check_feature(dev, DRIVER_MODESET))
5262 0 : return -EINVAL;
5263 :
5264 0 : if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
5265 0 : page_flip->reserved != 0)
5266 0 : return -EINVAL;
5267 :
5268 0 : if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
5269 0 : return -EINVAL;
5270 :
5271 0 : crtc = drm_crtc_find(dev, page_flip->crtc_id);
5272 0 : if (!crtc)
5273 0 : return -ENOENT;
5274 :
5275 0 : drm_modeset_lock_crtc(crtc, crtc->primary);
5276 0 : if (crtc->primary->fb == NULL) {
5277 : /* The framebuffer is currently unbound, presumably
5278 : * due to a hotplug event, that userspace has not
5279 : * yet discovered.
5280 : */
5281 : ret = -EBUSY;
5282 0 : goto out;
5283 : }
5284 :
5285 0 : if (crtc->funcs->page_flip == NULL)
5286 : goto out;
5287 :
5288 0 : fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
5289 0 : if (!fb) {
5290 : ret = -ENOENT;
5291 0 : goto out;
5292 : }
5293 :
5294 0 : if (crtc->state) {
5295 0 : const struct drm_plane_state *state = crtc->primary->state;
5296 :
5297 0 : ret = check_src_coords(state->src_x, state->src_y,
5298 0 : state->src_w, state->src_h, fb);
5299 0 : } else {
5300 0 : ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb);
5301 : }
5302 0 : if (ret)
5303 : goto out;
5304 :
5305 0 : if (crtc->primary->fb->pixel_format != fb->pixel_format) {
5306 : DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
5307 : ret = -EINVAL;
5308 0 : goto out;
5309 : }
5310 :
5311 0 : if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
5312 : ret = -ENOMEM;
5313 0 : spin_lock_irqsave(&dev->event_lock, flags);
5314 0 : if (file_priv->event_space < sizeof(e->event)) {
5315 0 : spin_unlock_irqrestore(&dev->event_lock, flags);
5316 0 : goto out;
5317 : }
5318 0 : file_priv->event_space -= sizeof(e->event);
5319 0 : spin_unlock_irqrestore(&dev->event_lock, flags);
5320 :
5321 0 : e = kzalloc(sizeof(*e), GFP_KERNEL);
5322 0 : if (e == NULL) {
5323 0 : spin_lock_irqsave(&dev->event_lock, flags);
5324 0 : file_priv->event_space += sizeof(e->event);
5325 0 : spin_unlock_irqrestore(&dev->event_lock, flags);
5326 0 : goto out;
5327 : }
5328 :
5329 0 : e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
5330 0 : e->event.base.length = sizeof(e->event);
5331 0 : e->event.user_data = page_flip->user_data;
5332 0 : e->base.event = &e->event.base;
5333 0 : e->base.file_priv = file_priv;
5334 0 : e->base.destroy =
5335 : (void (*) (struct drm_pending_event *)) kfree;
5336 0 : }
5337 :
5338 0 : crtc->primary->old_fb = crtc->primary->fb;
5339 0 : ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
5340 0 : if (ret) {
5341 0 : if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
5342 0 : spin_lock_irqsave(&dev->event_lock, flags);
5343 0 : file_priv->event_space += sizeof(e->event);
5344 0 : spin_unlock_irqrestore(&dev->event_lock, flags);
5345 0 : kfree(e);
5346 0 : }
5347 : /* Keep the old fb, don't unref it. */
5348 0 : crtc->primary->old_fb = NULL;
5349 0 : } else {
5350 0 : crtc->primary->fb = fb;
5351 : /* Unref only the old framebuffer. */
5352 : fb = NULL;
5353 : }
5354 :
5355 : out:
5356 0 : if (fb)
5357 0 : drm_framebuffer_unreference(fb);
5358 0 : if (crtc->primary->old_fb)
5359 0 : drm_framebuffer_unreference(crtc->primary->old_fb);
5360 0 : crtc->primary->old_fb = NULL;
5361 0 : drm_modeset_unlock_crtc(crtc);
5362 :
5363 0 : return ret;
5364 0 : }
5365 :
5366 : /**
5367 : * drm_mode_config_reset - call ->reset callbacks
5368 : * @dev: drm device
5369 : *
5370 : * This functions calls all the crtc's, encoder's and connector's ->reset
5371 : * callback. Drivers can use this in e.g. their driver load or resume code to
5372 : * reset hardware and software state.
5373 : */
5374 0 : void drm_mode_config_reset(struct drm_device *dev)
5375 : {
5376 : struct drm_crtc *crtc;
5377 : struct drm_plane *plane;
5378 : struct drm_encoder *encoder;
5379 : struct drm_connector *connector;
5380 :
5381 0 : drm_for_each_plane(plane, dev)
5382 0 : if (plane->funcs->reset)
5383 0 : plane->funcs->reset(plane);
5384 :
5385 0 : drm_for_each_crtc(crtc, dev)
5386 0 : if (crtc->funcs->reset)
5387 0 : crtc->funcs->reset(crtc);
5388 :
5389 0 : drm_for_each_encoder(encoder, dev)
5390 0 : if (encoder->funcs->reset)
5391 0 : encoder->funcs->reset(encoder);
5392 :
5393 0 : mutex_lock(&dev->mode_config.mutex);
5394 0 : drm_for_each_connector(connector, dev)
5395 0 : if (connector->funcs->reset)
5396 0 : connector->funcs->reset(connector);
5397 0 : mutex_unlock(&dev->mode_config.mutex);
5398 0 : }
5399 : EXPORT_SYMBOL(drm_mode_config_reset);
5400 :
5401 : /**
5402 : * drm_mode_create_dumb_ioctl - create a dumb backing storage buffer
5403 : * @dev: DRM device
5404 : * @data: ioctl data
5405 : * @file_priv: DRM file info
5406 : *
5407 : * This creates a new dumb buffer in the driver's backing storage manager (GEM,
5408 : * TTM or something else entirely) and returns the resulting buffer handle. This
5409 : * handle can then be wrapped up into a framebuffer modeset object.
5410 : *
5411 : * Note that userspace is not allowed to use such objects for render
5412 : * acceleration - drivers must create their own private ioctls for such a use
5413 : * case.
5414 : *
5415 : * Called by the user via ioctl.
5416 : *
5417 : * Returns:
5418 : * Zero on success, negative errno on failure.
5419 : */
5420 0 : int drm_mode_create_dumb_ioctl(struct drm_device *dev,
5421 : void *data, struct drm_file *file_priv)
5422 : {
5423 0 : struct drm_mode_create_dumb *args = data;
5424 : u32 cpp, stride, size;
5425 :
5426 0 : if (!dev->driver->dumb_create)
5427 0 : return -ENOSYS;
5428 0 : if (!args->width || !args->height || !args->bpp)
5429 0 : return -EINVAL;
5430 :
5431 : /* overflow checks for 32bit size calculations */
5432 : /* NOTE: DIV_ROUND_UP() can overflow */
5433 0 : cpp = DIV_ROUND_UP(args->bpp, 8);
5434 0 : if (!cpp || cpp > 0xffffffffU / args->width)
5435 0 : return -EINVAL;
5436 0 : stride = cpp * args->width;
5437 0 : if (args->height > 0xffffffffU / stride)
5438 0 : return -EINVAL;
5439 :
5440 : /* test for wrap-around */
5441 0 : size = args->height * stride;
5442 0 : if (PAGE_ALIGN(size) == 0)
5443 0 : return -EINVAL;
5444 :
5445 : /*
5446 : * handle, pitch and size are output parameters. Zero them out to
5447 : * prevent drivers from accidentally using uninitialized data. Since
5448 : * not all existing userspace is clearing these fields properly we
5449 : * cannot reject IOCTL with garbage in them.
5450 : */
5451 0 : args->handle = 0;
5452 0 : args->pitch = 0;
5453 0 : args->size = 0;
5454 :
5455 0 : return dev->driver->dumb_create(file_priv, dev, args);
5456 0 : }
5457 :
5458 : /**
5459 : * drm_mode_mmap_dumb_ioctl - create an mmap offset for a dumb backing storage buffer
5460 : * @dev: DRM device
5461 : * @data: ioctl data
5462 : * @file_priv: DRM file info
5463 : *
5464 : * Allocate an offset in the drm device node's address space to be able to
5465 : * memory map a dumb buffer.
5466 : *
5467 : * Called by the user via ioctl.
5468 : *
5469 : * Returns:
5470 : * Zero on success, negative errno on failure.
5471 : */
5472 0 : int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
5473 : void *data, struct drm_file *file_priv)
5474 : {
5475 0 : struct drm_mode_map_dumb *args = data;
5476 :
5477 : /* call driver ioctl to get mmap offset */
5478 0 : if (!dev->driver->dumb_map_offset)
5479 0 : return -ENOSYS;
5480 :
5481 0 : return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
5482 0 : }
5483 :
5484 : /**
5485 : * drm_mode_destroy_dumb_ioctl - destroy a dumb backing strage buffer
5486 : * @dev: DRM device
5487 : * @data: ioctl data
5488 : * @file_priv: DRM file info
5489 : *
5490 : * This destroys the userspace handle for the given dumb backing storage buffer.
5491 : * Since buffer objects must be reference counted in the kernel a buffer object
5492 : * won't be immediately freed if a framebuffer modeset object still uses it.
5493 : *
5494 : * Called by the user via ioctl.
5495 : *
5496 : * Returns:
5497 : * Zero on success, negative errno on failure.
5498 : */
5499 0 : int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
5500 : void *data, struct drm_file *file_priv)
5501 : {
5502 0 : struct drm_mode_destroy_dumb *args = data;
5503 :
5504 0 : if (!dev->driver->dumb_destroy)
5505 0 : return -ENOSYS;
5506 :
5507 0 : return dev->driver->dumb_destroy(file_priv, dev, args->handle);
5508 0 : }
5509 :
5510 : /**
5511 : * drm_fb_get_bpp_depth - get the bpp/depth values for format
5512 : * @format: pixel format (DRM_FORMAT_*)
5513 : * @depth: storage for the depth value
5514 : * @bpp: storage for the bpp value
5515 : *
5516 : * This only supports RGB formats here for compat with code that doesn't use
5517 : * pixel formats directly yet.
5518 : */
5519 0 : void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
5520 : int *bpp)
5521 : {
5522 0 : switch (format) {
5523 : case DRM_FORMAT_C8:
5524 : case DRM_FORMAT_RGB332:
5525 : case DRM_FORMAT_BGR233:
5526 0 : *depth = 8;
5527 0 : *bpp = 8;
5528 0 : break;
5529 : case DRM_FORMAT_XRGB1555:
5530 : case DRM_FORMAT_XBGR1555:
5531 : case DRM_FORMAT_RGBX5551:
5532 : case DRM_FORMAT_BGRX5551:
5533 : case DRM_FORMAT_ARGB1555:
5534 : case DRM_FORMAT_ABGR1555:
5535 : case DRM_FORMAT_RGBA5551:
5536 : case DRM_FORMAT_BGRA5551:
5537 0 : *depth = 15;
5538 0 : *bpp = 16;
5539 0 : break;
5540 : case DRM_FORMAT_RGB565:
5541 : case DRM_FORMAT_BGR565:
5542 0 : *depth = 16;
5543 0 : *bpp = 16;
5544 0 : break;
5545 : case DRM_FORMAT_RGB888:
5546 : case DRM_FORMAT_BGR888:
5547 0 : *depth = 24;
5548 0 : *bpp = 24;
5549 0 : break;
5550 : case DRM_FORMAT_XRGB8888:
5551 : case DRM_FORMAT_XBGR8888:
5552 : case DRM_FORMAT_RGBX8888:
5553 : case DRM_FORMAT_BGRX8888:
5554 0 : *depth = 24;
5555 0 : *bpp = 32;
5556 0 : break;
5557 : case DRM_FORMAT_XRGB2101010:
5558 : case DRM_FORMAT_XBGR2101010:
5559 : case DRM_FORMAT_RGBX1010102:
5560 : case DRM_FORMAT_BGRX1010102:
5561 : case DRM_FORMAT_ARGB2101010:
5562 : case DRM_FORMAT_ABGR2101010:
5563 : case DRM_FORMAT_RGBA1010102:
5564 : case DRM_FORMAT_BGRA1010102:
5565 0 : *depth = 30;
5566 0 : *bpp = 32;
5567 0 : break;
5568 : case DRM_FORMAT_ARGB8888:
5569 : case DRM_FORMAT_ABGR8888:
5570 : case DRM_FORMAT_RGBA8888:
5571 : case DRM_FORMAT_BGRA8888:
5572 0 : *depth = 32;
5573 0 : *bpp = 32;
5574 0 : break;
5575 : default:
5576 : DRM_DEBUG_KMS("unsupported pixel format %s\n",
5577 : drm_get_format_name(format));
5578 0 : *depth = 0;
5579 0 : *bpp = 0;
5580 0 : break;
5581 : }
5582 0 : }
5583 : EXPORT_SYMBOL(drm_fb_get_bpp_depth);
5584 :
5585 : /**
5586 : * drm_format_num_planes - get the number of planes for format
5587 : * @format: pixel format (DRM_FORMAT_*)
5588 : *
5589 : * Returns:
5590 : * The number of planes used by the specified pixel format.
5591 : */
5592 0 : int drm_format_num_planes(uint32_t format)
5593 : {
5594 0 : switch (format) {
5595 : case DRM_FORMAT_YUV410:
5596 : case DRM_FORMAT_YVU410:
5597 : case DRM_FORMAT_YUV411:
5598 : case DRM_FORMAT_YVU411:
5599 : case DRM_FORMAT_YUV420:
5600 : case DRM_FORMAT_YVU420:
5601 : case DRM_FORMAT_YUV422:
5602 : case DRM_FORMAT_YVU422:
5603 : case DRM_FORMAT_YUV444:
5604 : case DRM_FORMAT_YVU444:
5605 0 : return 3;
5606 : case DRM_FORMAT_NV12:
5607 : case DRM_FORMAT_NV21:
5608 : case DRM_FORMAT_NV16:
5609 : case DRM_FORMAT_NV61:
5610 : case DRM_FORMAT_NV24:
5611 : case DRM_FORMAT_NV42:
5612 0 : return 2;
5613 : default:
5614 0 : return 1;
5615 : }
5616 0 : }
5617 : EXPORT_SYMBOL(drm_format_num_planes);
5618 :
5619 : /**
5620 : * drm_format_plane_cpp - determine the bytes per pixel value
5621 : * @format: pixel format (DRM_FORMAT_*)
5622 : * @plane: plane index
5623 : *
5624 : * Returns:
5625 : * The bytes per pixel value for the specified plane.
5626 : */
5627 0 : int drm_format_plane_cpp(uint32_t format, int plane)
5628 : {
5629 0 : unsigned int depth;
5630 0 : int bpp;
5631 :
5632 0 : if (plane >= drm_format_num_planes(format))
5633 0 : return 0;
5634 :
5635 0 : switch (format) {
5636 : case DRM_FORMAT_YUYV:
5637 : case DRM_FORMAT_YVYU:
5638 : case DRM_FORMAT_UYVY:
5639 : case DRM_FORMAT_VYUY:
5640 0 : return 2;
5641 : case DRM_FORMAT_NV12:
5642 : case DRM_FORMAT_NV21:
5643 : case DRM_FORMAT_NV16:
5644 : case DRM_FORMAT_NV61:
5645 : case DRM_FORMAT_NV24:
5646 : case DRM_FORMAT_NV42:
5647 0 : return plane ? 2 : 1;
5648 : case DRM_FORMAT_YUV410:
5649 : case DRM_FORMAT_YVU410:
5650 : case DRM_FORMAT_YUV411:
5651 : case DRM_FORMAT_YVU411:
5652 : case DRM_FORMAT_YUV420:
5653 : case DRM_FORMAT_YVU420:
5654 : case DRM_FORMAT_YUV422:
5655 : case DRM_FORMAT_YVU422:
5656 : case DRM_FORMAT_YUV444:
5657 : case DRM_FORMAT_YVU444:
5658 0 : return 1;
5659 : default:
5660 0 : drm_fb_get_bpp_depth(format, &depth, &bpp);
5661 0 : return bpp >> 3;
5662 : }
5663 0 : }
5664 : EXPORT_SYMBOL(drm_format_plane_cpp);
5665 :
5666 : /**
5667 : * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
5668 : * @format: pixel format (DRM_FORMAT_*)
5669 : *
5670 : * Returns:
5671 : * The horizontal chroma subsampling factor for the
5672 : * specified pixel format.
5673 : */
5674 0 : int drm_format_horz_chroma_subsampling(uint32_t format)
5675 : {
5676 0 : switch (format) {
5677 : case DRM_FORMAT_YUV411:
5678 : case DRM_FORMAT_YVU411:
5679 : case DRM_FORMAT_YUV410:
5680 : case DRM_FORMAT_YVU410:
5681 0 : return 4;
5682 : case DRM_FORMAT_YUYV:
5683 : case DRM_FORMAT_YVYU:
5684 : case DRM_FORMAT_UYVY:
5685 : case DRM_FORMAT_VYUY:
5686 : case DRM_FORMAT_NV12:
5687 : case DRM_FORMAT_NV21:
5688 : case DRM_FORMAT_NV16:
5689 : case DRM_FORMAT_NV61:
5690 : case DRM_FORMAT_YUV422:
5691 : case DRM_FORMAT_YVU422:
5692 : case DRM_FORMAT_YUV420:
5693 : case DRM_FORMAT_YVU420:
5694 0 : return 2;
5695 : default:
5696 0 : return 1;
5697 : }
5698 0 : }
5699 : EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
5700 :
5701 : /**
5702 : * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
5703 : * @format: pixel format (DRM_FORMAT_*)
5704 : *
5705 : * Returns:
5706 : * The vertical chroma subsampling factor for the
5707 : * specified pixel format.
5708 : */
5709 0 : int drm_format_vert_chroma_subsampling(uint32_t format)
5710 : {
5711 0 : switch (format) {
5712 : case DRM_FORMAT_YUV410:
5713 : case DRM_FORMAT_YVU410:
5714 0 : return 4;
5715 : case DRM_FORMAT_YUV420:
5716 : case DRM_FORMAT_YVU420:
5717 : case DRM_FORMAT_NV12:
5718 : case DRM_FORMAT_NV21:
5719 0 : return 2;
5720 : default:
5721 0 : return 1;
5722 : }
5723 0 : }
5724 : EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
5725 :
5726 : /**
5727 : * drm_rotation_simplify() - Try to simplify the rotation
5728 : * @rotation: Rotation to be simplified
5729 : * @supported_rotations: Supported rotations
5730 : *
5731 : * Attempt to simplify the rotation to a form that is supported.
5732 : * Eg. if the hardware supports everything except DRM_REFLECT_X
5733 : * one could call this function like this:
5734 : *
5735 : * drm_rotation_simplify(rotation, BIT(DRM_ROTATE_0) |
5736 : * BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_180) |
5737 : * BIT(DRM_ROTATE_270) | BIT(DRM_REFLECT_Y));
5738 : *
5739 : * to eliminate the DRM_ROTATE_X flag. Depending on what kind of
5740 : * transforms the hardware supports, this function may not
5741 : * be able to produce a supported transform, so the caller should
5742 : * check the result afterwards.
5743 : */
5744 0 : unsigned int drm_rotation_simplify(unsigned int rotation,
5745 : unsigned int supported_rotations)
5746 : {
5747 0 : if (rotation & ~supported_rotations) {
5748 0 : rotation ^= BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y);
5749 0 : rotation = (rotation & DRM_REFLECT_MASK) |
5750 0 : BIT((ffs(rotation & DRM_ROTATE_MASK) + 1) % 4);
5751 0 : }
5752 :
5753 0 : return rotation;
5754 : }
5755 : EXPORT_SYMBOL(drm_rotation_simplify);
5756 :
5757 : /**
5758 : * drm_mode_config_init - initialize DRM mode_configuration structure
5759 : * @dev: DRM device
5760 : *
5761 : * Initialize @dev's mode_config structure, used for tracking the graphics
5762 : * configuration of @dev.
5763 : *
5764 : * Since this initializes the modeset locks, no locking is possible. Which is no
5765 : * problem, since this should happen single threaded at init time. It is the
5766 : * driver's problem to ensure this guarantee.
5767 : *
5768 : */
5769 0 : void drm_mode_config_init(struct drm_device *dev)
5770 : {
5771 0 : rw_init(&dev->mode_config.mutex, "mcrwl");
5772 0 : drm_modeset_lock_init(&dev->mode_config.connection_mutex);
5773 0 : rw_init(&dev->mode_config.idr_mutex, "idrlk");
5774 0 : rw_init(&dev->mode_config.fb_lock, "fblk");
5775 0 : rw_init(&dev->mode_config.blob_lock, "mcblk");
5776 0 : INIT_LIST_HEAD(&dev->mode_config.fb_list);
5777 0 : INIT_LIST_HEAD(&dev->mode_config.crtc_list);
5778 0 : INIT_LIST_HEAD(&dev->mode_config.connector_list);
5779 0 : INIT_LIST_HEAD(&dev->mode_config.encoder_list);
5780 0 : INIT_LIST_HEAD(&dev->mode_config.property_list);
5781 0 : INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
5782 0 : INIT_LIST_HEAD(&dev->mode_config.plane_list);
5783 0 : idr_init(&dev->mode_config.crtc_idr);
5784 0 : idr_init(&dev->mode_config.tile_idr);
5785 :
5786 0 : drm_modeset_lock_all(dev);
5787 0 : drm_mode_create_standard_properties(dev);
5788 0 : drm_modeset_unlock_all(dev);
5789 :
5790 : /* Just to be sure */
5791 0 : dev->mode_config.num_fb = 0;
5792 0 : dev->mode_config.num_connector = 0;
5793 0 : dev->mode_config.num_crtc = 0;
5794 0 : dev->mode_config.num_encoder = 0;
5795 0 : dev->mode_config.num_overlay_plane = 0;
5796 0 : dev->mode_config.num_total_plane = 0;
5797 0 : }
5798 : EXPORT_SYMBOL(drm_mode_config_init);
5799 :
5800 : /**
5801 : * drm_mode_config_cleanup - free up DRM mode_config info
5802 : * @dev: DRM device
5803 : *
5804 : * Free up all the connectors and CRTCs associated with this DRM device, then
5805 : * free up the framebuffers and associated buffer objects.
5806 : *
5807 : * Note that since this /should/ happen single-threaded at driver/device
5808 : * teardown time, no locking is required. It's the driver's job to ensure that
5809 : * this guarantee actually holds true.
5810 : *
5811 : * FIXME: cleanup any dangling user buffer objects too
5812 : */
5813 0 : void drm_mode_config_cleanup(struct drm_device *dev)
5814 : {
5815 : struct drm_connector *connector, *ot;
5816 : struct drm_crtc *crtc, *ct;
5817 : struct drm_encoder *encoder, *enct;
5818 : struct drm_framebuffer *fb, *fbt;
5819 : struct drm_property *property, *pt;
5820 : struct drm_property_blob *blob, *bt;
5821 : struct drm_plane *plane, *plt;
5822 :
5823 0 : list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
5824 : head) {
5825 0 : encoder->funcs->destroy(encoder);
5826 : }
5827 :
5828 0 : list_for_each_entry_safe(connector, ot,
5829 : &dev->mode_config.connector_list, head) {
5830 0 : connector->funcs->destroy(connector);
5831 : }
5832 :
5833 0 : list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
5834 : head) {
5835 0 : drm_property_destroy(dev, property);
5836 : }
5837 :
5838 0 : list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
5839 : head_global) {
5840 0 : drm_property_unreference_blob(blob);
5841 : }
5842 :
5843 : /*
5844 : * Single-threaded teardown context, so it's not required to grab the
5845 : * fb_lock to protect against concurrent fb_list access. Contrary, it
5846 : * would actually deadlock with the drm_framebuffer_cleanup function.
5847 : *
5848 : * Also, if there are any framebuffers left, that's a driver leak now,
5849 : * so politely WARN about this.
5850 : */
5851 0 : WARN_ON(!list_empty(&dev->mode_config.fb_list));
5852 0 : list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
5853 0 : drm_framebuffer_free(&fb->refcount);
5854 : }
5855 :
5856 0 : list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
5857 : head) {
5858 0 : plane->funcs->destroy(plane);
5859 : }
5860 :
5861 0 : list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
5862 0 : crtc->funcs->destroy(crtc);
5863 : }
5864 :
5865 0 : idr_destroy(&dev->mode_config.tile_idr);
5866 0 : idr_destroy(&dev->mode_config.crtc_idr);
5867 0 : drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
5868 0 : }
5869 : EXPORT_SYMBOL(drm_mode_config_cleanup);
5870 :
5871 0 : struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
5872 : unsigned int supported_rotations)
5873 : {
5874 : static const struct drm_prop_enum_list props[] = {
5875 : { DRM_ROTATE_0, "rotate-0" },
5876 : { DRM_ROTATE_90, "rotate-90" },
5877 : { DRM_ROTATE_180, "rotate-180" },
5878 : { DRM_ROTATE_270, "rotate-270" },
5879 : { DRM_REFLECT_X, "reflect-x" },
5880 : { DRM_REFLECT_Y, "reflect-y" },
5881 : };
5882 :
5883 0 : return drm_property_create_bitmask(dev, 0, "rotation",
5884 : props, ARRAY_SIZE(props),
5885 0 : supported_rotations);
5886 : }
5887 : EXPORT_SYMBOL(drm_mode_create_rotation_property);
5888 :
5889 : /**
5890 : * DOC: Tile group
5891 : *
5892 : * Tile groups are used to represent tiled monitors with a unique
5893 : * integer identifier. Tiled monitors using DisplayID v1.3 have
5894 : * a unique 8-byte handle, we store this in a tile group, so we
5895 : * have a common identifier for all tiles in a monitor group.
5896 : */
5897 0 : static void drm_tile_group_free(struct kref *kref)
5898 : {
5899 0 : struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
5900 0 : struct drm_device *dev = tg->dev;
5901 0 : mutex_lock(&dev->mode_config.idr_mutex);
5902 0 : idr_remove(&dev->mode_config.tile_idr, tg->id);
5903 0 : mutex_unlock(&dev->mode_config.idr_mutex);
5904 0 : kfree(tg);
5905 0 : }
5906 :
5907 : /**
5908 : * drm_mode_put_tile_group - drop a reference to a tile group.
5909 : * @dev: DRM device
5910 : * @tg: tile group to drop reference to.
5911 : *
5912 : * drop reference to tile group and free if 0.
5913 : */
5914 0 : void drm_mode_put_tile_group(struct drm_device *dev,
5915 : struct drm_tile_group *tg)
5916 : {
5917 0 : kref_put(&tg->refcount, drm_tile_group_free);
5918 0 : }
5919 :
5920 : /**
5921 : * drm_mode_get_tile_group - get a reference to an existing tile group
5922 : * @dev: DRM device
5923 : * @topology: 8-bytes unique per monitor.
5924 : *
5925 : * Use the unique bytes to get a reference to an existing tile group.
5926 : *
5927 : * RETURNS:
5928 : * tile group or NULL if not found.
5929 : */
5930 0 : struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
5931 : char topology[8])
5932 : {
5933 : struct drm_tile_group *tg;
5934 0 : int id;
5935 0 : mutex_lock(&dev->mode_config.idr_mutex);
5936 0 : idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
5937 0 : if (!memcmp(tg->group_data, topology, 8)) {
5938 0 : if (!kref_get_unless_zero(&tg->refcount))
5939 0 : tg = NULL;
5940 0 : mutex_unlock(&dev->mode_config.idr_mutex);
5941 0 : return tg;
5942 : }
5943 : }
5944 0 : mutex_unlock(&dev->mode_config.idr_mutex);
5945 0 : return NULL;
5946 0 : }
5947 : EXPORT_SYMBOL(drm_mode_get_tile_group);
5948 :
5949 : /**
5950 : * drm_mode_create_tile_group - create a tile group from a displayid description
5951 : * @dev: DRM device
5952 : * @topology: 8-bytes unique per monitor.
5953 : *
5954 : * Create a tile group for the unique monitor, and get a unique
5955 : * identifier for the tile group.
5956 : *
5957 : * RETURNS:
5958 : * new tile group or error.
5959 : */
5960 0 : struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
5961 : char topology[8])
5962 : {
5963 : struct drm_tile_group *tg;
5964 : int ret;
5965 :
5966 0 : tg = kzalloc(sizeof(*tg), GFP_KERNEL);
5967 0 : if (!tg)
5968 0 : return ERR_PTR(-ENOMEM);
5969 :
5970 0 : kref_init(&tg->refcount);
5971 0 : memcpy(tg->group_data, topology, 8);
5972 0 : tg->dev = dev;
5973 :
5974 0 : mutex_lock(&dev->mode_config.idr_mutex);
5975 0 : ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
5976 0 : if (ret >= 0) {
5977 0 : tg->id = ret;
5978 0 : } else {
5979 0 : kfree(tg);
5980 0 : tg = ERR_PTR(ret);
5981 : }
5982 :
5983 0 : mutex_unlock(&dev->mode_config.idr_mutex);
5984 0 : return tg;
5985 0 : }
5986 : EXPORT_SYMBOL(drm_mode_create_tile_group);
|