Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  * Copyright (c) 2016 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Permission to use, copy, modify, distribute, and sell this software and its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * documentation for any purpose is hereby granted without fee, provided that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * the above copyright notice appear in all copies and that both that copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * notice and this permission notice appear in supporting documentation, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * that the name of the copyright holders not be used in advertising or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * publicity pertaining to distribution of the software without specific,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * written prior permission.  The copyright holders make no representations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * about the suitability of this software for any purpose.  It is provided "as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * is" without express or implied warranty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * OF THIS SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <drm/drm_plane.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <drm/drm_drv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <drm/drm_print.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <drm/drm_framebuffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <drm/drm_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <drm/drm_crtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <drm/drm_fourcc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <drm/drm_vblank.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include "drm_crtc_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  * DOC: overview
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  * A plane represents an image source that can be blended with or overlayed on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  * top of a CRTC during the scanout process. Planes take their input data from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  * &drm_framebuffer object. The plane itself specifies the cropping and scaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  * of that image, and where it is placed on the visible are of a display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  * pipeline, represented by &drm_crtc. A plane can also have additional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  * properties that specify how the pixels are positioned and blended, like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  * rotation or Z-position. All these properties are stored in &drm_plane_state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  * To create a plane, a KMS drivers allocates and zeroes an instances of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  * &struct drm_plane (possibly as part of a larger structure) and registers it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50)  * with a call to drm_universal_plane_init().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52)  * Cursor and overlay planes are optional. All drivers should provide one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53)  * primary plane per CRTC to avoid surprising userspace too much. See enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54)  * drm_plane_type for a more in-depth discussion of these special uapi-relevant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  * plane types. Special planes are associated with their CRTC by calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  * drm_crtc_init_with_planes().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58)  * The type of a plane is exposed in the immutable "type" enumeration property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59)  * which has one of the following values: "Overlay", "Primary", "Cursor".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) static unsigned int drm_num_planes(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	unsigned int num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	struct drm_plane *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	drm_for_each_plane(tmp, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 		num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) static inline u32 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) formats_ptr(struct drm_format_modifier_blob *blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	return (u32 *)(((char *)blob) + blob->formats_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) static inline struct drm_format_modifier *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) modifiers_ptr(struct drm_format_modifier_blob *blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	const struct drm_mode_config *config = &dev->mode_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	struct drm_property_blob *blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	struct drm_format_modifier *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	size_t blob_size, formats_size, modifiers_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	struct drm_format_modifier_blob *blob_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	formats_size = sizeof(__u32) * plane->format_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	if (WARN_ON(!formats_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 		/* 0 formats are never expected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	modifiers_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		sizeof(struct drm_format_modifier) * plane->modifier_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	blob_size = sizeof(struct drm_format_modifier_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	/* Modifiers offset is a pointer to a struct with a 64 bit field so it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	 * should be naturally aligned to 8B.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	blob_size += ALIGN(formats_size, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	blob_size += modifiers_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	blob = drm_property_create_blob(dev, blob_size, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	if (IS_ERR(blob))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	blob_data = blob->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	blob_data->version = FORMAT_BLOB_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	blob_data->count_formats = plane->format_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	blob_data->count_modifiers = plane->modifier_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	blob_data->modifiers_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		ALIGN(blob_data->formats_offset + formats_size, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	/* If we can't determine support, just bail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	if (!plane->funcs->format_mod_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	mod = modifiers_ptr(blob_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	for (i = 0; i < plane->modifier_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		for (j = 0; j < plane->format_count; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 			if (plane->funcs->format_mod_supported(plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 							       plane->format_types[j],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 							       plane->modifiers[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 				mod->formats |= 1ULL << j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		mod->modifier = plane->modifiers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		mod->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		mod->pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		mod++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	drm_object_attach_property(&plane->base, config->modifiers_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 				   blob->base.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * drm_universal_plane_init - Initialize a new universal plane object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  * @plane: plane object to init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  * @possible_crtcs: bitmask of possible CRTCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  * @funcs: callbacks for the new plane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161)  * @formats: array of supported formats (DRM_FORMAT\_\*)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162)  * @format_count: number of elements in @formats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163)  * @format_modifiers: array of struct drm_format modifiers terminated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164)  *                    DRM_FORMAT_MOD_INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165)  * @type: type of plane (overlay, primary, cursor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  * @name: printf style format string for the plane name, or NULL for default name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * Initializes a plane object of type @type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  * Zero on success, error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 			     uint32_t possible_crtcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			     const struct drm_plane_funcs *funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 			     const uint32_t *formats, unsigned int format_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			     const uint64_t *format_modifiers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 			     enum drm_plane_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 			     const char *name, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	struct drm_mode_config *config = &dev->mode_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	unsigned int format_modifier_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	/* plane index is used with 32bit bitmasks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	if (WARN_ON(config->num_total_plane >= 32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		(!funcs->atomic_destroy_state ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		 !funcs->atomic_duplicate_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	drm_modeset_lock_init(&plane->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	plane->base.properties = &plane->properties;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	plane->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	plane->funcs = funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 					    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (!plane->format_types) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		DRM_DEBUG_KMS("out of memory when allocating plane\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		drm_mode_object_unregister(dev, &plane->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	 * First driver to need more than 64 formats needs to fix this. Each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	 * format is encoded as a bit and the current code only supports a u64.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	if (WARN_ON(format_count > 64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	if (format_modifiers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		const uint64_t *temp_modifiers = format_modifiers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 			format_modifier_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	if (format_modifier_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		config->allow_fb_modifiers = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	plane->modifier_count = format_modifier_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	plane->modifiers = kmalloc_array(format_modifier_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 					 sizeof(format_modifiers[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 					 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	if (format_modifier_count && !plane->modifiers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		DRM_DEBUG_KMS("out of memory when allocating plane\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		kfree(plane->format_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		drm_mode_object_unregister(dev, &plane->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	if (name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		va_start(ap, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		plane->name = kvasprintf(GFP_KERNEL, name, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		plane->name = kasprintf(GFP_KERNEL, "plane-%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 					drm_num_planes(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	if (!plane->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		kfree(plane->format_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		kfree(plane->modifiers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		drm_mode_object_unregister(dev, &plane->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	plane->format_count = format_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	memcpy(plane->modifiers, format_modifiers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	       format_modifier_count * sizeof(format_modifiers[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	plane->possible_crtcs = possible_crtcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	plane->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	list_add_tail(&plane->head, &config->plane_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	plane->index = config->num_total_plane++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	drm_object_attach_property(&plane->base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 				   config->plane_type_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 				   plane->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		drm_object_attach_property(&plane->base, config->prop_src_x, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		drm_object_attach_property(&plane->base, config->prop_src_y, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		drm_object_attach_property(&plane->base, config->prop_src_w, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		drm_object_attach_property(&plane->base, config->prop_src_h, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	if (config->allow_fb_modifiers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		create_in_format_blob(dev, plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) EXPORT_SYMBOL(drm_universal_plane_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) int drm_plane_register_all(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	unsigned int num_planes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	unsigned int num_zpos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	struct drm_plane *plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	drm_for_each_plane(plane, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		if (plane->funcs->late_register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 			ret = plane->funcs->late_register(plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		if (plane->zpos_property)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 			num_zpos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		num_planes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	drm_WARN(dev, num_zpos && num_planes != num_zpos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		 "Mixing planes with and without zpos property is invalid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) void drm_plane_unregister_all(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	struct drm_plane *plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	drm_for_each_plane(plane, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		if (plane->funcs->early_unregister)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 			plane->funcs->early_unregister(plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326)  * drm_plane_init - Initialize a legacy plane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327)  * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328)  * @plane: plane object to init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329)  * @possible_crtcs: bitmask of possible CRTCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330)  * @funcs: callbacks for the new plane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331)  * @formats: array of supported formats (DRM_FORMAT\_\*)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332)  * @format_count: number of elements in @formats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333)  * @is_primary: plane type (primary vs overlay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335)  * Legacy API to initialize a DRM plane.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337)  * New drivers should call drm_universal_plane_init() instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340)  * Zero on success, error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		   uint32_t possible_crtcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		   const struct drm_plane_funcs *funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		   const uint32_t *formats, unsigned int format_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		   bool is_primary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	enum drm_plane_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 					formats, format_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 					NULL, type, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) EXPORT_SYMBOL(drm_plane_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358)  * drm_plane_cleanup - Clean up the core plane usage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359)  * @plane: plane to cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361)  * This function cleans up @plane and removes it from the DRM mode setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  * core. Note that the function does *not* free the plane structure itself,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  * this is the responsibility of the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) void drm_plane_cleanup(struct drm_plane *plane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	struct drm_device *dev = plane->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	drm_modeset_lock_fini(&plane->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	kfree(plane->format_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	kfree(plane->modifiers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	drm_mode_object_unregister(dev, &plane->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	BUG_ON(list_empty(&plane->head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	/* Note that the plane_list is considered to be static; should we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	 * remove the drm_plane at runtime we would have to decrement all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	 * the indices on the drm_plane after us in the plane_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	list_del(&plane->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	dev->mode_config.num_total_plane--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	if (plane->state && plane->funcs->atomic_destroy_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		plane->funcs->atomic_destroy_state(plane, plane->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	kfree(plane->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	memset(plane, 0, sizeof(*plane));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) EXPORT_SYMBOL(drm_plane_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396)  * drm_plane_from_index - find the registered plane at an index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397)  * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398)  * @idx: index of registered plane to find for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400)  * Given a plane index, return the registered plane from DRM device's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401)  * list of planes with matching index. This is the inverse of drm_plane_index().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) struct drm_plane *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) drm_plane_from_index(struct drm_device *dev, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	struct drm_plane *plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	drm_for_each_plane(plane, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		if (idx == plane->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			return plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) EXPORT_SYMBOL(drm_plane_from_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417)  * drm_plane_force_disable - Forcibly disable a plane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418)  * @plane: plane to disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420)  * Forces the plane to be disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422)  * Used when the plane's current framebuffer is destroyed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423)  * and when restoring fbdev mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425)  * Note that this function is not suitable for atomic drivers, since it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)  * wire through the lock acquisition context properly and hence can't handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427)  * retries or driver private locks. You probably want to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428)  * drm_atomic_helper_disable_plane() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)  * drm_atomic_helper_disable_planes_on_crtc() instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) void drm_plane_force_disable(struct drm_plane *plane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	if (!plane->fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	plane->old_fb = plane->fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	ret = plane->funcs->disable_plane(plane, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		DRM_ERROR("failed to disable plane with busy fb\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		plane->old_fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	/* disconnect the plane from the fb and crtc: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	drm_framebuffer_put(plane->old_fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	plane->old_fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	plane->fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	plane->crtc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) EXPORT_SYMBOL(drm_plane_force_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456)  * drm_mode_plane_set_obj_prop - set the value of a property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457)  * @plane: drm plane object to set property value for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458)  * @property: property to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459)  * @value: value the property should be set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461)  * This functions sets a given property on a given plane object. This function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  * calls the driver's ->set_property callback and changes the software state of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463)  * the property if the callback succeeds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466)  * Zero on success, error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 				struct drm_property *property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 				uint64_t value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	struct drm_mode_object *obj = &plane->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	if (plane->funcs->set_property)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		ret = plane->funcs->set_property(plane, property, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		drm_object_property_set_value(obj, property, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) int drm_mode_getplane_res(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			  struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	struct drm_mode_get_plane_res *plane_resp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	struct drm_plane *plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	uint32_t __user *plane_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	plane_ptr = u64_to_user_ptr(plane_resp->plane_id_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	 * This ioctl is called twice, once to determine how much space is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	 * needed, and the 2nd time to fill it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	drm_for_each_plane(plane, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		 * Unless userspace set the 'universal planes'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		 * capability bit, only advertise overlays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		if (plane->type != DRM_PLANE_TYPE_OVERLAY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		    !file_priv->universal_planes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		if (drm_lease_held(file_priv, plane->base.id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 			if (count < plane_resp->count_planes &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 			    put_user(plane->base.id, plane_ptr + count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 				return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	plane_resp->count_planes = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) int drm_mode_getplane(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		      struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	struct drm_mode_get_plane *plane_resp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	struct drm_plane *plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	uint32_t __user *format_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	plane = drm_plane_find(dev, file_priv, plane_resp->plane_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	if (!plane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	drm_modeset_lock(&plane->mutex, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		plane_resp->crtc_id = plane->state->crtc->base.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		plane_resp->crtc_id = plane->crtc->base.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		plane_resp->crtc_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	if (plane->state && plane->state->fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		plane_resp->fb_id = plane->state->fb->base.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	else if (!plane->state && plane->fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		plane_resp->fb_id = plane->fb->base.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		plane_resp->fb_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	drm_modeset_unlock(&plane->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	plane_resp->plane_id = plane->base.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 							    plane->possible_crtcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	plane_resp->gamma_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	 * This ioctl is called twice, once to determine how much space is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	 * needed, and the 2nd time to fill it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	if (plane->format_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	    (plane_resp->count_format_types >= plane->format_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		if (copy_to_user(format_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 				 plane->format_types,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 				 sizeof(uint32_t) * plane->format_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	plane_resp->count_format_types = plane->format_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) int drm_plane_check_pixel_format(struct drm_plane *plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 				 u32 format, u64 modifier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	for (i = 0; i < plane->format_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		if (format == plane->format_types[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	if (i == plane->format_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	if (plane->funcs->format_mod_supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		if (!plane->funcs->format_mod_supported(plane, format, modifier))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		if (!plane->modifier_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		for (i = 0; i < plane->modifier_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 			if (modifier == plane->modifiers[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		if (i == plane->modifier_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) static int __setplane_check(struct drm_plane *plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			    struct drm_crtc *crtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 			    struct drm_framebuffer *fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 			    int32_t crtc_x, int32_t crtc_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 			    uint32_t crtc_w, uint32_t crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			    uint32_t src_x, uint32_t src_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 			    uint32_t src_w, uint32_t src_h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	/* Check whether this plane is usable on this CRTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		DRM_DEBUG_KMS("Invalid crtc for plane\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	/* Check whether this plane supports the fb pixel format. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	ret = drm_plane_check_pixel_format(plane, fb->format->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 					   fb->modifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		struct drm_format_name_buf format_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 			      drm_get_format_name(fb->format->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 						  &format_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 			      fb->modifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	/* Give drivers some help against integer overflows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	if (crtc_w > INT_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	    crtc_x > INT_MAX - (int32_t) crtc_w ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	    crtc_h > INT_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	    crtc_y > INT_MAX - (int32_t) crtc_h) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			      crtc_w, crtc_h, crtc_x, crtc_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653)  * drm_any_plane_has_format - Check whether any plane supports this format and modifier combination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654)  * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)  * @format: pixel format (DRM_FORMAT_*)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  * @modifier: data layout modifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659)  * Whether at least one plane supports the specified format and modifier combination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) bool drm_any_plane_has_format(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			      u32 format, u64 modifier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	struct drm_plane *plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	drm_for_each_plane(plane, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		if (drm_plane_check_pixel_format(plane, format, modifier) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) EXPORT_SYMBOL(drm_any_plane_has_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)  * __setplane_internal - setplane handler for internal callers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678)  * This function will take a reference on the new fb for the plane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679)  * on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681)  * src_{x,y,w,h} are provided in 16.16 fixed point format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) static int __setplane_internal(struct drm_plane *plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 			       struct drm_crtc *crtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 			       struct drm_framebuffer *fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 			       int32_t crtc_x, int32_t crtc_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 			       uint32_t crtc_w, uint32_t crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 			       /* src_{x,y,w,h} values are 16.16 fixed point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			       uint32_t src_x, uint32_t src_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 			       uint32_t src_w, uint32_t src_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			       struct drm_modeset_acquire_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	/* No fb means shut it down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	if (!fb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		plane->old_fb = plane->fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		ret = plane->funcs->disable_plane(plane, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 			plane->crtc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 			plane->fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			plane->old_fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	ret = __setplane_check(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			       crtc_x, crtc_y, crtc_w, crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			       src_x, src_y, src_w, src_h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	plane->old_fb = plane->fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	ret = plane->funcs->update_plane(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 					 crtc_x, crtc_y, crtc_w, crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 					 src_x, src_y, src_w, src_h, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		plane->crtc = crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		plane->fb = fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		drm_framebuffer_get(plane->fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		plane->old_fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	if (plane->old_fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		drm_framebuffer_put(plane->old_fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	plane->old_fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) static int __setplane_atomic(struct drm_plane *plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			     struct drm_crtc *crtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			     struct drm_framebuffer *fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			     int32_t crtc_x, int32_t crtc_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			     uint32_t crtc_w, uint32_t crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			     uint32_t src_x, uint32_t src_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			     uint32_t src_w, uint32_t src_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			     struct drm_modeset_acquire_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	/* No fb means shut it down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (!fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		return plane->funcs->disable_plane(plane, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	 * FIXME: This is redundant with drm_atomic_plane_check(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	 * but the legacy cursor/"async" .update_plane() tricks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	 * don't call that so we still need this here. Should remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	 * this when all .update_plane() implementations have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	 * fixed to call drm_atomic_plane_check().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	ret = __setplane_check(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			       crtc_x, crtc_y, crtc_w, crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 			       src_x, src_y, src_w, src_h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	return plane->funcs->update_plane(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 					  crtc_x, crtc_y, crtc_w, crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 					  src_x, src_y, src_w, src_h, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) static int setplane_internal(struct drm_plane *plane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 			     struct drm_crtc *crtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			     struct drm_framebuffer *fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			     int32_t crtc_x, int32_t crtc_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			     uint32_t crtc_w, uint32_t crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			     /* src_{x,y,w,h} values are 16.16 fixed point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 			     uint32_t src_x, uint32_t src_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			     uint32_t src_w, uint32_t src_h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	struct drm_modeset_acquire_ctx ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 				   DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	if (drm_drv_uses_atomic_modeset(plane->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		ret = __setplane_atomic(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 					crtc_x, crtc_y, crtc_w, crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 					src_x, src_y, src_w, src_h, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		ret = __setplane_internal(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 					  crtc_x, crtc_y, crtc_w, crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 					  src_x, src_y, src_w, src_h, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) int drm_mode_setplane(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		      struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	struct drm_mode_set_plane *plane_req = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	struct drm_plane *plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	struct drm_crtc *crtc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	struct drm_framebuffer *fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	 * First, find the plane, crtc, and fb objects.  If not available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	 * we don't bother to call the driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	plane = drm_plane_find(dev, file_priv, plane_req->plane_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	if (!plane) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		DRM_DEBUG_KMS("Unknown plane ID %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 			      plane_req->plane_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	if (plane_req->fb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		if (!fb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 				      plane_req->fb_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		if (!crtc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			drm_framebuffer_put(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			DRM_DEBUG_KMS("Unknown crtc ID %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 				      plane_req->crtc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	ret = setplane_internal(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 				plane_req->crtc_x, plane_req->crtc_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 				plane_req->crtc_w, plane_req->crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 				plane_req->src_x, plane_req->src_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 				plane_req->src_w, plane_req->src_h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	if (fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		drm_framebuffer_put(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) static int drm_mode_cursor_universal(struct drm_crtc *crtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 				     struct drm_mode_cursor2 *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 				     struct drm_file *file_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 				     struct drm_modeset_acquire_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	struct drm_device *dev = crtc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	struct drm_plane *plane = crtc->cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	struct drm_framebuffer *fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	struct drm_mode_fb_cmd2 fbreq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		.width = req->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		.height = req->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		.pixel_format = DRM_FORMAT_ARGB8888,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		.pitches = { req->width * 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		.handles = { req->handle },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	int32_t crtc_x, crtc_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	uint32_t crtc_w = 0, crtc_h = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	uint32_t src_w = 0, src_h = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	BUG_ON(!plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	WARN_ON(plane->crtc != crtc && plane->crtc != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	 * Obtain fb we'll be using (either new or existing) and take an extra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	 * reference to it if fb != null.  setplane will take care of dropping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	 * the reference if the plane update fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	if (req->flags & DRM_MODE_CURSOR_BO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		if (req->handle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 			fb = drm_internal_framebuffer_create(dev, &fbreq, file_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			if (IS_ERR(fb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 				DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 				return PTR_ERR(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 			fb->hot_x = req->hot_x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 			fb->hot_y = req->hot_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		if (plane->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 			fb = plane->state->fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			fb = plane->fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		if (fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 			drm_framebuffer_get(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	if (req->flags & DRM_MODE_CURSOR_MOVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		crtc_x = req->x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		crtc_y = req->y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		crtc_x = crtc->cursor_x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		crtc_y = crtc->cursor_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	if (fb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		crtc_w = fb->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		crtc_h = fb->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		src_w = fb->width << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		src_h = fb->height << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	if (drm_drv_uses_atomic_modeset(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		ret = __setplane_atomic(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 					crtc_x, crtc_y, crtc_w, crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 					0, 0, src_w, src_h, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		ret = __setplane_internal(plane, crtc, fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 					  crtc_x, crtc_y, crtc_w, crtc_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 					  0, 0, src_w, src_h, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	if (fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		drm_framebuffer_put(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	/* Update successful; save new cursor position, if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		crtc->cursor_x = req->x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		crtc->cursor_y = req->y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) static int drm_mode_cursor_common(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 				  struct drm_mode_cursor2 *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 				  struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	struct drm_crtc *crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	struct drm_modeset_acquire_ctx ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	crtc = drm_crtc_find(dev, file_priv, req->crtc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	if (!crtc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	ret = drm_modeset_lock(&crtc->mutex, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	 * If this crtc has a universal cursor plane, call that plane's update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	 * handler rather than using legacy cursor handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	if (crtc->cursor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		ret = drm_modeset_lock(&crtc->cursor->mutex, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		if (!drm_lease_held(file_priv, crtc->cursor->base.id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 			ret = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		ret = drm_mode_cursor_universal(crtc, req, file_priv, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (req->flags & DRM_MODE_CURSOR_BO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 			ret = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		/* Turns off the cursor if handle is 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		if (crtc->funcs->cursor_set2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 			ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 						      req->width, req->height, req->hot_x, req->hot_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 			ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 						      req->width, req->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	if (req->flags & DRM_MODE_CURSOR_MOVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		if (crtc->funcs->cursor_move) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 			ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 			ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	if (ret == -EDEADLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		ret = drm_modeset_backoff(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 			goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	drm_modeset_drop_locks(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	drm_modeset_acquire_fini(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) int drm_mode_cursor_ioctl(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 			  void *data, struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	struct drm_mode_cursor *req = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	struct drm_mode_cursor2 new_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	new_req.hot_x = new_req.hot_y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	return drm_mode_cursor_common(dev, &new_req, file_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)  * Set the cursor configuration based on user request. This implements the 2nd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)  * version of the cursor ioctl, which allows userspace to additionally specify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)  * the hotspot of the pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) int drm_mode_cursor2_ioctl(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			   void *data, struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	struct drm_mode_cursor2 *req = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	return drm_mode_cursor_common(dev, req, file_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) int drm_mode_page_flip_ioctl(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			     void *data, struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	struct drm_mode_crtc_page_flip_target *page_flip = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	struct drm_crtc *crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	struct drm_plane *plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	struct drm_framebuffer *fb = NULL, *old_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	struct drm_pending_vblank_event *e = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	u32 target_vblank = page_flip->sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	struct drm_modeset_acquire_ctx ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	/* Only one of the DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	 * can be specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	if (!crtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	plane = crtc->primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	if (!drm_lease_held(file_priv, plane->base.id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	if (crtc->funcs->page_flip_target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		u32 current_vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		r = drm_crtc_vblank_get(crtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		current_vblank = (u32)drm_crtc_vblank_count(crtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 			if ((int)(target_vblank - current_vblank) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 				DRM_DEBUG("Invalid absolute flip target %u, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 					  "must be <= %u\n", target_vblank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 					  current_vblank + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 				drm_crtc_vblank_put(crtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			if (target_vblank != 0 && target_vblank != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 				DRM_DEBUG("Invalid relative flip target %u, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 					  "must be 0 or 1\n", target_vblank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 				drm_crtc_vblank_put(crtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			target_vblank += current_vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			target_vblank = current_vblank +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 				!(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	} else if (crtc->funcs->page_flip == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		   (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	ret = drm_modeset_lock(&crtc->mutex, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	ret = drm_modeset_lock(&plane->mutex, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	if (plane->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		old_fb = plane->state->fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		old_fb = plane->fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	if (old_fb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		/* The framebuffer is currently unbound, presumably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		 * due to a hotplug event, that userspace has not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		 * yet discovered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	if (!fb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	if (plane->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		const struct drm_plane_state *state = plane->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		ret = drm_framebuffer_check_src_coords(state->src_x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 						       state->src_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 						       state->src_w,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 						       state->src_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 						       fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 					      &crtc->mode, fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	if (old_fb->format != fb->format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		e = kzalloc(sizeof *e, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		if (!e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 		e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		e->event.base.length = sizeof(e->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		e->event.vbl.user_data = page_flip->user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		e->event.vbl.crtc_id = crtc->base.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 			kfree(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 			e = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	plane->old_fb = plane->fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	if (crtc->funcs->page_flip_target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		ret = crtc->funcs->page_flip_target(crtc, fb, e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 						    page_flip->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 						    target_vblank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 						    &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 					     &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 			drm_event_cancel_free(dev, &e->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		/* Keep the old fb, don't unref it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		plane->old_fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		if (!plane->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 			plane->fb = fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			drm_framebuffer_get(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	if (fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		drm_framebuffer_put(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	if (plane->old_fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		drm_framebuffer_put(plane->old_fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	plane->old_fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	if (ret == -EDEADLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		ret = drm_modeset_backoff(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 			goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	drm_modeset_drop_locks(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	drm_modeset_acquire_fini(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	if (ret && crtc->funcs->page_flip_target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		drm_crtc_vblank_put(crtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }