Linux Audio

Check our new training course

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