xref: /openbmc/linux/drivers/gpu/drm/drm_plane.c (revision 7d7ae873b5e0f46d19e5dc818d1a7809e4b7cc81)
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/slab.h>
24  #include <linux/uaccess.h>
25  
26  #include <drm/drm_plane.h>
27  #include <drm/drm_drv.h>
28  #include <drm/drm_print.h>
29  #include <drm/drm_framebuffer.h>
30  #include <drm/drm_file.h>
31  #include <drm/drm_crtc.h>
32  #include <drm/drm_fourcc.h>
33  #include <drm/drm_managed.h>
34  #include <drm/drm_vblank.h>
35  
36  #include "drm_crtc_internal.h"
37  
38  /**
39   * DOC: overview
40   *
41   * A plane represents an image source that can be blended with or overlaid on
42   * top of a CRTC during the scanout process. Planes take their input data from a
43   * &drm_framebuffer object. The plane itself specifies the cropping and scaling
44   * of that image, and where it is placed on the visible area of a display
45   * pipeline, represented by &drm_crtc. A plane can also have additional
46   * properties that specify how the pixels are positioned and blended, like
47   * rotation or Z-position. All these properties are stored in &drm_plane_state.
48   *
49   * Unless explicitly specified (via CRTC property or otherwise), the active area
50   * of a CRTC will be black by default. This means portions of the active area
51   * which are not covered by a plane will be black, and alpha blending of any
52   * planes with the CRTC background will blend with black at the lowest zpos.
53   *
54   * To create a plane, a KMS drivers allocates and zeroes an instances of
55   * &struct drm_plane (possibly as part of a larger structure) and registers it
56   * with a call to drm_universal_plane_init().
57   *
58   * Each plane has a type, see enum drm_plane_type. A plane can be compatible
59   * with multiple CRTCs, see &drm_plane.possible_crtcs.
60   *
61   * Each CRTC must have a unique primary plane userspace can attach to enable
62   * the CRTC. In other words, userspace must be able to attach a different
63   * primary plane to each CRTC at the same time. Primary planes can still be
64   * compatible with multiple CRTCs. There must be exactly as many primary planes
65   * as there are CRTCs.
66   *
67   * Legacy uAPI doesn't expose the primary and cursor planes directly. DRM core
68   * relies on the driver to set the primary and optionally the cursor plane used
69   * for legacy IOCTLs. This is done by calling drm_crtc_init_with_planes(). All
70   * drivers must provide one primary plane per CRTC to avoid surprising legacy
71   * userspace too much.
72   */
73  
74  /**
75   * DOC: standard plane properties
76   *
77   * DRM planes have a few standardized properties:
78   *
79   * type:
80   *     Immutable property describing the type of the plane.
81   *
82   *     For user-space which has enabled the &DRM_CLIENT_CAP_ATOMIC capability,
83   *     the plane type is just a hint and is mostly superseded by atomic
84   *     test-only commits. The type hint can still be used to come up more
85   *     easily with a plane configuration accepted by the driver.
86   *
87   *     The value of this property can be one of the following:
88   *
89   *     "Primary":
90   *         To light up a CRTC, attaching a primary plane is the most likely to
91   *         work if it covers the whole CRTC and doesn't have scaling or
92   *         cropping set up.
93   *
94   *         Drivers may support more features for the primary plane, user-space
95   *         can find out with test-only atomic commits.
96   *
97   *         Some primary planes are implicitly used by the kernel in the legacy
98   *         IOCTLs &DRM_IOCTL_MODE_SETCRTC and &DRM_IOCTL_MODE_PAGE_FLIP.
99   *         Therefore user-space must not mix explicit usage of any primary
100   *         plane (e.g. through an atomic commit) with these legacy IOCTLs.
101   *
102   *     "Cursor":
103   *         To enable this plane, using a framebuffer configured without scaling
104   *         or cropping and with the following properties is the most likely to
105   *         work:
106   *
107   *         - If the driver provides the capabilities &DRM_CAP_CURSOR_WIDTH and
108   *           &DRM_CAP_CURSOR_HEIGHT, create the framebuffer with this size.
109   *           Otherwise, create a framebuffer with the size 64x64.
110   *         - If the driver doesn't support modifiers, create a framebuffer with
111   *           a linear layout. Otherwise, use the IN_FORMATS plane property.
112   *
113   *         Drivers may support more features for the cursor plane, user-space
114   *         can find out with test-only atomic commits.
115   *
116   *         Some cursor planes are implicitly used by the kernel in the legacy
117   *         IOCTLs &DRM_IOCTL_MODE_CURSOR and &DRM_IOCTL_MODE_CURSOR2.
118   *         Therefore user-space must not mix explicit usage of any cursor
119   *         plane (e.g. through an atomic commit) with these legacy IOCTLs.
120   *
121   *         Some drivers may support cursors even if no cursor plane is exposed.
122   *         In this case, the legacy cursor IOCTLs can be used to configure the
123   *         cursor.
124   *
125   *     "Overlay":
126   *         Neither primary nor cursor.
127   *
128   *         Overlay planes are the only planes exposed when the
129   *         &DRM_CLIENT_CAP_UNIVERSAL_PLANES capability is disabled.
130   *
131   * IN_FORMATS:
132   *     Blob property which contains the set of buffer format and modifier
133   *     pairs supported by this plane. The blob is a struct
134   *     drm_format_modifier_blob. Without this property the plane doesn't
135   *     support buffers with modifiers. Userspace cannot change this property.
136   *
137   *     Note that userspace can check the &DRM_CAP_ADDFB2_MODIFIERS driver
138   *     capability for general modifier support. If this flag is set then every
139   *     plane will have the IN_FORMATS property, even when it only supports
140   *     DRM_FORMAT_MOD_LINEAR. Before linux kernel release v5.1 there have been
141   *     various bugs in this area with inconsistencies between the capability
142   *     flag and per-plane properties.
143   */
144  
drm_num_planes(struct drm_device * dev)145  static unsigned int drm_num_planes(struct drm_device *dev)
146  {
147  	unsigned int num = 0;
148  	struct drm_plane *tmp;
149  
150  	drm_for_each_plane(tmp, dev) {
151  		num++;
152  	}
153  
154  	return num;
155  }
156  
157  static inline u32 *
formats_ptr(struct drm_format_modifier_blob * blob)158  formats_ptr(struct drm_format_modifier_blob *blob)
159  {
160  	return (u32 *)(((char *)blob) + blob->formats_offset);
161  }
162  
163  static inline struct drm_format_modifier *
modifiers_ptr(struct drm_format_modifier_blob * blob)164  modifiers_ptr(struct drm_format_modifier_blob *blob)
165  {
166  	return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
167  }
168  
create_in_format_blob(struct drm_device * dev,struct drm_plane * plane)169  static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane)
170  {
171  	const struct drm_mode_config *config = &dev->mode_config;
172  	struct drm_property_blob *blob;
173  	struct drm_format_modifier *mod;
174  	size_t blob_size, formats_size, modifiers_size;
175  	struct drm_format_modifier_blob *blob_data;
176  	unsigned int i, j;
177  
178  	formats_size = sizeof(__u32) * plane->format_count;
179  	if (WARN_ON(!formats_size)) {
180  		/* 0 formats are never expected */
181  		return 0;
182  	}
183  
184  	modifiers_size =
185  		sizeof(struct drm_format_modifier) * plane->modifier_count;
186  
187  	blob_size = sizeof(struct drm_format_modifier_blob);
188  	/* Modifiers offset is a pointer to a struct with a 64 bit field so it
189  	 * should be naturally aligned to 8B.
190  	 */
191  	BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8);
192  	blob_size += ALIGN(formats_size, 8);
193  	blob_size += modifiers_size;
194  
195  	blob = drm_property_create_blob(dev, blob_size, NULL);
196  	if (IS_ERR(blob))
197  		return -1;
198  
199  	blob_data = blob->data;
200  	blob_data->version = FORMAT_BLOB_CURRENT;
201  	blob_data->count_formats = plane->format_count;
202  	blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
203  	blob_data->count_modifiers = plane->modifier_count;
204  
205  	blob_data->modifiers_offset =
206  		ALIGN(blob_data->formats_offset + formats_size, 8);
207  
208  	memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
209  
210  	mod = modifiers_ptr(blob_data);
211  	for (i = 0; i < plane->modifier_count; i++) {
212  		for (j = 0; j < plane->format_count; j++) {
213  			if (!plane->funcs->format_mod_supported ||
214  			    plane->funcs->format_mod_supported(plane,
215  							       plane->format_types[j],
216  							       plane->modifiers[i])) {
217  				mod->formats |= 1ULL << j;
218  			}
219  		}
220  
221  		mod->modifier = plane->modifiers[i];
222  		mod->offset = 0;
223  		mod->pad = 0;
224  		mod++;
225  	}
226  
227  	drm_object_attach_property(&plane->base, config->modifiers_property,
228  				   blob->base.id);
229  
230  	return 0;
231  }
232  
233  __printf(9, 0)
__drm_universal_plane_init(struct drm_device * dev,struct drm_plane * plane,uint32_t possible_crtcs,const struct drm_plane_funcs * funcs,const uint32_t * formats,unsigned int format_count,const uint64_t * format_modifiers,enum drm_plane_type type,const char * name,va_list ap)234  static int __drm_universal_plane_init(struct drm_device *dev,
235  				      struct drm_plane *plane,
236  				      uint32_t possible_crtcs,
237  				      const struct drm_plane_funcs *funcs,
238  				      const uint32_t *formats,
239  				      unsigned int format_count,
240  				      const uint64_t *format_modifiers,
241  				      enum drm_plane_type type,
242  				      const char *name, va_list ap)
243  {
244  	struct drm_mode_config *config = &dev->mode_config;
245  	static const uint64_t default_modifiers[] = {
246  		DRM_FORMAT_MOD_LINEAR,
247  	};
248  	unsigned int format_modifier_count = 0;
249  	int ret;
250  
251  	/* plane index is used with 32bit bitmasks */
252  	if (WARN_ON(config->num_total_plane >= 32))
253  		return -EINVAL;
254  
255  	/*
256  	 * First driver to need more than 64 formats needs to fix this. Each
257  	 * format is encoded as a bit and the current code only supports a u64.
258  	 */
259  	if (WARN_ON(format_count > 64))
260  		return -EINVAL;
261  
262  	WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
263  		(!funcs->atomic_destroy_state ||
264  		 !funcs->atomic_duplicate_state));
265  
266  	ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
267  	if (ret)
268  		return ret;
269  
270  	drm_modeset_lock_init(&plane->mutex);
271  
272  	plane->base.properties = &plane->properties;
273  	plane->dev = dev;
274  	plane->funcs = funcs;
275  	plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
276  					    GFP_KERNEL);
277  	if (!plane->format_types) {
278  		DRM_DEBUG_KMS("out of memory when allocating plane\n");
279  		drm_mode_object_unregister(dev, &plane->base);
280  		return -ENOMEM;
281  	}
282  
283  	if (format_modifiers) {
284  		const uint64_t *temp_modifiers = format_modifiers;
285  
286  		while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
287  			format_modifier_count++;
288  	} else {
289  		if (!dev->mode_config.fb_modifiers_not_supported) {
290  			format_modifiers = default_modifiers;
291  			format_modifier_count = ARRAY_SIZE(default_modifiers);
292  		}
293  	}
294  
295  	/* autoset the cap and check for consistency across all planes */
296  	drm_WARN_ON(dev, config->fb_modifiers_not_supported &&
297  				format_modifier_count);
298  
299  	plane->modifier_count = format_modifier_count;
300  	plane->modifiers = kmalloc_array(format_modifier_count,
301  					 sizeof(format_modifiers[0]),
302  					 GFP_KERNEL);
303  
304  	if (format_modifier_count && !plane->modifiers) {
305  		DRM_DEBUG_KMS("out of memory when allocating plane\n");
306  		kfree(plane->format_types);
307  		drm_mode_object_unregister(dev, &plane->base);
308  		return -ENOMEM;
309  	}
310  
311  	if (name) {
312  		plane->name = kvasprintf(GFP_KERNEL, name, ap);
313  	} else {
314  		plane->name = kasprintf(GFP_KERNEL, "plane-%d",
315  					drm_num_planes(dev));
316  	}
317  	if (!plane->name) {
318  		kfree(plane->format_types);
319  		kfree(plane->modifiers);
320  		drm_mode_object_unregister(dev, &plane->base);
321  		return -ENOMEM;
322  	}
323  
324  	memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
325  	plane->format_count = format_count;
326  	memcpy(plane->modifiers, format_modifiers,
327  	       format_modifier_count * sizeof(format_modifiers[0]));
328  	plane->possible_crtcs = possible_crtcs;
329  	plane->type = type;
330  
331  	list_add_tail(&plane->head, &config->plane_list);
332  	plane->index = config->num_total_plane++;
333  
334  	drm_object_attach_property(&plane->base,
335  				   config->plane_type_property,
336  				   plane->type);
337  
338  	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
339  		drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
340  		drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1);
341  		drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
342  		drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
343  		drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
344  		drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
345  		drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
346  		drm_object_attach_property(&plane->base, config->prop_src_x, 0);
347  		drm_object_attach_property(&plane->base, config->prop_src_y, 0);
348  		drm_object_attach_property(&plane->base, config->prop_src_w, 0);
349  		drm_object_attach_property(&plane->base, config->prop_src_h, 0);
350  	}
351  
352  	if (format_modifier_count)
353  		create_in_format_blob(dev, plane);
354  
355  	return 0;
356  }
357  
358  /**
359   * drm_universal_plane_init - Initialize a new universal plane object
360   * @dev: DRM device
361   * @plane: plane object to init
362   * @possible_crtcs: bitmask of possible CRTCs
363   * @funcs: callbacks for the new plane
364   * @formats: array of supported formats (DRM_FORMAT\_\*)
365   * @format_count: number of elements in @formats
366   * @format_modifiers: array of struct drm_format modifiers terminated by
367   *                    DRM_FORMAT_MOD_INVALID
368   * @type: type of plane (overlay, primary, cursor)
369   * @name: printf style format string for the plane name, or NULL for default name
370   *
371   * Initializes a plane object of type @type. The &drm_plane_funcs.destroy hook
372   * should call drm_plane_cleanup() and kfree() the plane structure. The plane
373   * structure should not be allocated with devm_kzalloc().
374   *
375   * Note: consider using drmm_universal_plane_alloc() instead of
376   * drm_universal_plane_init() to let the DRM managed resource infrastructure
377   * take care of cleanup and deallocation.
378   *
379   * Drivers that only support the DRM_FORMAT_MOD_LINEAR modifier support may set
380   * @format_modifiers to NULL. The plane will advertise the linear modifier.
381   *
382   * Returns:
383   * Zero on success, error code on failure.
384   */
drm_universal_plane_init(struct drm_device * dev,struct drm_plane * plane,uint32_t possible_crtcs,const struct drm_plane_funcs * funcs,const uint32_t * formats,unsigned int format_count,const uint64_t * format_modifiers,enum drm_plane_type type,const char * name,...)385  int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
386  			     uint32_t possible_crtcs,
387  			     const struct drm_plane_funcs *funcs,
388  			     const uint32_t *formats, unsigned int format_count,
389  			     const uint64_t *format_modifiers,
390  			     enum drm_plane_type type,
391  			     const char *name, ...)
392  {
393  	va_list ap;
394  	int ret;
395  
396  	WARN_ON(!funcs->destroy);
397  
398  	va_start(ap, name);
399  	ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
400  					 formats, format_count, format_modifiers,
401  					 type, name, ap);
402  	va_end(ap);
403  	return ret;
404  }
405  EXPORT_SYMBOL(drm_universal_plane_init);
406  
drmm_universal_plane_alloc_release(struct drm_device * dev,void * ptr)407  static void drmm_universal_plane_alloc_release(struct drm_device *dev, void *ptr)
408  {
409  	struct drm_plane *plane = ptr;
410  
411  	if (WARN_ON(!plane->dev))
412  		return;
413  
414  	drm_plane_cleanup(plane);
415  }
416  
__drmm_universal_plane_alloc(struct drm_device * dev,size_t size,size_t offset,uint32_t possible_crtcs,const struct drm_plane_funcs * funcs,const uint32_t * formats,unsigned int format_count,const uint64_t * format_modifiers,enum drm_plane_type type,const char * name,...)417  void *__drmm_universal_plane_alloc(struct drm_device *dev, size_t size,
418  				   size_t offset, uint32_t possible_crtcs,
419  				   const struct drm_plane_funcs *funcs,
420  				   const uint32_t *formats, unsigned int format_count,
421  				   const uint64_t *format_modifiers,
422  				   enum drm_plane_type type,
423  				   const char *name, ...)
424  {
425  	void *container;
426  	struct drm_plane *plane;
427  	va_list ap;
428  	int ret;
429  
430  	if (WARN_ON(!funcs || funcs->destroy))
431  		return ERR_PTR(-EINVAL);
432  
433  	container = drmm_kzalloc(dev, size, GFP_KERNEL);
434  	if (!container)
435  		return ERR_PTR(-ENOMEM);
436  
437  	plane = container + offset;
438  
439  	va_start(ap, name);
440  	ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
441  					 formats, format_count, format_modifiers,
442  					 type, name, ap);
443  	va_end(ap);
444  	if (ret)
445  		return ERR_PTR(ret);
446  
447  	ret = drmm_add_action_or_reset(dev, drmm_universal_plane_alloc_release,
448  				       plane);
449  	if (ret)
450  		return ERR_PTR(ret);
451  
452  	return container;
453  }
454  EXPORT_SYMBOL(__drmm_universal_plane_alloc);
455  
__drm_universal_plane_alloc(struct drm_device * dev,size_t size,size_t offset,uint32_t possible_crtcs,const struct drm_plane_funcs * funcs,const uint32_t * formats,unsigned int format_count,const uint64_t * format_modifiers,enum drm_plane_type type,const char * name,...)456  void *__drm_universal_plane_alloc(struct drm_device *dev, size_t size,
457  				  size_t offset, uint32_t possible_crtcs,
458  				  const struct drm_plane_funcs *funcs,
459  				  const uint32_t *formats, unsigned int format_count,
460  				  const uint64_t *format_modifiers,
461  				  enum drm_plane_type type,
462  				  const char *name, ...)
463  {
464  	void *container;
465  	struct drm_plane *plane;
466  	va_list ap;
467  	int ret;
468  
469  	if (drm_WARN_ON(dev, !funcs))
470  		return ERR_PTR(-EINVAL);
471  
472  	container = kzalloc(size, GFP_KERNEL);
473  	if (!container)
474  		return ERR_PTR(-ENOMEM);
475  
476  	plane = container + offset;
477  
478  	va_start(ap, name);
479  	ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
480  					 formats, format_count, format_modifiers,
481  					 type, name, ap);
482  	va_end(ap);
483  	if (ret)
484  		goto err_kfree;
485  
486  	return container;
487  
488  err_kfree:
489  	kfree(container);
490  	return ERR_PTR(ret);
491  }
492  EXPORT_SYMBOL(__drm_universal_plane_alloc);
493  
drm_plane_register_all(struct drm_device * dev)494  int drm_plane_register_all(struct drm_device *dev)
495  {
496  	unsigned int num_planes = 0;
497  	unsigned int num_zpos = 0;
498  	struct drm_plane *plane;
499  	int ret = 0;
500  
501  	drm_for_each_plane(plane, dev) {
502  		if (plane->funcs->late_register)
503  			ret = plane->funcs->late_register(plane);
504  		if (ret)
505  			return ret;
506  
507  		if (plane->zpos_property)
508  			num_zpos++;
509  		num_planes++;
510  	}
511  
512  	drm_WARN(dev, num_zpos && num_planes != num_zpos,
513  		 "Mixing planes with and without zpos property is invalid\n");
514  
515  	return 0;
516  }
517  
drm_plane_unregister_all(struct drm_device * dev)518  void drm_plane_unregister_all(struct drm_device *dev)
519  {
520  	struct drm_plane *plane;
521  
522  	drm_for_each_plane(plane, dev) {
523  		if (plane->funcs->early_unregister)
524  			plane->funcs->early_unregister(plane);
525  	}
526  }
527  
528  /**
529   * drm_plane_cleanup - Clean up the core plane usage
530   * @plane: plane to cleanup
531   *
532   * This function cleans up @plane and removes it from the DRM mode setting
533   * core. Note that the function does *not* free the plane structure itself,
534   * this is the responsibility of the caller.
535   */
drm_plane_cleanup(struct drm_plane * plane)536  void drm_plane_cleanup(struct drm_plane *plane)
537  {
538  	struct drm_device *dev = plane->dev;
539  
540  	drm_modeset_lock_fini(&plane->mutex);
541  
542  	kfree(plane->format_types);
543  	kfree(plane->modifiers);
544  	drm_mode_object_unregister(dev, &plane->base);
545  
546  	BUG_ON(list_empty(&plane->head));
547  
548  	/* Note that the plane_list is considered to be static; should we
549  	 * remove the drm_plane at runtime we would have to decrement all
550  	 * the indices on the drm_plane after us in the plane_list.
551  	 */
552  
553  	list_del(&plane->head);
554  	dev->mode_config.num_total_plane--;
555  
556  	WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
557  	if (plane->state && plane->funcs->atomic_destroy_state)
558  		plane->funcs->atomic_destroy_state(plane, plane->state);
559  
560  	kfree(plane->name);
561  
562  	memset(plane, 0, sizeof(*plane));
563  }
564  EXPORT_SYMBOL(drm_plane_cleanup);
565  
566  /**
567   * drm_plane_from_index - find the registered plane at an index
568   * @dev: DRM device
569   * @idx: index of registered plane to find for
570   *
571   * Given a plane index, return the registered plane from DRM device's
572   * list of planes with matching index. This is the inverse of drm_plane_index().
573   */
574  struct drm_plane *
drm_plane_from_index(struct drm_device * dev,int idx)575  drm_plane_from_index(struct drm_device *dev, int idx)
576  {
577  	struct drm_plane *plane;
578  
579  	drm_for_each_plane(plane, dev)
580  		if (idx == plane->index)
581  			return plane;
582  
583  	return NULL;
584  }
585  EXPORT_SYMBOL(drm_plane_from_index);
586  
587  /**
588   * drm_plane_force_disable - Forcibly disable a plane
589   * @plane: plane to disable
590   *
591   * Forces the plane to be disabled.
592   *
593   * Used when the plane's current framebuffer is destroyed,
594   * and when restoring fbdev mode.
595   *
596   * Note that this function is not suitable for atomic drivers, since it doesn't
597   * wire through the lock acquisition context properly and hence can't handle
598   * retries or driver private locks. You probably want to use
599   * drm_atomic_helper_disable_plane() or
600   * drm_atomic_helper_disable_planes_on_crtc() instead.
601   */
drm_plane_force_disable(struct drm_plane * plane)602  void drm_plane_force_disable(struct drm_plane *plane)
603  {
604  	int ret;
605  
606  	if (!plane->fb)
607  		return;
608  
609  	WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
610  
611  	plane->old_fb = plane->fb;
612  	ret = plane->funcs->disable_plane(plane, NULL);
613  	if (ret) {
614  		DRM_ERROR("failed to disable plane with busy fb\n");
615  		plane->old_fb = NULL;
616  		return;
617  	}
618  	/* disconnect the plane from the fb and crtc: */
619  	drm_framebuffer_put(plane->old_fb);
620  	plane->old_fb = NULL;
621  	plane->fb = NULL;
622  	plane->crtc = NULL;
623  }
624  EXPORT_SYMBOL(drm_plane_force_disable);
625  
626  /**
627   * drm_mode_plane_set_obj_prop - set the value of a property
628   * @plane: drm plane object to set property value for
629   * @property: property to set
630   * @value: value the property should be set to
631   *
632   * This functions sets a given property on a given plane object. This function
633   * calls the driver's ->set_property callback and changes the software state of
634   * the property if the callback succeeds.
635   *
636   * Returns:
637   * Zero on success, error code on failure.
638   */
drm_mode_plane_set_obj_prop(struct drm_plane * plane,struct drm_property * property,uint64_t value)639  int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
640  				struct drm_property *property,
641  				uint64_t value)
642  {
643  	int ret = -EINVAL;
644  	struct drm_mode_object *obj = &plane->base;
645  
646  	if (plane->funcs->set_property)
647  		ret = plane->funcs->set_property(plane, property, value);
648  	if (!ret)
649  		drm_object_property_set_value(obj, property, value);
650  
651  	return ret;
652  }
653  EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
654  
drm_mode_getplane_res(struct drm_device * dev,void * data,struct drm_file * file_priv)655  int drm_mode_getplane_res(struct drm_device *dev, void *data,
656  			  struct drm_file *file_priv)
657  {
658  	struct drm_mode_get_plane_res *plane_resp = data;
659  	struct drm_plane *plane;
660  	uint32_t __user *plane_ptr;
661  	int count = 0;
662  
663  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
664  		return -EOPNOTSUPP;
665  
666  	plane_ptr = u64_to_user_ptr(plane_resp->plane_id_ptr);
667  
668  	/*
669  	 * This ioctl is called twice, once to determine how much space is
670  	 * needed, and the 2nd time to fill it.
671  	 */
672  	drm_for_each_plane(plane, dev) {
673  		/*
674  		 * Unless userspace set the 'universal planes'
675  		 * capability bit, only advertise overlays.
676  		 */
677  		if (plane->type != DRM_PLANE_TYPE_OVERLAY &&
678  		    !file_priv->universal_planes)
679  			continue;
680  
681  		/*
682  		 * If we're running on a virtualized driver then,
683  		 * unless userspace advertizes support for the
684  		 * virtualized cursor plane, disable cursor planes
685  		 * because they'll be broken due to missing cursor
686  		 * hotspot info.
687  		 */
688  		if (plane->type == DRM_PLANE_TYPE_CURSOR &&
689  		    drm_core_check_feature(dev, DRIVER_CURSOR_HOTSPOT) &&
690  		    file_priv->atomic &&
691  		    !file_priv->supports_virtualized_cursor_plane)
692  			continue;
693  
694  		if (drm_lease_held(file_priv, plane->base.id)) {
695  			if (count < plane_resp->count_planes &&
696  			    put_user(plane->base.id, plane_ptr + count))
697  				return -EFAULT;
698  			count++;
699  		}
700  	}
701  	plane_resp->count_planes = count;
702  
703  	return 0;
704  }
705  
drm_mode_getplane(struct drm_device * dev,void * data,struct drm_file * file_priv)706  int drm_mode_getplane(struct drm_device *dev, void *data,
707  		      struct drm_file *file_priv)
708  {
709  	struct drm_mode_get_plane *plane_resp = data;
710  	struct drm_plane *plane;
711  	uint32_t __user *format_ptr;
712  
713  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
714  		return -EOPNOTSUPP;
715  
716  	plane = drm_plane_find(dev, file_priv, plane_resp->plane_id);
717  	if (!plane)
718  		return -ENOENT;
719  
720  	drm_modeset_lock(&plane->mutex, NULL);
721  	if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id))
722  		plane_resp->crtc_id = plane->state->crtc->base.id;
723  	else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id))
724  		plane_resp->crtc_id = plane->crtc->base.id;
725  	else
726  		plane_resp->crtc_id = 0;
727  
728  	if (plane->state && plane->state->fb)
729  		plane_resp->fb_id = plane->state->fb->base.id;
730  	else if (!plane->state && plane->fb)
731  		plane_resp->fb_id = plane->fb->base.id;
732  	else
733  		plane_resp->fb_id = 0;
734  	drm_modeset_unlock(&plane->mutex);
735  
736  	plane_resp->plane_id = plane->base.id;
737  	plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
738  							    plane->possible_crtcs);
739  
740  	plane_resp->gamma_size = 0;
741  
742  	/*
743  	 * This ioctl is called twice, once to determine how much space is
744  	 * needed, and the 2nd time to fill it.
745  	 */
746  	if (plane->format_count &&
747  	    (plane_resp->count_format_types >= plane->format_count)) {
748  		format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
749  		if (copy_to_user(format_ptr,
750  				 plane->format_types,
751  				 sizeof(uint32_t) * plane->format_count)) {
752  			return -EFAULT;
753  		}
754  	}
755  	plane_resp->count_format_types = plane->format_count;
756  
757  	return 0;
758  }
759  
drm_plane_check_pixel_format(struct drm_plane * plane,u32 format,u64 modifier)760  int drm_plane_check_pixel_format(struct drm_plane *plane,
761  				 u32 format, u64 modifier)
762  {
763  	unsigned int i;
764  
765  	for (i = 0; i < plane->format_count; i++) {
766  		if (format == plane->format_types[i])
767  			break;
768  	}
769  	if (i == plane->format_count)
770  		return -EINVAL;
771  
772  	if (plane->funcs->format_mod_supported) {
773  		if (!plane->funcs->format_mod_supported(plane, format, modifier))
774  			return -EINVAL;
775  	} else {
776  		if (!plane->modifier_count)
777  			return 0;
778  
779  		for (i = 0; i < plane->modifier_count; i++) {
780  			if (modifier == plane->modifiers[i])
781  				break;
782  		}
783  		if (i == plane->modifier_count)
784  			return -EINVAL;
785  	}
786  
787  	return 0;
788  }
789  
__setplane_check(struct drm_plane * plane,struct drm_crtc * crtc,struct drm_framebuffer * fb,int32_t crtc_x,int32_t crtc_y,uint32_t crtc_w,uint32_t crtc_h,uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h)790  static int __setplane_check(struct drm_plane *plane,
791  			    struct drm_crtc *crtc,
792  			    struct drm_framebuffer *fb,
793  			    int32_t crtc_x, int32_t crtc_y,
794  			    uint32_t crtc_w, uint32_t crtc_h,
795  			    uint32_t src_x, uint32_t src_y,
796  			    uint32_t src_w, uint32_t src_h)
797  {
798  	int ret;
799  
800  	/* Check whether this plane is usable on this CRTC */
801  	if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
802  		DRM_DEBUG_KMS("Invalid crtc for plane\n");
803  		return -EINVAL;
804  	}
805  
806  	/* Check whether this plane supports the fb pixel format. */
807  	ret = drm_plane_check_pixel_format(plane, fb->format->format,
808  					   fb->modifier);
809  	if (ret) {
810  		DRM_DEBUG_KMS("Invalid pixel format %p4cc, modifier 0x%llx\n",
811  			      &fb->format->format, fb->modifier);
812  		return ret;
813  	}
814  
815  	/* Give drivers some help against integer overflows */
816  	if (crtc_w > INT_MAX ||
817  	    crtc_x > INT_MAX - (int32_t) crtc_w ||
818  	    crtc_h > INT_MAX ||
819  	    crtc_y > INT_MAX - (int32_t) crtc_h) {
820  		DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
821  			      crtc_w, crtc_h, crtc_x, crtc_y);
822  		return -ERANGE;
823  	}
824  
825  	ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb);
826  	if (ret)
827  		return ret;
828  
829  	return 0;
830  }
831  
832  /**
833   * drm_any_plane_has_format - Check whether any plane supports this format and modifier combination
834   * @dev: DRM device
835   * @format: pixel format (DRM_FORMAT_*)
836   * @modifier: data layout modifier
837   *
838   * Returns:
839   * Whether at least one plane supports the specified format and modifier combination.
840   */
drm_any_plane_has_format(struct drm_device * dev,u32 format,u64 modifier)841  bool drm_any_plane_has_format(struct drm_device *dev,
842  			      u32 format, u64 modifier)
843  {
844  	struct drm_plane *plane;
845  
846  	drm_for_each_plane(plane, dev) {
847  		if (drm_plane_check_pixel_format(plane, format, modifier) == 0)
848  			return true;
849  	}
850  
851  	return false;
852  }
853  EXPORT_SYMBOL(drm_any_plane_has_format);
854  
855  /*
856   * __setplane_internal - setplane handler for internal callers
857   *
858   * This function will take a reference on the new fb for the plane
859   * on success.
860   *
861   * src_{x,y,w,h} are provided in 16.16 fixed point format
862   */
__setplane_internal(struct drm_plane * plane,struct drm_crtc * crtc,struct drm_framebuffer * fb,int32_t crtc_x,int32_t crtc_y,uint32_t crtc_w,uint32_t crtc_h,uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h,struct drm_modeset_acquire_ctx * ctx)863  static int __setplane_internal(struct drm_plane *plane,
864  			       struct drm_crtc *crtc,
865  			       struct drm_framebuffer *fb,
866  			       int32_t crtc_x, int32_t crtc_y,
867  			       uint32_t crtc_w, uint32_t crtc_h,
868  			       /* src_{x,y,w,h} values are 16.16 fixed point */
869  			       uint32_t src_x, uint32_t src_y,
870  			       uint32_t src_w, uint32_t src_h,
871  			       struct drm_modeset_acquire_ctx *ctx)
872  {
873  	int ret = 0;
874  
875  	WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
876  
877  	/* No fb means shut it down */
878  	if (!fb) {
879  		plane->old_fb = plane->fb;
880  		ret = plane->funcs->disable_plane(plane, ctx);
881  		if (!ret) {
882  			plane->crtc = NULL;
883  			plane->fb = NULL;
884  		} else {
885  			plane->old_fb = NULL;
886  		}
887  		goto out;
888  	}
889  
890  	ret = __setplane_check(plane, crtc, fb,
891  			       crtc_x, crtc_y, crtc_w, crtc_h,
892  			       src_x, src_y, src_w, src_h);
893  	if (ret)
894  		goto out;
895  
896  	plane->old_fb = plane->fb;
897  	ret = plane->funcs->update_plane(plane, crtc, fb,
898  					 crtc_x, crtc_y, crtc_w, crtc_h,
899  					 src_x, src_y, src_w, src_h, ctx);
900  	if (!ret) {
901  		plane->crtc = crtc;
902  		plane->fb = fb;
903  		drm_framebuffer_get(plane->fb);
904  	} else {
905  		plane->old_fb = NULL;
906  	}
907  
908  out:
909  	if (plane->old_fb)
910  		drm_framebuffer_put(plane->old_fb);
911  	plane->old_fb = NULL;
912  
913  	return ret;
914  }
915  
__setplane_atomic(struct drm_plane * plane,struct drm_crtc * crtc,struct drm_framebuffer * fb,int32_t crtc_x,int32_t crtc_y,uint32_t crtc_w,uint32_t crtc_h,uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h,struct drm_modeset_acquire_ctx * ctx)916  static int __setplane_atomic(struct drm_plane *plane,
917  			     struct drm_crtc *crtc,
918  			     struct drm_framebuffer *fb,
919  			     int32_t crtc_x, int32_t crtc_y,
920  			     uint32_t crtc_w, uint32_t crtc_h,
921  			     uint32_t src_x, uint32_t src_y,
922  			     uint32_t src_w, uint32_t src_h,
923  			     struct drm_modeset_acquire_ctx *ctx)
924  {
925  	int ret;
926  
927  	WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
928  
929  	/* No fb means shut it down */
930  	if (!fb)
931  		return plane->funcs->disable_plane(plane, ctx);
932  
933  	/*
934  	 * FIXME: This is redundant with drm_atomic_plane_check(),
935  	 * but the legacy cursor/"async" .update_plane() tricks
936  	 * don't call that so we still need this here. Should remove
937  	 * this when all .update_plane() implementations have been
938  	 * fixed to call drm_atomic_plane_check().
939  	 */
940  	ret = __setplane_check(plane, crtc, fb,
941  			       crtc_x, crtc_y, crtc_w, crtc_h,
942  			       src_x, src_y, src_w, src_h);
943  	if (ret)
944  		return ret;
945  
946  	return plane->funcs->update_plane(plane, crtc, fb,
947  					  crtc_x, crtc_y, crtc_w, crtc_h,
948  					  src_x, src_y, src_w, src_h, ctx);
949  }
950  
setplane_internal(struct drm_plane * plane,struct drm_crtc * crtc,struct drm_framebuffer * fb,int32_t crtc_x,int32_t crtc_y,uint32_t crtc_w,uint32_t crtc_h,uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h)951  static int setplane_internal(struct drm_plane *plane,
952  			     struct drm_crtc *crtc,
953  			     struct drm_framebuffer *fb,
954  			     int32_t crtc_x, int32_t crtc_y,
955  			     uint32_t crtc_w, uint32_t crtc_h,
956  			     /* src_{x,y,w,h} values are 16.16 fixed point */
957  			     uint32_t src_x, uint32_t src_y,
958  			     uint32_t src_w, uint32_t src_h)
959  {
960  	struct drm_modeset_acquire_ctx ctx;
961  	int ret;
962  
963  	DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx,
964  				   DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
965  
966  	if (drm_drv_uses_atomic_modeset(plane->dev))
967  		ret = __setplane_atomic(plane, crtc, fb,
968  					crtc_x, crtc_y, crtc_w, crtc_h,
969  					src_x, src_y, src_w, src_h, &ctx);
970  	else
971  		ret = __setplane_internal(plane, crtc, fb,
972  					  crtc_x, crtc_y, crtc_w, crtc_h,
973  					  src_x, src_y, src_w, src_h, &ctx);
974  
975  	DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret);
976  
977  	return ret;
978  }
979  
drm_mode_setplane(struct drm_device * dev,void * data,struct drm_file * file_priv)980  int drm_mode_setplane(struct drm_device *dev, void *data,
981  		      struct drm_file *file_priv)
982  {
983  	struct drm_mode_set_plane *plane_req = data;
984  	struct drm_plane *plane;
985  	struct drm_crtc *crtc = NULL;
986  	struct drm_framebuffer *fb = NULL;
987  	int ret;
988  
989  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
990  		return -EOPNOTSUPP;
991  
992  	/*
993  	 * First, find the plane, crtc, and fb objects.  If not available,
994  	 * we don't bother to call the driver.
995  	 */
996  	plane = drm_plane_find(dev, file_priv, plane_req->plane_id);
997  	if (!plane) {
998  		DRM_DEBUG_KMS("Unknown plane ID %d\n",
999  			      plane_req->plane_id);
1000  		return -ENOENT;
1001  	}
1002  
1003  	if (plane_req->fb_id) {
1004  		fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id);
1005  		if (!fb) {
1006  			DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
1007  				      plane_req->fb_id);
1008  			return -ENOENT;
1009  		}
1010  
1011  		crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id);
1012  		if (!crtc) {
1013  			drm_framebuffer_put(fb);
1014  			DRM_DEBUG_KMS("Unknown crtc ID %d\n",
1015  				      plane_req->crtc_id);
1016  			return -ENOENT;
1017  		}
1018  	}
1019  
1020  	ret = setplane_internal(plane, crtc, fb,
1021  				plane_req->crtc_x, plane_req->crtc_y,
1022  				plane_req->crtc_w, plane_req->crtc_h,
1023  				plane_req->src_x, plane_req->src_y,
1024  				plane_req->src_w, plane_req->src_h);
1025  
1026  	if (fb)
1027  		drm_framebuffer_put(fb);
1028  
1029  	return ret;
1030  }
1031  
drm_mode_cursor_universal(struct drm_crtc * crtc,struct drm_mode_cursor2 * req,struct drm_file * file_priv,struct drm_modeset_acquire_ctx * ctx)1032  static int drm_mode_cursor_universal(struct drm_crtc *crtc,
1033  				     struct drm_mode_cursor2 *req,
1034  				     struct drm_file *file_priv,
1035  				     struct drm_modeset_acquire_ctx *ctx)
1036  {
1037  	struct drm_device *dev = crtc->dev;
1038  	struct drm_plane *plane = crtc->cursor;
1039  	struct drm_framebuffer *fb = NULL;
1040  	struct drm_mode_fb_cmd2 fbreq = {
1041  		.width = req->width,
1042  		.height = req->height,
1043  		.pixel_format = DRM_FORMAT_ARGB8888,
1044  		.pitches = { req->width * 4 },
1045  		.handles = { req->handle },
1046  	};
1047  	int32_t crtc_x, crtc_y;
1048  	uint32_t crtc_w = 0, crtc_h = 0;
1049  	uint32_t src_w = 0, src_h = 0;
1050  	int ret = 0;
1051  
1052  	BUG_ON(!plane);
1053  	WARN_ON(plane->crtc != crtc && plane->crtc != NULL);
1054  
1055  	/*
1056  	 * Obtain fb we'll be using (either new or existing) and take an extra
1057  	 * reference to it if fb != null.  setplane will take care of dropping
1058  	 * the reference if the plane update fails.
1059  	 */
1060  	if (req->flags & DRM_MODE_CURSOR_BO) {
1061  		if (req->handle) {
1062  			fb = drm_internal_framebuffer_create(dev, &fbreq, file_priv);
1063  			if (IS_ERR(fb)) {
1064  				DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
1065  				return PTR_ERR(fb);
1066  			}
1067  
1068  			fb->hot_x = req->hot_x;
1069  			fb->hot_y = req->hot_y;
1070  		} else {
1071  			fb = NULL;
1072  		}
1073  	} else {
1074  		if (plane->state)
1075  			fb = plane->state->fb;
1076  		else
1077  			fb = plane->fb;
1078  
1079  		if (fb)
1080  			drm_framebuffer_get(fb);
1081  	}
1082  
1083  	if (req->flags & DRM_MODE_CURSOR_MOVE) {
1084  		crtc_x = req->x;
1085  		crtc_y = req->y;
1086  	} else {
1087  		crtc_x = crtc->cursor_x;
1088  		crtc_y = crtc->cursor_y;
1089  	}
1090  
1091  	if (fb) {
1092  		crtc_w = fb->width;
1093  		crtc_h = fb->height;
1094  		src_w = fb->width << 16;
1095  		src_h = fb->height << 16;
1096  	}
1097  
1098  	if (drm_drv_uses_atomic_modeset(dev))
1099  		ret = __setplane_atomic(plane, crtc, fb,
1100  					crtc_x, crtc_y, crtc_w, crtc_h,
1101  					0, 0, src_w, src_h, ctx);
1102  	else
1103  		ret = __setplane_internal(plane, crtc, fb,
1104  					  crtc_x, crtc_y, crtc_w, crtc_h,
1105  					  0, 0, src_w, src_h, ctx);
1106  
1107  	if (fb)
1108  		drm_framebuffer_put(fb);
1109  
1110  	/* Update successful; save new cursor position, if necessary */
1111  	if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) {
1112  		crtc->cursor_x = req->x;
1113  		crtc->cursor_y = req->y;
1114  	}
1115  
1116  	return ret;
1117  }
1118  
drm_mode_cursor_common(struct drm_device * dev,struct drm_mode_cursor2 * req,struct drm_file * file_priv)1119  static int drm_mode_cursor_common(struct drm_device *dev,
1120  				  struct drm_mode_cursor2 *req,
1121  				  struct drm_file *file_priv)
1122  {
1123  	struct drm_crtc *crtc;
1124  	struct drm_modeset_acquire_ctx ctx;
1125  	int ret = 0;
1126  
1127  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1128  		return -EOPNOTSUPP;
1129  
1130  	if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
1131  		return -EINVAL;
1132  
1133  	crtc = drm_crtc_find(dev, file_priv, req->crtc_id);
1134  	if (!crtc) {
1135  		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
1136  		return -ENOENT;
1137  	}
1138  
1139  	drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
1140  retry:
1141  	ret = drm_modeset_lock(&crtc->mutex, &ctx);
1142  	if (ret)
1143  		goto out;
1144  	/*
1145  	 * If this crtc has a universal cursor plane, call that plane's update
1146  	 * handler rather than using legacy cursor handlers.
1147  	 */
1148  	if (crtc->cursor) {
1149  		ret = drm_modeset_lock(&crtc->cursor->mutex, &ctx);
1150  		if (ret)
1151  			goto out;
1152  
1153  		if (!drm_lease_held(file_priv, crtc->cursor->base.id)) {
1154  			ret = -EACCES;
1155  			goto out;
1156  		}
1157  
1158  		ret = drm_mode_cursor_universal(crtc, req, file_priv, &ctx);
1159  		goto out;
1160  	}
1161  
1162  	if (req->flags & DRM_MODE_CURSOR_BO) {
1163  		if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
1164  			ret = -ENXIO;
1165  			goto out;
1166  		}
1167  		/* Turns off the cursor if handle is 0 */
1168  		if (crtc->funcs->cursor_set2)
1169  			ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
1170  						      req->width, req->height, req->hot_x, req->hot_y);
1171  		else
1172  			ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
1173  						      req->width, req->height);
1174  	}
1175  
1176  	if (req->flags & DRM_MODE_CURSOR_MOVE) {
1177  		if (crtc->funcs->cursor_move) {
1178  			ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
1179  		} else {
1180  			ret = -EFAULT;
1181  			goto out;
1182  		}
1183  	}
1184  out:
1185  	if (ret == -EDEADLK) {
1186  		ret = drm_modeset_backoff(&ctx);
1187  		if (!ret)
1188  			goto retry;
1189  	}
1190  
1191  	drm_modeset_drop_locks(&ctx);
1192  	drm_modeset_acquire_fini(&ctx);
1193  
1194  	return ret;
1195  
1196  }
1197  
1198  
drm_mode_cursor_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1199  int drm_mode_cursor_ioctl(struct drm_device *dev,
1200  			  void *data, struct drm_file *file_priv)
1201  {
1202  	struct drm_mode_cursor *req = data;
1203  	struct drm_mode_cursor2 new_req;
1204  
1205  	memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
1206  	new_req.hot_x = new_req.hot_y = 0;
1207  
1208  	return drm_mode_cursor_common(dev, &new_req, file_priv);
1209  }
1210  
1211  /*
1212   * Set the cursor configuration based on user request. This implements the 2nd
1213   * version of the cursor ioctl, which allows userspace to additionally specify
1214   * the hotspot of the pointer.
1215   */
drm_mode_cursor2_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1216  int drm_mode_cursor2_ioctl(struct drm_device *dev,
1217  			   void *data, struct drm_file *file_priv)
1218  {
1219  	struct drm_mode_cursor2 *req = data;
1220  
1221  	return drm_mode_cursor_common(dev, req, file_priv);
1222  }
1223  
drm_mode_page_flip_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1224  int drm_mode_page_flip_ioctl(struct drm_device *dev,
1225  			     void *data, struct drm_file *file_priv)
1226  {
1227  	struct drm_mode_crtc_page_flip_target *page_flip = data;
1228  	struct drm_crtc *crtc;
1229  	struct drm_plane *plane;
1230  	struct drm_framebuffer *fb = NULL, *old_fb;
1231  	struct drm_pending_vblank_event *e = NULL;
1232  	u32 target_vblank = page_flip->sequence;
1233  	struct drm_modeset_acquire_ctx ctx;
1234  	int ret = -EINVAL;
1235  
1236  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1237  		return -EOPNOTSUPP;
1238  
1239  	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS)
1240  		return -EINVAL;
1241  
1242  	if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET))
1243  		return -EINVAL;
1244  
1245  	/* Only one of the DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags
1246  	 * can be specified
1247  	 */
1248  	if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET)
1249  		return -EINVAL;
1250  
1251  	if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
1252  		return -EINVAL;
1253  
1254  	crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id);
1255  	if (!crtc)
1256  		return -ENOENT;
1257  
1258  	plane = crtc->primary;
1259  
1260  	if (!drm_lease_held(file_priv, plane->base.id))
1261  		return -EACCES;
1262  
1263  	if (crtc->funcs->page_flip_target) {
1264  		u32 current_vblank;
1265  		int r;
1266  
1267  		r = drm_crtc_vblank_get(crtc);
1268  		if (r)
1269  			return r;
1270  
1271  		current_vblank = (u32)drm_crtc_vblank_count(crtc);
1272  
1273  		switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) {
1274  		case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE:
1275  			if ((int)(target_vblank - current_vblank) > 1) {
1276  				DRM_DEBUG("Invalid absolute flip target %u, "
1277  					  "must be <= %u\n", target_vblank,
1278  					  current_vblank + 1);
1279  				drm_crtc_vblank_put(crtc);
1280  				return -EINVAL;
1281  			}
1282  			break;
1283  		case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE:
1284  			if (target_vblank != 0 && target_vblank != 1) {
1285  				DRM_DEBUG("Invalid relative flip target %u, "
1286  					  "must be 0 or 1\n", target_vblank);
1287  				drm_crtc_vblank_put(crtc);
1288  				return -EINVAL;
1289  			}
1290  			target_vblank += current_vblank;
1291  			break;
1292  		default:
1293  			target_vblank = current_vblank +
1294  				!(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC);
1295  			break;
1296  		}
1297  	} else if (crtc->funcs->page_flip == NULL ||
1298  		   (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) {
1299  		return -EINVAL;
1300  	}
1301  
1302  	drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
1303  retry:
1304  	ret = drm_modeset_lock(&crtc->mutex, &ctx);
1305  	if (ret)
1306  		goto out;
1307  	ret = drm_modeset_lock(&plane->mutex, &ctx);
1308  	if (ret)
1309  		goto out;
1310  
1311  	if (plane->state)
1312  		old_fb = plane->state->fb;
1313  	else
1314  		old_fb = plane->fb;
1315  
1316  	if (old_fb == NULL) {
1317  		/* The framebuffer is currently unbound, presumably
1318  		 * due to a hotplug event, that userspace has not
1319  		 * yet discovered.
1320  		 */
1321  		ret = -EBUSY;
1322  		goto out;
1323  	}
1324  
1325  	fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
1326  	if (!fb) {
1327  		ret = -ENOENT;
1328  		goto out;
1329  	}
1330  
1331  	if (plane->state) {
1332  		const struct drm_plane_state *state = plane->state;
1333  
1334  		ret = drm_framebuffer_check_src_coords(state->src_x,
1335  						       state->src_y,
1336  						       state->src_w,
1337  						       state->src_h,
1338  						       fb);
1339  	} else {
1340  		ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y,
1341  					      &crtc->mode, fb);
1342  	}
1343  	if (ret)
1344  		goto out;
1345  
1346  	/*
1347  	 * Only check the FOURCC format code, excluding modifiers. This is
1348  	 * enough for all legacy drivers. Atomic drivers have their own
1349  	 * checks in their ->atomic_check implementation, which will
1350  	 * return -EINVAL if any hw or driver constraint is violated due
1351  	 * to modifier changes.
1352  	 */
1353  	if (old_fb->format->format != fb->format->format) {
1354  		DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
1355  		ret = -EINVAL;
1356  		goto out;
1357  	}
1358  
1359  	if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
1360  		e = kzalloc(sizeof *e, GFP_KERNEL);
1361  		if (!e) {
1362  			ret = -ENOMEM;
1363  			goto out;
1364  		}
1365  
1366  		e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
1367  		e->event.base.length = sizeof(e->event);
1368  		e->event.vbl.user_data = page_flip->user_data;
1369  		e->event.vbl.crtc_id = crtc->base.id;
1370  
1371  		ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
1372  		if (ret) {
1373  			kfree(e);
1374  			e = NULL;
1375  			goto out;
1376  		}
1377  	}
1378  
1379  	plane->old_fb = plane->fb;
1380  	if (crtc->funcs->page_flip_target)
1381  		ret = crtc->funcs->page_flip_target(crtc, fb, e,
1382  						    page_flip->flags,
1383  						    target_vblank,
1384  						    &ctx);
1385  	else
1386  		ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags,
1387  					     &ctx);
1388  	if (ret) {
1389  		if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
1390  			drm_event_cancel_free(dev, &e->base);
1391  		/* Keep the old fb, don't unref it. */
1392  		plane->old_fb = NULL;
1393  	} else {
1394  		if (!plane->state) {
1395  			plane->fb = fb;
1396  			drm_framebuffer_get(fb);
1397  		}
1398  	}
1399  
1400  out:
1401  	if (fb)
1402  		drm_framebuffer_put(fb);
1403  	fb = NULL;
1404  	if (plane->old_fb)
1405  		drm_framebuffer_put(plane->old_fb);
1406  	plane->old_fb = NULL;
1407  
1408  	if (ret == -EDEADLK) {
1409  		ret = drm_modeset_backoff(&ctx);
1410  		if (!ret)
1411  			goto retry;
1412  	}
1413  
1414  	drm_modeset_drop_locks(&ctx);
1415  	drm_modeset_acquire_fini(&ctx);
1416  
1417  	if (ret && crtc->funcs->page_flip_target)
1418  		drm_crtc_vblank_put(crtc);
1419  
1420  	return ret;
1421  }
1422  
1423  /**
1424   * DOC: damage tracking
1425   *
1426   * FB_DAMAGE_CLIPS is an optional plane property which provides a means to
1427   * specify a list of damage rectangles on a plane in framebuffer coordinates of
1428   * the framebuffer attached to the plane. In current context damage is the area
1429   * of plane framebuffer that has changed since last plane update (also called
1430   * page-flip), irrespective of whether currently attached framebuffer is same as
1431   * framebuffer attached during last plane update or not.
1432   *
1433   * FB_DAMAGE_CLIPS is a hint to kernel which could be helpful for some drivers
1434   * to optimize internally especially for virtual devices where each framebuffer
1435   * change needs to be transmitted over network, usb, etc.
1436   *
1437   * Since FB_DAMAGE_CLIPS is a hint so it is an optional property. User-space can
1438   * ignore damage clips property and in that case driver will do a full plane
1439   * update. In case damage clips are provided then it is guaranteed that the area
1440   * inside damage clips will be updated to plane. For efficiency driver can do
1441   * full update or can update more than specified in damage clips. Since driver
1442   * is free to read more, user-space must always render the entire visible
1443   * framebuffer. Otherwise there can be corruptions. Also, if a user-space
1444   * provides damage clips which doesn't encompass the actual damage to
1445   * framebuffer (since last plane update) can result in incorrect rendering.
1446   *
1447   * FB_DAMAGE_CLIPS is a blob property with the layout of blob data is simply an
1448   * array of &drm_mode_rect. Unlike plane &drm_plane_state.src coordinates,
1449   * damage clips are not in 16.16 fixed point. Similar to plane src in
1450   * framebuffer, damage clips cannot be negative. In damage clip, x1/y1 are
1451   * inclusive and x2/y2 are exclusive. While kernel does not error for overlapped
1452   * damage clips, it is strongly discouraged.
1453   *
1454   * Drivers that are interested in damage interface for plane should enable
1455   * FB_DAMAGE_CLIPS property by calling drm_plane_enable_fb_damage_clips().
1456   * Drivers implementing damage can use drm_atomic_helper_damage_iter_init() and
1457   * drm_atomic_helper_damage_iter_next() helper iterator function to get damage
1458   * rectangles clipped to &drm_plane_state.src.
1459   */
1460  
1461  /**
1462   * drm_plane_enable_fb_damage_clips - Enables plane fb damage clips property.
1463   * @plane: Plane on which to enable damage clips property.
1464   *
1465   * This function lets driver to enable the damage clips property on a plane.
1466   */
drm_plane_enable_fb_damage_clips(struct drm_plane * plane)1467  void drm_plane_enable_fb_damage_clips(struct drm_plane *plane)
1468  {
1469  	struct drm_device *dev = plane->dev;
1470  	struct drm_mode_config *config = &dev->mode_config;
1471  
1472  	drm_object_attach_property(&plane->base, config->prop_fb_damage_clips,
1473  				   0);
1474  }
1475  EXPORT_SYMBOL(drm_plane_enable_fb_damage_clips);
1476  
1477  /**
1478   * drm_plane_get_damage_clips_count - Returns damage clips count.
1479   * @state: Plane state.
1480   *
1481   * Simple helper to get the number of &drm_mode_rect clips set by user-space
1482   * during plane update.
1483   *
1484   * Return: Number of clips in plane fb_damage_clips blob property.
1485   */
1486  unsigned int
drm_plane_get_damage_clips_count(const struct drm_plane_state * state)1487  drm_plane_get_damage_clips_count(const struct drm_plane_state *state)
1488  {
1489  	return (state && state->fb_damage_clips) ?
1490  		state->fb_damage_clips->length/sizeof(struct drm_mode_rect) : 0;
1491  }
1492  EXPORT_SYMBOL(drm_plane_get_damage_clips_count);
1493  
1494  struct drm_mode_rect *
__drm_plane_get_damage_clips(const struct drm_plane_state * state)1495  __drm_plane_get_damage_clips(const struct drm_plane_state *state)
1496  {
1497  	return (struct drm_mode_rect *)((state && state->fb_damage_clips) ?
1498  					state->fb_damage_clips->data : NULL);
1499  }
1500  
1501  /**
1502   * drm_plane_get_damage_clips - Returns damage clips.
1503   * @state: Plane state.
1504   *
1505   * Note that this function returns uapi type &drm_mode_rect. Drivers might want
1506   * to use the helper functions drm_atomic_helper_damage_iter_init() and
1507   * drm_atomic_helper_damage_iter_next() or drm_atomic_helper_damage_merged() if
1508   * the driver can only handle a single damage region at most.
1509   *
1510   * Return: Damage clips in plane fb_damage_clips blob property.
1511   */
1512  struct drm_mode_rect *
drm_plane_get_damage_clips(const struct drm_plane_state * state)1513  drm_plane_get_damage_clips(const struct drm_plane_state *state)
1514  {
1515  	struct drm_device *dev = state->plane->dev;
1516  	struct drm_mode_config *config = &dev->mode_config;
1517  
1518  	/* check that drm_plane_enable_fb_damage_clips() was called */
1519  	if (!drm_mode_obj_find_prop_id(&state->plane->base,
1520  				       config->prop_fb_damage_clips->base.id))
1521  		drm_warn_once(dev, "drm_plane_enable_fb_damage_clips() not called\n");
1522  
1523  	return __drm_plane_get_damage_clips(state);
1524  }
1525  EXPORT_SYMBOL(drm_plane_get_damage_clips);
1526  
1527  struct drm_property *
drm_create_scaling_filter_prop(struct drm_device * dev,unsigned int supported_filters)1528  drm_create_scaling_filter_prop(struct drm_device *dev,
1529  			       unsigned int supported_filters)
1530  {
1531  	struct drm_property *prop;
1532  	static const struct drm_prop_enum_list props[] = {
1533  		{ DRM_SCALING_FILTER_DEFAULT, "Default" },
1534  		{ DRM_SCALING_FILTER_NEAREST_NEIGHBOR, "Nearest Neighbor" },
1535  	};
1536  	unsigned int valid_mode_mask = BIT(DRM_SCALING_FILTER_DEFAULT) |
1537  				       BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
1538  	int i;
1539  
1540  	if (WARN_ON((supported_filters & ~valid_mode_mask) ||
1541  		    ((supported_filters & BIT(DRM_SCALING_FILTER_DEFAULT)) == 0)))
1542  		return ERR_PTR(-EINVAL);
1543  
1544  	prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
1545  				   "SCALING_FILTER",
1546  				   hweight32(supported_filters));
1547  	if (!prop)
1548  		return ERR_PTR(-ENOMEM);
1549  
1550  	for (i = 0; i < ARRAY_SIZE(props); i++) {
1551  		int ret;
1552  
1553  		if (!(BIT(props[i].type) & supported_filters))
1554  			continue;
1555  
1556  		ret = drm_property_add_enum(prop, props[i].type,
1557  					    props[i].name);
1558  
1559  		if (ret) {
1560  			drm_property_destroy(dev, prop);
1561  
1562  			return ERR_PTR(ret);
1563  		}
1564  	}
1565  
1566  	return prop;
1567  }
1568  
1569  /**
1570   * drm_plane_create_scaling_filter_property - create a new scaling filter
1571   * property
1572   *
1573   * @plane: drm plane
1574   * @supported_filters: bitmask of supported scaling filters, must include
1575   *		       BIT(DRM_SCALING_FILTER_DEFAULT).
1576   *
1577   * This function lets driver to enable the scaling filter property on a given
1578   * plane.
1579   *
1580   * RETURNS:
1581   * Zero for success or -errno
1582   */
drm_plane_create_scaling_filter_property(struct drm_plane * plane,unsigned int supported_filters)1583  int drm_plane_create_scaling_filter_property(struct drm_plane *plane,
1584  					     unsigned int supported_filters)
1585  {
1586  	struct drm_property *prop =
1587  		drm_create_scaling_filter_prop(plane->dev, supported_filters);
1588  
1589  	if (IS_ERR(prop))
1590  		return PTR_ERR(prop);
1591  
1592  	drm_object_attach_property(&plane->base, prop,
1593  				   DRM_SCALING_FILTER_DEFAULT);
1594  	plane->scaling_filter_property = prop;
1595  
1596  	return 0;
1597  }
1598  EXPORT_SYMBOL(drm_plane_create_scaling_filter_property);
1599