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