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