xref: /linux/drivers/gpu/drm/drm_framebuffer.c (revision 260f6f4fda93c8485c8037865c941b42b9cba5d2)
1 /*
2  * Copyright (c) 2016 Intel Corporation
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22 
23 #include <linux/export.h>
24 #include <linux/uaccess.h>
25 
26 #include <drm/drm_atomic.h>
27 #include <drm/drm_atomic_uapi.h>
28 #include <drm/drm_auth.h>
29 #include <drm/drm_debugfs.h>
30 #include <drm/drm_drv.h>
31 #include <drm/drm_file.h>
32 #include <drm/drm_fourcc.h>
33 #include <drm/drm_framebuffer.h>
34 #include <drm/drm_gem.h>
35 #include <drm/drm_print.h>
36 #include <drm/drm_util.h>
37 
38 #include "drm_crtc_internal.h"
39 #include "drm_internal.h"
40 
41 /**
42  * DOC: overview
43  *
44  * Frame buffers are abstract memory objects that provide a source of pixels to
45  * scanout to a CRTC. Applications explicitly request the creation of frame
46  * buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls and receive an opaque
47  * handle that can be passed to the KMS CRTC control, plane configuration and
48  * page flip functions.
49  *
50  * Frame buffers rely on the underlying memory manager for allocating backing
51  * storage. When creating a frame buffer applications pass a memory handle
52  * (or a list of memory handles for multi-planar formats) through the
53  * &struct drm_mode_fb_cmd2 argument. For drivers using GEM as their userspace
54  * buffer management interface this would be a GEM handle.  Drivers are however
55  * free to use their own backing storage object handles, e.g. vmwgfx directly
56  * exposes special TTM handles to userspace and so expects TTM handles in the
57  * create ioctl and not GEM handles.
58  *
59  * Framebuffers are tracked with &struct drm_framebuffer. They are published
60  * using drm_framebuffer_init() - after calling that function userspace can use
61  * and access the framebuffer object. The helper function
62  * drm_helper_mode_fill_fb_struct() can be used to pre-fill the required
63  * metadata fields.
64  *
65  * The lifetime of a drm framebuffer is controlled with a reference count,
66  * drivers can grab additional references with drm_framebuffer_get() and drop
67  * them again with drm_framebuffer_put(). For driver-private framebuffers for
68  * which the last reference is never dropped (e.g. for the fbdev framebuffer
69  * when the struct &struct drm_framebuffer is embedded into the fbdev helper
70  * struct) drivers can manually clean up a framebuffer at module unload time
71  * with drm_framebuffer_unregister_private(). But doing this is not
72  * recommended, and it's better to have a normal free-standing &struct
73  * drm_framebuffer.
74  */
75 
drm_framebuffer_check_src_coords(uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h,const struct drm_framebuffer * fb)76 int drm_framebuffer_check_src_coords(uint32_t src_x, uint32_t src_y,
77 				     uint32_t src_w, uint32_t src_h,
78 				     const struct drm_framebuffer *fb)
79 {
80 	unsigned int fb_width, fb_height;
81 
82 	fb_width = fb->width << 16;
83 	fb_height = fb->height << 16;
84 
85 	/* Make sure source coordinates are inside the fb. */
86 	if (src_w > fb_width ||
87 	    src_x > fb_width - src_w ||
88 	    src_h > fb_height ||
89 	    src_y > fb_height - src_h) {
90 		drm_dbg_kms(fb->dev, "Invalid source coordinates "
91 			    "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
92 			    src_w >> 16, ((src_w & 0xffff) * 15625) >> 10,
93 			    src_h >> 16, ((src_h & 0xffff) * 15625) >> 10,
94 			    src_x >> 16, ((src_x & 0xffff) * 15625) >> 10,
95 			    src_y >> 16, ((src_y & 0xffff) * 15625) >> 10,
96 			    fb->width, fb->height);
97 		return -ENOSPC;
98 	}
99 
100 	return 0;
101 }
102 EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_check_src_coords);
103 
104 /**
105  * drm_mode_addfb - add an FB to the graphics configuration
106  * @dev: drm device for the ioctl
107  * @or: pointer to request structure
108  * @file_priv: drm file
109  *
110  * Add a new FB to the specified CRTC, given a user request. This is the
111  * original addfb ioctl which only supported RGB formats.
112  *
113  * Called by the user via ioctl, or by an in-kernel client.
114  *
115  * Returns:
116  * Zero on success, negative errno on failure.
117  */
drm_mode_addfb(struct drm_device * dev,struct drm_mode_fb_cmd * or,struct drm_file * file_priv)118 int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or,
119 		   struct drm_file *file_priv)
120 {
121 	struct drm_mode_fb_cmd2 r = {};
122 	int ret;
123 
124 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
125 		return -EOPNOTSUPP;
126 
127 	r.pixel_format = drm_driver_legacy_fb_format(dev, or->bpp, or->depth);
128 	if (r.pixel_format == DRM_FORMAT_INVALID) {
129 		drm_dbg_kms(dev, "bad {bpp:%d, depth:%d}\n", or->bpp, or->depth);
130 		return -EINVAL;
131 	}
132 
133 	/* convert to new format and call new ioctl */
134 	r.fb_id = or->fb_id;
135 	r.width = or->width;
136 	r.height = or->height;
137 	r.pitches[0] = or->pitch;
138 	r.handles[0] = or->handle;
139 
140 	ret = drm_mode_addfb2(dev, &r, file_priv);
141 	if (ret)
142 		return ret;
143 
144 	or->fb_id = r.fb_id;
145 
146 	return 0;
147 }
148 
drm_mode_addfb_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)149 int drm_mode_addfb_ioctl(struct drm_device *dev,
150 			 void *data, struct drm_file *file_priv)
151 {
152 	return drm_mode_addfb(dev, data, file_priv);
153 }
154 
framebuffer_check(struct drm_device * dev,const struct drm_format_info * info,const struct drm_mode_fb_cmd2 * r)155 static int framebuffer_check(struct drm_device *dev,
156 			     const struct drm_format_info *info,
157 			     const struct drm_mode_fb_cmd2 *r)
158 {
159 	int i;
160 
161 	if (r->width == 0) {
162 		drm_dbg_kms(dev, "bad framebuffer width %u\n", r->width);
163 		return -EINVAL;
164 	}
165 
166 	if (r->height == 0) {
167 		drm_dbg_kms(dev, "bad framebuffer height %u\n", r->height);
168 		return -EINVAL;
169 	}
170 
171 	for (i = 0; i < info->num_planes; i++) {
172 		unsigned int width = drm_format_info_plane_width(info, r->width, i);
173 		unsigned int height = drm_format_info_plane_height(info, r->height, i);
174 		unsigned int block_size = info->char_per_block[i];
175 		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
176 
177 		if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
178 			drm_dbg_kms(dev, "Format requires non-linear modifier for plane %d\n", i);
179 			return -EINVAL;
180 		}
181 
182 		if (!r->handles[i]) {
183 			drm_dbg_kms(dev, "no buffer object handle for plane %d\n", i);
184 			return -EINVAL;
185 		}
186 
187 		if (min_pitch > UINT_MAX)
188 			return -ERANGE;
189 
190 		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
191 			return -ERANGE;
192 
193 		if (block_size && r->pitches[i] < min_pitch) {
194 			drm_dbg_kms(dev, "bad pitch %u for plane %d\n", r->pitches[i], i);
195 			return -EINVAL;
196 		}
197 
198 		if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) {
199 			drm_dbg_kms(dev, "bad fb modifier %llu for plane %d\n",
200 				    r->modifier[i], i);
201 			return -EINVAL;
202 		}
203 
204 		if (r->flags & DRM_MODE_FB_MODIFIERS &&
205 		    r->modifier[i] != r->modifier[0]) {
206 			drm_dbg_kms(dev, "bad fb modifier %llu for plane %d\n",
207 				    r->modifier[i], i);
208 			return -EINVAL;
209 		}
210 
211 		/* modifier specific checks: */
212 		switch (r->modifier[i]) {
213 		case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
214 			/* NOTE: the pitch restriction may be lifted later if it turns
215 			 * out that no hw has this restriction:
216 			 */
217 			if (r->pixel_format != DRM_FORMAT_NV12 ||
218 					width % 128 || height % 32 ||
219 					r->pitches[i] % 128) {
220 				drm_dbg_kms(dev, "bad modifier data for plane %d\n", i);
221 				return -EINVAL;
222 			}
223 			break;
224 
225 		default:
226 			break;
227 		}
228 	}
229 
230 	for (i = info->num_planes; i < 4; i++) {
231 		if (r->modifier[i]) {
232 			drm_dbg_kms(dev, "non-zero modifier for unused plane %d\n", i);
233 			return -EINVAL;
234 		}
235 
236 		/* Pre-FB_MODIFIERS userspace didn't clear the structs properly. */
237 		if (!(r->flags & DRM_MODE_FB_MODIFIERS))
238 			continue;
239 
240 		if (r->handles[i]) {
241 			drm_dbg_kms(dev, "buffer object handle for unused plane %d\n", i);
242 			return -EINVAL;
243 		}
244 
245 		if (r->pitches[i]) {
246 			drm_dbg_kms(dev, "non-zero pitch for unused plane %d\n", i);
247 			return -EINVAL;
248 		}
249 
250 		if (r->offsets[i]) {
251 			drm_dbg_kms(dev, "non-zero offset for unused plane %d\n", i);
252 			return -EINVAL;
253 		}
254 	}
255 
256 	return 0;
257 }
258 
259 struct drm_framebuffer *
drm_internal_framebuffer_create(struct drm_device * dev,const struct drm_mode_fb_cmd2 * r,struct drm_file * file_priv)260 drm_internal_framebuffer_create(struct drm_device *dev,
261 				const struct drm_mode_fb_cmd2 *r,
262 				struct drm_file *file_priv)
263 {
264 	struct drm_mode_config *config = &dev->mode_config;
265 	const struct drm_format_info *info;
266 	struct drm_framebuffer *fb;
267 	int ret;
268 
269 	if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) {
270 		drm_dbg_kms(dev, "bad framebuffer flags 0x%08x\n", r->flags);
271 		return ERR_PTR(-EINVAL);
272 	}
273 
274 	if ((config->min_width > r->width) || (r->width > config->max_width)) {
275 		drm_dbg_kms(dev, "bad framebuffer width %d, should be >= %d && <= %d\n",
276 			    r->width, config->min_width, config->max_width);
277 		return ERR_PTR(-EINVAL);
278 	}
279 	if ((config->min_height > r->height) || (r->height > config->max_height)) {
280 		drm_dbg_kms(dev, "bad framebuffer height %d, should be >= %d && <= %d\n",
281 			    r->height, config->min_height, config->max_height);
282 		return ERR_PTR(-EINVAL);
283 	}
284 
285 	if (r->flags & DRM_MODE_FB_MODIFIERS &&
286 	    dev->mode_config.fb_modifiers_not_supported) {
287 		drm_dbg_kms(dev, "driver does not support fb modifiers\n");
288 		return ERR_PTR(-EINVAL);
289 	}
290 
291 	/* check if the format is supported at all */
292 	if (!__drm_format_info(r->pixel_format)) {
293 		drm_dbg_kms(dev, "bad framebuffer format %p4cc\n",
294 			    &r->pixel_format);
295 		return ERR_PTR(-EINVAL);
296 	}
297 
298 	/* now let the driver pick its own format info */
299 	info = drm_get_format_info(dev, r->pixel_format, r->modifier[0]);
300 
301 	ret = framebuffer_check(dev, info, r);
302 	if (ret)
303 		return ERR_PTR(ret);
304 
305 	fb = dev->mode_config.funcs->fb_create(dev, file_priv, info, r);
306 	if (IS_ERR(fb)) {
307 		drm_dbg_kms(dev, "could not create framebuffer\n");
308 		return fb;
309 	}
310 
311 	return fb;
312 }
313 EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_internal_framebuffer_create);
314 
315 /**
316  * drm_mode_addfb2 - add an FB to the graphics configuration
317  * @dev: drm device for the ioctl
318  * @data: data pointer for the ioctl
319  * @file_priv: drm file for the ioctl call
320  *
321  * Add a new FB to the specified CRTC, given a user request with format. This is
322  * the 2nd version of the addfb ioctl, which supports multi-planar framebuffers
323  * and uses fourcc codes as pixel format specifiers.
324  *
325  * Called by the user via ioctl.
326  *
327  * Returns:
328  * Zero on success, negative errno on failure.
329  */
drm_mode_addfb2(struct drm_device * dev,void * data,struct drm_file * file_priv)330 int drm_mode_addfb2(struct drm_device *dev,
331 		    void *data, struct drm_file *file_priv)
332 {
333 	struct drm_mode_fb_cmd2 *r = data;
334 	struct drm_framebuffer *fb;
335 
336 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
337 		return -EOPNOTSUPP;
338 
339 	fb = drm_internal_framebuffer_create(dev, r, file_priv);
340 	if (IS_ERR(fb))
341 		return PTR_ERR(fb);
342 
343 	drm_dbg_kms(dev, "[FB:%d]\n", fb->base.id);
344 	r->fb_id = fb->base.id;
345 
346 	/* Transfer ownership to the filp for reaping on close */
347 	mutex_lock(&file_priv->fbs_lock);
348 	list_add(&fb->filp_head, &file_priv->fbs);
349 	mutex_unlock(&file_priv->fbs_lock);
350 
351 	return 0;
352 }
353 
drm_mode_addfb2_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)354 int drm_mode_addfb2_ioctl(struct drm_device *dev,
355 			  void *data, struct drm_file *file_priv)
356 {
357 #ifdef __BIG_ENDIAN
358 	if (!dev->mode_config.quirk_addfb_prefer_host_byte_order) {
359 		/*
360 		 * Drivers must set the
361 		 * quirk_addfb_prefer_host_byte_order quirk to make
362 		 * the drm_mode_addfb() compat code work correctly on
363 		 * bigendian machines.
364 		 *
365 		 * If they don't they interpret pixel_format values
366 		 * incorrectly for bug compatibility, which in turn
367 		 * implies the ADDFB2 ioctl does not work correctly
368 		 * then.  So block it to make userspace fallback to
369 		 * ADDFB.
370 		 */
371 		drm_dbg_kms(dev, "addfb2 broken on bigendian");
372 		return -EOPNOTSUPP;
373 	}
374 #endif
375 	return drm_mode_addfb2(dev, data, file_priv);
376 }
377 
378 struct drm_mode_rmfb_work {
379 	struct work_struct work;
380 	struct list_head fbs;
381 };
382 
drm_mode_rmfb_work_fn(struct work_struct * w)383 static void drm_mode_rmfb_work_fn(struct work_struct *w)
384 {
385 	struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
386 
387 	while (!list_empty(&arg->fbs)) {
388 		struct drm_framebuffer *fb =
389 			list_first_entry(&arg->fbs, typeof(*fb), filp_head);
390 
391 		drm_dbg_kms(fb->dev,
392 			    "Removing [FB:%d] from all active usage due to RMFB ioctl\n",
393 			    fb->base.id);
394 		list_del_init(&fb->filp_head);
395 		drm_framebuffer_remove(fb);
396 	}
397 }
398 
drm_mode_closefb(struct drm_framebuffer * fb,struct drm_file * file_priv)399 static int drm_mode_closefb(struct drm_framebuffer *fb,
400 			    struct drm_file *file_priv)
401 {
402 	struct drm_framebuffer *fbl;
403 	bool found = false;
404 
405 	mutex_lock(&file_priv->fbs_lock);
406 	list_for_each_entry(fbl, &file_priv->fbs, filp_head)
407 		if (fb == fbl)
408 			found = true;
409 
410 	if (!found) {
411 		mutex_unlock(&file_priv->fbs_lock);
412 		return -ENOENT;
413 	}
414 
415 	list_del_init(&fb->filp_head);
416 	mutex_unlock(&file_priv->fbs_lock);
417 
418 	/* Drop the reference that was stored in the fbs list */
419 	drm_framebuffer_put(fb);
420 
421 	return 0;
422 }
423 
424 /**
425  * drm_mode_rmfb - remove an FB from the configuration
426  * @dev: drm device
427  * @fb_id: id of framebuffer to remove
428  * @file_priv: drm file
429  *
430  * Remove the specified FB.
431  *
432  * Called by the user via ioctl, or by an in-kernel client.
433  *
434  * Returns:
435  * Zero on success, negative errno on failure.
436  */
drm_mode_rmfb(struct drm_device * dev,u32 fb_id,struct drm_file * file_priv)437 int drm_mode_rmfb(struct drm_device *dev, u32 fb_id,
438 		  struct drm_file *file_priv)
439 {
440 	struct drm_framebuffer *fb;
441 	int ret;
442 
443 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
444 		return -EOPNOTSUPP;
445 
446 	fb = drm_framebuffer_lookup(dev, file_priv, fb_id);
447 	if (!fb)
448 		return -ENOENT;
449 
450 	ret = drm_mode_closefb(fb, file_priv);
451 	if (ret != 0) {
452 		drm_framebuffer_put(fb);
453 		return ret;
454 	}
455 
456 	/*
457 	 * drm_framebuffer_remove may fail with -EINTR on pending signals,
458 	 * so run this in a separate stack as there's no way to correctly
459 	 * handle this after the fb is already removed from the lookup table.
460 	 */
461 	if (drm_framebuffer_read_refcount(fb) > 1) {
462 		struct drm_mode_rmfb_work arg;
463 
464 		INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
465 		INIT_LIST_HEAD(&arg.fbs);
466 		drm_WARN_ON(dev, !list_empty(&fb->filp_head));
467 		list_add_tail(&fb->filp_head, &arg.fbs);
468 
469 		schedule_work(&arg.work);
470 		flush_work(&arg.work);
471 		destroy_work_on_stack(&arg.work);
472 	} else
473 		drm_framebuffer_put(fb);
474 
475 	return 0;
476 }
477 
drm_mode_rmfb_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)478 int drm_mode_rmfb_ioctl(struct drm_device *dev,
479 			void *data, struct drm_file *file_priv)
480 {
481 	uint32_t *fb_id = data;
482 
483 	return drm_mode_rmfb(dev, *fb_id, file_priv);
484 }
485 
drm_mode_closefb_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)486 int drm_mode_closefb_ioctl(struct drm_device *dev,
487 			   void *data, struct drm_file *file_priv)
488 {
489 	struct drm_mode_closefb *r = data;
490 	struct drm_framebuffer *fb;
491 	int ret;
492 
493 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
494 		return -EOPNOTSUPP;
495 
496 	if (r->pad)
497 		return -EINVAL;
498 
499 	fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
500 	if (!fb)
501 		return -ENOENT;
502 
503 	ret = drm_mode_closefb(fb, file_priv);
504 	drm_framebuffer_put(fb);
505 	return ret;
506 }
507 
508 /**
509  * drm_mode_getfb - get FB info
510  * @dev: drm device for the ioctl
511  * @data: data pointer for the ioctl
512  * @file_priv: drm file for the ioctl call
513  *
514  * Lookup the FB given its ID and return info about it.
515  *
516  * Called by the user via ioctl.
517  *
518  * Returns:
519  * Zero on success, negative errno on failure.
520  */
drm_mode_getfb(struct drm_device * dev,void * data,struct drm_file * file_priv)521 int drm_mode_getfb(struct drm_device *dev,
522 		   void *data, struct drm_file *file_priv)
523 {
524 	struct drm_mode_fb_cmd *r = data;
525 	struct drm_framebuffer *fb;
526 	int ret;
527 
528 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
529 		return -EOPNOTSUPP;
530 
531 	fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
532 	if (!fb)
533 		return -ENOENT;
534 
535 	/* Multi-planar framebuffers need getfb2. */
536 	if (fb->format->num_planes > 1) {
537 		ret = -EINVAL;
538 		goto out;
539 	}
540 
541 	if (!fb->funcs->create_handle) {
542 		ret = -ENODEV;
543 		goto out;
544 	}
545 
546 	r->height = fb->height;
547 	r->width = fb->width;
548 	r->depth = fb->format->depth;
549 	r->bpp = drm_format_info_bpp(fb->format, 0);
550 	r->pitch = fb->pitches[0];
551 
552 	/* GET_FB() is an unprivileged ioctl so we must not return a
553 	 * buffer-handle to non-master processes! For
554 	 * backwards-compatibility reasons, we cannot make GET_FB() privileged,
555 	 * so just return an invalid handle for non-masters.
556 	 */
557 	if (!drm_is_current_master(file_priv) && !capable(CAP_SYS_ADMIN)) {
558 		r->handle = 0;
559 		ret = 0;
560 		goto out;
561 	}
562 
563 	ret = fb->funcs->create_handle(fb, file_priv, &r->handle);
564 
565 out:
566 	drm_framebuffer_put(fb);
567 	return ret;
568 }
569 
570 /**
571  * drm_mode_getfb2_ioctl - get extended FB info
572  * @dev: drm device for the ioctl
573  * @data: data pointer for the ioctl
574  * @file_priv: drm file for the ioctl call
575  *
576  * Lookup the FB given its ID and return info about it.
577  *
578  * Called by the user via ioctl.
579  *
580  * Returns:
581  * Zero on success, negative errno on failure.
582  */
drm_mode_getfb2_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)583 int drm_mode_getfb2_ioctl(struct drm_device *dev,
584 			  void *data, struct drm_file *file_priv)
585 {
586 	struct drm_mode_fb_cmd2 *r = data;
587 	struct drm_framebuffer *fb;
588 	unsigned int i;
589 	int ret = 0;
590 
591 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
592 		return -EINVAL;
593 
594 	fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
595 	if (!fb)
596 		return -ENOENT;
597 
598 	/* For multi-plane framebuffers, we require the driver to place the
599 	 * GEM objects directly in the drm_framebuffer. For single-plane
600 	 * framebuffers, we can fall back to create_handle.
601 	 */
602 	if (!fb->obj[0] &&
603 	    (fb->format->num_planes > 1 || !fb->funcs->create_handle)) {
604 		ret = -ENODEV;
605 		goto out;
606 	}
607 
608 	r->height = fb->height;
609 	r->width = fb->width;
610 	r->pixel_format = fb->format->format;
611 
612 	r->flags = 0;
613 	if (!dev->mode_config.fb_modifiers_not_supported)
614 		r->flags |= DRM_MODE_FB_MODIFIERS;
615 
616 	for (i = 0; i < ARRAY_SIZE(r->handles); i++) {
617 		r->handles[i] = 0;
618 		r->pitches[i] = 0;
619 		r->offsets[i] = 0;
620 		r->modifier[i] = 0;
621 	}
622 
623 	for (i = 0; i < fb->format->num_planes; i++) {
624 		r->pitches[i] = fb->pitches[i];
625 		r->offsets[i] = fb->offsets[i];
626 		if (!dev->mode_config.fb_modifiers_not_supported)
627 			r->modifier[i] = fb->modifier;
628 	}
629 
630 	/* GET_FB2() is an unprivileged ioctl so we must not return a
631 	 * buffer-handle to non master/root processes! To match GET_FB()
632 	 * just return invalid handles (0) for non masters/root
633 	 * rather than making GET_FB2() privileged.
634 	 */
635 	if (!drm_is_current_master(file_priv) && !capable(CAP_SYS_ADMIN)) {
636 		ret = 0;
637 		goto out;
638 	}
639 
640 	for (i = 0; i < fb->format->num_planes; i++) {
641 		int j;
642 
643 		/* If we reuse the same object for multiple planes, also
644 		 * return the same handle.
645 		 */
646 		for (j = 0; j < i; j++) {
647 			if (fb->obj[i] == fb->obj[j]) {
648 				r->handles[i] = r->handles[j];
649 				break;
650 			}
651 		}
652 
653 		if (r->handles[i])
654 			continue;
655 
656 		if (fb->obj[i]) {
657 			ret = drm_gem_handle_create(file_priv, fb->obj[i],
658 						    &r->handles[i]);
659 		} else {
660 			WARN_ON(i > 0);
661 			ret = fb->funcs->create_handle(fb, file_priv,
662 						       &r->handles[i]);
663 		}
664 
665 		if (ret != 0)
666 			goto out;
667 	}
668 
669 out:
670 	if (ret != 0) {
671 		/* Delete any previously-created handles on failure. */
672 		for (i = 0; i < ARRAY_SIZE(r->handles); i++) {
673 			int j;
674 
675 			if (r->handles[i])
676 				drm_gem_handle_delete(file_priv, r->handles[i]);
677 
678 			/* Zero out any handles identical to the one we just
679 			 * deleted.
680 			 */
681 			for (j = i + 1; j < ARRAY_SIZE(r->handles); j++) {
682 				if (r->handles[j] == r->handles[i])
683 					r->handles[j] = 0;
684 			}
685 		}
686 	}
687 
688 	drm_framebuffer_put(fb);
689 	return ret;
690 }
691 
692 /**
693  * drm_mode_dirtyfb_ioctl - flush frontbuffer rendering on an FB
694  * @dev: drm device for the ioctl
695  * @data: data pointer for the ioctl
696  * @file_priv: drm file for the ioctl call
697  *
698  * Lookup the FB and flush out the damaged area supplied by userspace as a clip
699  * rectangle list. Generic userspace which does frontbuffer rendering must call
700  * this ioctl to flush out the changes on manual-update display outputs, e.g.
701  * usb display-link, mipi manual update panels or edp panel self refresh modes.
702  *
703  * Modesetting drivers which always update the frontbuffer do not need to
704  * implement the corresponding &drm_framebuffer_funcs.dirty callback.
705  *
706  * Called by the user via ioctl.
707  *
708  * Returns:
709  * Zero on success, negative errno on failure.
710  */
drm_mode_dirtyfb_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)711 int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
712 			   void *data, struct drm_file *file_priv)
713 {
714 	struct drm_clip_rect __user *clips_ptr;
715 	struct drm_clip_rect *clips = NULL;
716 	struct drm_mode_fb_dirty_cmd *r = data;
717 	struct drm_framebuffer *fb;
718 	unsigned flags;
719 	int num_clips;
720 	int ret;
721 
722 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
723 		return -EOPNOTSUPP;
724 
725 	fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
726 	if (!fb)
727 		return -ENOENT;
728 
729 	num_clips = r->num_clips;
730 	clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
731 
732 	if (!num_clips != !clips_ptr) {
733 		ret = -EINVAL;
734 		goto out_err1;
735 	}
736 
737 	flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
738 
739 	/* If userspace annotates copy, clips must come in pairs */
740 	if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
741 		ret = -EINVAL;
742 		goto out_err1;
743 	}
744 
745 	if (num_clips && clips_ptr) {
746 		if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
747 			ret = -EINVAL;
748 			goto out_err1;
749 		}
750 		clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
751 		if (!clips) {
752 			ret = -ENOMEM;
753 			goto out_err1;
754 		}
755 
756 		ret = copy_from_user(clips, clips_ptr,
757 				     num_clips * sizeof(*clips));
758 		if (ret) {
759 			ret = -EFAULT;
760 			goto out_err2;
761 		}
762 	}
763 
764 	if (fb->funcs->dirty) {
765 		ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
766 				       clips, num_clips);
767 	} else {
768 		ret = -ENOSYS;
769 	}
770 
771 out_err2:
772 	kfree(clips);
773 out_err1:
774 	drm_framebuffer_put(fb);
775 
776 	return ret;
777 }
778 
779 /**
780  * drm_fb_release - remove and free the FBs on this file
781  * @priv: drm file for the ioctl
782  *
783  * Destroy all the FBs associated with @filp.
784  *
785  * Called by the user via ioctl.
786  *
787  * Returns:
788  * Zero on success, negative errno on failure.
789  */
drm_fb_release(struct drm_file * priv)790 void drm_fb_release(struct drm_file *priv)
791 {
792 	struct drm_framebuffer *fb, *tfb;
793 	struct drm_mode_rmfb_work arg;
794 
795 	INIT_LIST_HEAD(&arg.fbs);
796 
797 	/*
798 	 * When the file gets released that means no one else can access the fb
799 	 * list any more, so no need to grab fpriv->fbs_lock. And we need to
800 	 * avoid upsetting lockdep since the universal cursor code adds a
801 	 * framebuffer while holding mutex locks.
802 	 *
803 	 * Note that a real deadlock between fpriv->fbs_lock and the modeset
804 	 * locks is impossible here since no one else but this function can get
805 	 * at it any more.
806 	 */
807 	list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
808 		if (drm_framebuffer_read_refcount(fb) > 1) {
809 			list_move_tail(&fb->filp_head, &arg.fbs);
810 		} else {
811 			list_del_init(&fb->filp_head);
812 
813 			/* This drops the fpriv->fbs reference. */
814 			drm_framebuffer_put(fb);
815 		}
816 	}
817 
818 	if (!list_empty(&arg.fbs)) {
819 		INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
820 
821 		schedule_work(&arg.work);
822 		flush_work(&arg.work);
823 		destroy_work_on_stack(&arg.work);
824 	}
825 }
826 
drm_framebuffer_free(struct kref * kref)827 void drm_framebuffer_free(struct kref *kref)
828 {
829 	struct drm_framebuffer *fb =
830 			container_of(kref, struct drm_framebuffer, base.refcount);
831 	struct drm_device *dev = fb->dev;
832 
833 	drm_WARN_ON(dev, !list_empty(&fb->filp_head));
834 
835 	/*
836 	 * The lookup idr holds a weak reference, which has not necessarily been
837 	 * removed at this point. Check for that.
838 	 */
839 	drm_mode_object_unregister(dev, &fb->base);
840 
841 	fb->funcs->destroy(fb);
842 }
843 EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_free);
844 
845 /**
846  * drm_framebuffer_init - initialize a framebuffer
847  * @dev: DRM device
848  * @fb: framebuffer to be initialized
849  * @funcs: ... with these functions
850  *
851  * Allocates an ID for the framebuffer's parent mode object, sets its mode
852  * functions & device file and adds it to the master fd list.
853  *
854  * IMPORTANT:
855  * This functions publishes the fb and makes it available for concurrent access
856  * by other users. Which means by this point the fb _must_ be fully set up -
857  * since all the fb attributes are invariant over its lifetime, no further
858  * locking but only correct reference counting is required.
859  *
860  * Returns:
861  * Zero on success, error code on failure.
862  */
drm_framebuffer_init(struct drm_device * dev,struct drm_framebuffer * fb,const struct drm_framebuffer_funcs * funcs)863 int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
864 			 const struct drm_framebuffer_funcs *funcs)
865 {
866 	unsigned int i;
867 	int ret;
868 	bool exists;
869 
870 	if (WARN_ON_ONCE(fb->dev != dev || !fb->format))
871 		return -EINVAL;
872 
873 	for (i = 0; i < fb->format->num_planes; i++) {
874 		if (drm_WARN_ON_ONCE(dev, fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)))
875 			fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
876 		if (fb->obj[i]) {
877 			exists = drm_gem_object_handle_get_if_exists_unlocked(fb->obj[i]);
878 			if (exists)
879 				fb->internal_flags |= DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
880 		}
881 	}
882 
883 	INIT_LIST_HEAD(&fb->filp_head);
884 
885 	fb->funcs = funcs;
886 	strscpy(fb->comm, current->comm);
887 
888 	ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,
889 				    false, drm_framebuffer_free);
890 	if (ret)
891 		goto err;
892 
893 	mutex_lock(&dev->mode_config.fb_lock);
894 	dev->mode_config.num_fb++;
895 	list_add(&fb->head, &dev->mode_config.fb_list);
896 	mutex_unlock(&dev->mode_config.fb_lock);
897 
898 	drm_mode_object_register(dev, &fb->base);
899 
900 	return 0;
901 
902 err:
903 	for (i = 0; i < fb->format->num_planes; i++) {
904 		if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)) {
905 			drm_gem_object_handle_put_unlocked(fb->obj[i]);
906 			fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
907 		}
908 	}
909 	return ret;
910 }
911 EXPORT_SYMBOL(drm_framebuffer_init);
912 
913 /**
914  * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
915  * @dev: drm device
916  * @file_priv: drm file to check for lease against.
917  * @id: id of the fb object
918  *
919  * If successful, this grabs an additional reference to the framebuffer -
920  * callers need to make sure to eventually unreference the returned framebuffer
921  * again, using drm_framebuffer_put().
922  */
drm_framebuffer_lookup(struct drm_device * dev,struct drm_file * file_priv,uint32_t id)923 struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
924 					       struct drm_file *file_priv,
925 					       uint32_t id)
926 {
927 	struct drm_mode_object *obj;
928 	struct drm_framebuffer *fb = NULL;
929 
930 	obj = __drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_FB);
931 	if (obj)
932 		fb = obj_to_fb(obj);
933 	return fb;
934 }
935 EXPORT_SYMBOL(drm_framebuffer_lookup);
936 
937 /**
938  * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
939  * @fb: fb to unregister
940  *
941  * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
942  * those used for fbdev. Note that the caller must hold a reference of its own,
943  * i.e. the object may not be destroyed through this call (since it'll lead to a
944  * locking inversion).
945  *
946  * NOTE: This function is deprecated. For driver-private framebuffers it is not
947  * recommended to embed a framebuffer struct info fbdev struct, instead, a
948  * framebuffer pointer is preferred and drm_framebuffer_put() should be called
949  * when the framebuffer is to be cleaned up.
950  */
drm_framebuffer_unregister_private(struct drm_framebuffer * fb)951 void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
952 {
953 	struct drm_device *dev;
954 
955 	if (!fb)
956 		return;
957 
958 	dev = fb->dev;
959 
960 	/* Mark fb as reaped and drop idr ref. */
961 	drm_mode_object_unregister(dev, &fb->base);
962 }
963 EXPORT_SYMBOL(drm_framebuffer_unregister_private);
964 
965 /**
966  * drm_framebuffer_cleanup - remove a framebuffer object
967  * @fb: framebuffer to remove
968  *
969  * Cleanup framebuffer. This function is intended to be used from the drivers
970  * &drm_framebuffer_funcs.destroy callback. It can also be used to clean up
971  * driver private framebuffers embedded into a larger structure.
972  *
973  * Note that this function does not remove the fb from active usage - if it is
974  * still used anywhere, hilarity can ensue since userspace could call getfb on
975  * the id and get back -EINVAL. Obviously no concern at driver unload time.
976  *
977  * Also, the framebuffer will not be removed from the lookup idr - for
978  * user-created framebuffers this will happen in the rmfb ioctl. For
979  * driver-private objects (e.g. for fbdev) drivers need to explicitly call
980  * drm_framebuffer_unregister_private.
981  */
drm_framebuffer_cleanup(struct drm_framebuffer * fb)982 void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
983 {
984 	struct drm_device *dev = fb->dev;
985 	unsigned int i;
986 
987 	for (i = 0; i < fb->format->num_planes; i++) {
988 		if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i))
989 			drm_gem_object_handle_put_unlocked(fb->obj[i]);
990 	}
991 
992 	mutex_lock(&dev->mode_config.fb_lock);
993 	list_del(&fb->head);
994 	dev->mode_config.num_fb--;
995 	mutex_unlock(&dev->mode_config.fb_lock);
996 }
997 EXPORT_SYMBOL(drm_framebuffer_cleanup);
998 
atomic_remove_fb(struct drm_framebuffer * fb)999 static int atomic_remove_fb(struct drm_framebuffer *fb)
1000 {
1001 	struct drm_modeset_acquire_ctx ctx;
1002 	struct drm_device *dev = fb->dev;
1003 	struct drm_atomic_state *state;
1004 	struct drm_plane *plane;
1005 	struct drm_connector *conn __maybe_unused;
1006 	struct drm_connector_state *conn_state;
1007 	int i, ret;
1008 	unsigned plane_mask;
1009 	bool disable_crtcs = false;
1010 
1011 retry_disable:
1012 	drm_modeset_acquire_init(&ctx, 0);
1013 
1014 	state = drm_atomic_state_alloc(dev);
1015 	if (!state) {
1016 		ret = -ENOMEM;
1017 		goto out;
1018 	}
1019 	state->acquire_ctx = &ctx;
1020 
1021 retry:
1022 	plane_mask = 0;
1023 	ret = drm_modeset_lock_all_ctx(dev, &ctx);
1024 	if (ret)
1025 		goto unlock;
1026 
1027 	drm_for_each_plane(plane, dev) {
1028 		struct drm_plane_state *plane_state;
1029 
1030 		if (plane->state->fb != fb)
1031 			continue;
1032 
1033 		drm_dbg_kms(dev,
1034 			    "Disabling [PLANE:%d:%s] because [FB:%d] is removed\n",
1035 			    plane->base.id, plane->name, fb->base.id);
1036 
1037 		plane_state = drm_atomic_get_plane_state(state, plane);
1038 		if (IS_ERR(plane_state)) {
1039 			ret = PTR_ERR(plane_state);
1040 			goto unlock;
1041 		}
1042 
1043 		if (disable_crtcs && plane_state->crtc->primary == plane) {
1044 			struct drm_crtc_state *crtc_state;
1045 
1046 			drm_dbg_kms(dev,
1047 				    "Disabling [CRTC:%d:%s] because [FB:%d] is removed\n",
1048 				    plane_state->crtc->base.id,
1049 				    plane_state->crtc->name, fb->base.id);
1050 
1051 			crtc_state = drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
1052 
1053 			ret = drm_atomic_add_affected_connectors(state, plane_state->crtc);
1054 			if (ret)
1055 				goto unlock;
1056 
1057 			crtc_state->active = false;
1058 			ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
1059 			if (ret)
1060 				goto unlock;
1061 		}
1062 
1063 		drm_atomic_set_fb_for_plane(plane_state, NULL);
1064 		ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
1065 		if (ret)
1066 			goto unlock;
1067 
1068 		plane_mask |= drm_plane_mask(plane);
1069 	}
1070 
1071 	/* This list is only filled when disable_crtcs is set. */
1072 	for_each_new_connector_in_state(state, conn, conn_state, i) {
1073 		ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
1074 
1075 		if (ret)
1076 			goto unlock;
1077 	}
1078 
1079 	if (plane_mask)
1080 		ret = drm_atomic_commit(state);
1081 
1082 unlock:
1083 	if (ret == -EDEADLK) {
1084 		drm_atomic_state_clear(state);
1085 		drm_modeset_backoff(&ctx);
1086 		goto retry;
1087 	}
1088 
1089 	drm_atomic_state_put(state);
1090 
1091 out:
1092 	drm_modeset_drop_locks(&ctx);
1093 	drm_modeset_acquire_fini(&ctx);
1094 
1095 	if (ret == -EINVAL && !disable_crtcs) {
1096 		disable_crtcs = true;
1097 		goto retry_disable;
1098 	}
1099 
1100 	return ret;
1101 }
1102 
legacy_remove_fb(struct drm_framebuffer * fb)1103 static void legacy_remove_fb(struct drm_framebuffer *fb)
1104 {
1105 	struct drm_device *dev = fb->dev;
1106 	struct drm_crtc *crtc;
1107 	struct drm_plane *plane;
1108 
1109 	drm_modeset_lock_all(dev);
1110 	/* remove from any CRTC */
1111 	drm_for_each_crtc(crtc, dev) {
1112 		if (crtc->primary->fb == fb) {
1113 			drm_dbg_kms(dev,
1114 				    "Disabling [CRTC:%d:%s] because [FB:%d] is removed\n",
1115 				    crtc->base.id, crtc->name, fb->base.id);
1116 
1117 			/* should turn off the crtc */
1118 			if (drm_crtc_force_disable(crtc))
1119 				DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
1120 		}
1121 	}
1122 
1123 	drm_for_each_plane(plane, dev) {
1124 		if (plane->fb == fb) {
1125 			drm_dbg_kms(dev,
1126 				    "Disabling [PLANE:%d:%s] because [FB:%d] is removed\n",
1127 				    plane->base.id, plane->name, fb->base.id);
1128 			drm_plane_force_disable(plane);
1129 		}
1130 	}
1131 	drm_modeset_unlock_all(dev);
1132 }
1133 
1134 /**
1135  * drm_framebuffer_remove - remove and unreference a framebuffer object
1136  * @fb: framebuffer to remove
1137  *
1138  * Scans all the CRTCs and planes in @dev's mode_config.  If they're
1139  * using @fb, removes it, setting it to NULL. Then drops the reference to the
1140  * passed-in framebuffer. Might take the modeset locks.
1141  *
1142  * Note that this function optimizes the cleanup away if the caller holds the
1143  * last reference to the framebuffer. It is also guaranteed to not take the
1144  * modeset locks in this case.
1145  */
drm_framebuffer_remove(struct drm_framebuffer * fb)1146 void drm_framebuffer_remove(struct drm_framebuffer *fb)
1147 {
1148 	struct drm_device *dev;
1149 
1150 	if (!fb)
1151 		return;
1152 
1153 	dev = fb->dev;
1154 
1155 	drm_WARN_ON(dev, !list_empty(&fb->filp_head));
1156 
1157 	/*
1158 	 * drm ABI mandates that we remove any deleted framebuffers from active
1159 	 * usage. But since most sane clients only remove framebuffers they no
1160 	 * longer need, try to optimize this away.
1161 	 *
1162 	 * Since we're holding a reference ourselves, observing a refcount of 1
1163 	 * means that we're the last holder and can skip it. Also, the refcount
1164 	 * can never increase from 1 again, so we don't need any barriers or
1165 	 * locks.
1166 	 *
1167 	 * Note that userspace could try to race with use and instate a new
1168 	 * usage _after_ we've cleared all current ones. End result will be an
1169 	 * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
1170 	 * in this manner.
1171 	 */
1172 	if (drm_framebuffer_read_refcount(fb) > 1) {
1173 		if (drm_drv_uses_atomic_modeset(dev)) {
1174 			int ret = atomic_remove_fb(fb);
1175 
1176 			WARN(ret, "atomic remove_fb failed with %i\n", ret);
1177 		} else
1178 			legacy_remove_fb(fb);
1179 	}
1180 
1181 	drm_framebuffer_put(fb);
1182 }
1183 EXPORT_SYMBOL(drm_framebuffer_remove);
1184 
drm_framebuffer_print_info(struct drm_printer * p,unsigned int indent,const struct drm_framebuffer * fb)1185 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
1186 				const struct drm_framebuffer *fb)
1187 {
1188 	unsigned int i;
1189 
1190 	drm_printf_indent(p, indent, "allocated by = %s\n", fb->comm);
1191 	drm_printf_indent(p, indent, "refcount=%u\n",
1192 			  drm_framebuffer_read_refcount(fb));
1193 	drm_printf_indent(p, indent, "format=%p4cc\n", &fb->format->format);
1194 	drm_printf_indent(p, indent, "modifier=0x%llx\n", fb->modifier);
1195 	drm_printf_indent(p, indent, "size=%ux%u\n", fb->width, fb->height);
1196 	drm_printf_indent(p, indent, "layers:\n");
1197 
1198 	for (i = 0; i < fb->format->num_planes; i++) {
1199 		drm_printf_indent(p, indent + 1, "size[%u]=%dx%d\n", i,
1200 				  drm_format_info_plane_width(fb->format, fb->width, i),
1201 				  drm_format_info_plane_height(fb->format, fb->height, i));
1202 		drm_printf_indent(p, indent + 1, "pitch[%u]=%u\n", i, fb->pitches[i]);
1203 		drm_printf_indent(p, indent + 1, "offset[%u]=%u\n", i, fb->offsets[i]);
1204 		drm_printf_indent(p, indent + 1, "obj[%u]:%s\n", i,
1205 				  fb->obj[i] ? "" : "(null)");
1206 		if (fb->obj[i])
1207 			drm_gem_print_info(p, indent + 2, fb->obj[i]);
1208 	}
1209 }
1210 
1211 #ifdef CONFIG_DEBUG_FS
drm_framebuffer_info(struct seq_file * m,void * data)1212 static int drm_framebuffer_info(struct seq_file *m, void *data)
1213 {
1214 	struct drm_debugfs_entry *entry = m->private;
1215 	struct drm_device *dev = entry->dev;
1216 	struct drm_printer p = drm_seq_file_printer(m);
1217 	struct drm_framebuffer *fb;
1218 
1219 	mutex_lock(&dev->mode_config.fb_lock);
1220 	drm_for_each_fb(fb, dev) {
1221 		drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
1222 		drm_framebuffer_print_info(&p, 1, fb);
1223 	}
1224 	mutex_unlock(&dev->mode_config.fb_lock);
1225 
1226 	return 0;
1227 }
1228 
1229 static const struct drm_debugfs_info drm_framebuffer_debugfs_list[] = {
1230 	{ "framebuffer", drm_framebuffer_info, 0 },
1231 };
1232 
drm_framebuffer_debugfs_init(struct drm_device * dev)1233 void drm_framebuffer_debugfs_init(struct drm_device *dev)
1234 {
1235 	drm_debugfs_add_files(dev, drm_framebuffer_debugfs_list,
1236 			      ARRAY_SIZE(drm_framebuffer_debugfs_list));
1237 }
1238 #endif
1239