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