linux/drivers/gpu/drm/drm_framebuffer.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/export.h>
  24#include <drm/drmP.h>
  25#include <drm/drm_auth.h>
  26#include <drm/drm_framebuffer.h>
  27#include <drm/drm_atomic.h>
  28#include <drm/drm_print.h>
  29
  30#include "drm_internal.h"
  31#include "drm_crtc_internal.h"
  32
  33/**
  34 * DOC: overview
  35 *
  36 * Frame buffers are abstract memory objects that provide a source of pixels to
  37 * scanout to a CRTC. Applications explicitly request the creation of frame
  38 * buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls and receive an opaque
  39 * handle that can be passed to the KMS CRTC control, plane configuration and
  40 * page flip functions.
  41 *
  42 * Frame buffers rely on the underlying memory manager for allocating backing
  43 * storage. When creating a frame buffer applications pass a memory handle
  44 * (or a list of memory handles for multi-planar formats) through the
  45 * &struct drm_mode_fb_cmd2 argument. For drivers using GEM as their userspace
  46 * buffer management interface this would be a GEM handle.  Drivers are however
  47 * free to use their own backing storage object handles, e.g. vmwgfx directly
  48 * exposes special TTM handles to userspace and so expects TTM handles in the
  49 * create ioctl and not GEM handles.
  50 *
  51 * Framebuffers are tracked with &struct drm_framebuffer. They are published
  52 * using drm_framebuffer_init() - after calling that function userspace can use
  53 * and access the framebuffer object. The helper function
  54 * drm_helper_mode_fill_fb_struct() can be used to pre-fill the required
  55 * metadata fields.
  56 *
  57 * The lifetime of a drm framebuffer is controlled with a reference count,
  58 * drivers can grab additional references with drm_framebuffer_get() and drop
  59 * them again with drm_framebuffer_put(). For driver-private framebuffers for
  60 * which the last reference is never dropped (e.g. for the fbdev framebuffer
  61 * when the struct &struct drm_framebuffer is embedded into the fbdev helper
  62 * struct) drivers can manually clean up a framebuffer at module unload time
  63 * with drm_framebuffer_unregister_private(). But doing this is not
  64 * recommended, and it's better to have a normal free-standing &struct
  65 * drm_framebuffer.
  66 */
  67
  68int drm_framebuffer_check_src_coords(uint32_t src_x, uint32_t src_y,
  69                                     uint32_t src_w, uint32_t src_h,
  70                                     const struct drm_framebuffer *fb)
  71{
  72        unsigned int fb_width, fb_height;
  73
  74        fb_width = fb->width << 16;
  75        fb_height = fb->height << 16;
  76
  77        /* Make sure source coordinates are inside the fb. */
  78        if (src_w > fb_width ||
  79            src_x > fb_width - src_w ||
  80            src_h > fb_height ||
  81            src_y > fb_height - src_h) {
  82                DRM_DEBUG_KMS("Invalid source coordinates "
  83                              "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
  84                              src_w >> 16, ((src_w & 0xffff) * 15625) >> 10,
  85                              src_h >> 16, ((src_h & 0xffff) * 15625) >> 10,
  86                              src_x >> 16, ((src_x & 0xffff) * 15625) >> 10,
  87                              src_y >> 16, ((src_y & 0xffff) * 15625) >> 10,
  88                              fb->width, fb->height);
  89                return -ENOSPC;
  90        }
  91
  92        return 0;
  93}
  94
  95/**
  96 * drm_mode_addfb - add an FB to the graphics configuration
  97 * @dev: drm device for the ioctl
  98 * @data: data pointer for the ioctl
  99 * @file_priv: drm file for the ioctl call
 100 *
 101 * Add a new FB to the specified CRTC, given a user request. This is the
 102 * original addfb ioctl which only supported RGB formats.
 103 *
 104 * Called by the user via ioctl.
 105 *
 106 * Returns:
 107 * Zero on success, negative errno on failure.
 108 */
 109int drm_mode_addfb(struct drm_device *dev,
 110                   void *data, struct drm_file *file_priv)
 111{
 112        struct drm_mode_fb_cmd *or = data;
 113        struct drm_mode_fb_cmd2 r = {};
 114        int ret;
 115
 116        /* convert to new format and call new ioctl */
 117        r.fb_id = or->fb_id;
 118        r.width = or->width;
 119        r.height = or->height;
 120        r.pitches[0] = or->pitch;
 121        r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
 122        r.handles[0] = or->handle;
 123
 124        if (r.pixel_format == DRM_FORMAT_XRGB2101010 &&
 125            dev->driver->driver_features & DRIVER_PREFER_XBGR_30BPP)
 126                r.pixel_format = DRM_FORMAT_XBGR2101010;
 127
 128        ret = drm_mode_addfb2(dev, &r, file_priv);
 129        if (ret)
 130                return ret;
 131
 132        or->fb_id = r.fb_id;
 133
 134        return 0;
 135}
 136
 137static int fb_plane_width(int width,
 138                          const struct drm_format_info *format, int plane)
 139{
 140        if (plane == 0)
 141                return width;
 142
 143        return DIV_ROUND_UP(width, format->hsub);
 144}
 145
 146static int fb_plane_height(int height,
 147                           const struct drm_format_info *format, int plane)
 148{
 149        if (plane == 0)
 150                return height;
 151
 152        return DIV_ROUND_UP(height, format->vsub);
 153}
 154
 155static int framebuffer_check(struct drm_device *dev,
 156                             const struct drm_mode_fb_cmd2 *r)
 157{
 158        const struct drm_format_info *info;
 159        int i;
 160
 161        /* check if the format is supported at all */
 162        info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
 163        if (!info) {
 164                struct drm_format_name_buf format_name;
 165                DRM_DEBUG_KMS("bad framebuffer format %s\n",
 166                              drm_get_format_name(r->pixel_format,
 167                                                  &format_name));
 168                return -EINVAL;
 169        }
 170
 171        /* now let the driver pick its own format info */
 172        info = drm_get_format_info(dev, r);
 173
 174        if (r->width == 0) {
 175                DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
 176                return -EINVAL;
 177        }
 178
 179        if (r->height == 0) {
 180                DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
 181                return -EINVAL;
 182        }
 183
 184        for (i = 0; i < info->num_planes; i++) {
 185                unsigned int width = fb_plane_width(r->width, info, i);
 186                unsigned int height = fb_plane_height(r->height, info, i);
 187                unsigned int cpp = info->cpp[i];
 188
 189                if (!r->handles[i]) {
 190                        DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
 191                        return -EINVAL;
 192                }
 193
 194                if ((uint64_t) width * cpp > UINT_MAX)
 195                        return -ERANGE;
 196
 197                if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
 198                        return -ERANGE;
 199
 200                if (r->pitches[i] < width * cpp) {
 201                        DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
 202                        return -EINVAL;
 203                }
 204
 205                if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) {
 206                        DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n",
 207                                      r->modifier[i], i);
 208                        return -EINVAL;
 209                }
 210
 211                if (r->flags & DRM_MODE_FB_MODIFIERS &&
 212                    r->modifier[i] != r->modifier[0]) {
 213                        DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n",
 214                                      r->modifier[i], i);
 215                        return -EINVAL;
 216                }
 217
 218                /* modifier specific checks: */
 219                switch (r->modifier[i]) {
 220                case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
 221                        /* NOTE: the pitch restriction may be lifted later if it turns
 222                         * out that no hw has this restriction:
 223                         */
 224                        if (r->pixel_format != DRM_FORMAT_NV12 ||
 225                                        width % 128 || height % 32 ||
 226                                        r->pitches[i] % 128) {
 227                                DRM_DEBUG_KMS("bad modifier data for plane %d\n", i);
 228                                return -EINVAL;
 229                        }
 230                        break;
 231
 232                default:
 233                        break;
 234                }
 235        }
 236
 237        for (i = info->num_planes; i < 4; i++) {
 238                if (r->modifier[i]) {
 239                        DRM_DEBUG_KMS("non-zero modifier for unused plane %d\n", i);
 240                        return -EINVAL;
 241                }
 242
 243                /* Pre-FB_MODIFIERS userspace didn't clear the structs properly. */
 244                if (!(r->flags & DRM_MODE_FB_MODIFIERS))
 245                        continue;
 246
 247                if (r->handles[i]) {
 248                        DRM_DEBUG_KMS("buffer object handle for unused plane %d\n", i);
 249                        return -EINVAL;
 250                }
 251
 252                if (r->pitches[i]) {
 253                        DRM_DEBUG_KMS("non-zero pitch for unused plane %d\n", i);
 254                        return -EINVAL;
 255                }
 256
 257                if (r->offsets[i]) {
 258                        DRM_DEBUG_KMS("non-zero offset for unused plane %d\n", i);
 259                        return -EINVAL;
 260                }
 261        }
 262
 263        return 0;
 264}
 265
 266struct drm_framebuffer *
 267drm_internal_framebuffer_create(struct drm_device *dev,
 268                                const struct drm_mode_fb_cmd2 *r,
 269                                struct drm_file *file_priv)
 270{
 271        struct drm_mode_config *config = &dev->mode_config;
 272        struct drm_framebuffer *fb;
 273        int ret;
 274
 275        if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) {
 276                DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
 277                return ERR_PTR(-EINVAL);
 278        }
 279
 280        if ((config->min_width > r->width) || (r->width > config->max_width)) {
 281                DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
 282                          r->width, config->min_width, config->max_width);
 283                return ERR_PTR(-EINVAL);
 284        }
 285        if ((config->min_height > r->height) || (r->height > config->max_height)) {
 286                DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
 287                          r->height, config->min_height, config->max_height);
 288                return ERR_PTR(-EINVAL);
 289        }
 290
 291        if (r->flags & DRM_MODE_FB_MODIFIERS &&
 292            !dev->mode_config.allow_fb_modifiers) {
 293                DRM_DEBUG_KMS("driver does not support fb modifiers\n");
 294                return ERR_PTR(-EINVAL);
 295        }
 296
 297        ret = framebuffer_check(dev, r);
 298        if (ret)
 299                return ERR_PTR(ret);
 300
 301        fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
 302        if (IS_ERR(fb)) {
 303                DRM_DEBUG_KMS("could not create framebuffer\n");
 304                return fb;
 305        }
 306
 307        return fb;
 308}
 309
 310/**
 311 * drm_mode_addfb2 - add an FB to the graphics configuration
 312 * @dev: drm device for the ioctl
 313 * @data: data pointer for the ioctl
 314 * @file_priv: drm file for the ioctl call
 315 *
 316 * Add a new FB to the specified CRTC, given a user request with format. This is
 317 * the 2nd version of the addfb ioctl, which supports multi-planar framebuffers
 318 * and uses fourcc codes as pixel format specifiers.
 319 *
 320 * Called by the user via ioctl.
 321 *
 322 * Returns:
 323 * Zero on success, negative errno on failure.
 324 */
 325int drm_mode_addfb2(struct drm_device *dev,
 326                    void *data, struct drm_file *file_priv)
 327{
 328        struct drm_mode_fb_cmd2 *r = data;
 329        struct drm_framebuffer *fb;
 330
 331        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 332                return -EINVAL;
 333
 334        fb = drm_internal_framebuffer_create(dev, r, file_priv);
 335        if (IS_ERR(fb))
 336                return PTR_ERR(fb);
 337
 338        DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
 339        r->fb_id = fb->base.id;
 340
 341        /* Transfer ownership to the filp for reaping on close */
 342        mutex_lock(&file_priv->fbs_lock);
 343        list_add(&fb->filp_head, &file_priv->fbs);
 344        mutex_unlock(&file_priv->fbs_lock);
 345
 346        return 0;
 347}
 348
 349struct drm_mode_rmfb_work {
 350        struct work_struct work;
 351        struct list_head fbs;
 352};
 353
 354static void drm_mode_rmfb_work_fn(struct work_struct *w)
 355{
 356        struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
 357
 358        while (!list_empty(&arg->fbs)) {
 359                struct drm_framebuffer *fb =
 360                        list_first_entry(&arg->fbs, typeof(*fb), filp_head);
 361
 362                list_del_init(&fb->filp_head);
 363                drm_framebuffer_remove(fb);
 364        }
 365}
 366
 367/**
 368 * drm_mode_rmfb - remove an FB from the configuration
 369 * @dev: drm device for the ioctl
 370 * @data: data pointer for the ioctl
 371 * @file_priv: drm file for the ioctl call
 372 *
 373 * Remove the FB specified by the user.
 374 *
 375 * Called by the user via ioctl.
 376 *
 377 * Returns:
 378 * Zero on success, negative errno on failure.
 379 */
 380int drm_mode_rmfb(struct drm_device *dev,
 381                   void *data, struct drm_file *file_priv)
 382{
 383        struct drm_framebuffer *fb = NULL;
 384        struct drm_framebuffer *fbl = NULL;
 385        uint32_t *id = data;
 386        int found = 0;
 387
 388        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 389                return -EINVAL;
 390
 391        fb = drm_framebuffer_lookup(dev, file_priv, *id);
 392        if (!fb)
 393                return -ENOENT;
 394
 395        mutex_lock(&file_priv->fbs_lock);
 396        list_for_each_entry(fbl, &file_priv->fbs, filp_head)
 397                if (fb == fbl)
 398                        found = 1;
 399        if (!found) {
 400                mutex_unlock(&file_priv->fbs_lock);
 401                goto fail_unref;
 402        }
 403
 404        list_del_init(&fb->filp_head);
 405        mutex_unlock(&file_priv->fbs_lock);
 406
 407        /* drop the reference we picked up in framebuffer lookup */
 408        drm_framebuffer_put(fb);
 409
 410        /*
 411         * we now own the reference that was stored in the fbs list
 412         *
 413         * drm_framebuffer_remove may fail with -EINTR on pending signals,
 414         * so run this in a separate stack as there's no way to correctly
 415         * handle this after the fb is already removed from the lookup table.
 416         */
 417        if (drm_framebuffer_read_refcount(fb) > 1) {
 418                struct drm_mode_rmfb_work arg;
 419
 420                INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
 421                INIT_LIST_HEAD(&arg.fbs);
 422                list_add_tail(&fb->filp_head, &arg.fbs);
 423
 424                schedule_work(&arg.work);
 425                flush_work(&arg.work);
 426                destroy_work_on_stack(&arg.work);
 427        } else
 428                drm_framebuffer_put(fb);
 429
 430        return 0;
 431
 432fail_unref:
 433        drm_framebuffer_put(fb);
 434        return -ENOENT;
 435}
 436
 437/**
 438 * drm_mode_getfb - get FB info
 439 * @dev: drm device for the ioctl
 440 * @data: data pointer for the ioctl
 441 * @file_priv: drm file for the ioctl call
 442 *
 443 * Lookup the FB given its ID and return info about it.
 444 *
 445 * Called by the user via ioctl.
 446 *
 447 * Returns:
 448 * Zero on success, negative errno on failure.
 449 */
 450int drm_mode_getfb(struct drm_device *dev,
 451                   void *data, struct drm_file *file_priv)
 452{
 453        struct drm_mode_fb_cmd *r = data;
 454        struct drm_framebuffer *fb;
 455        int ret;
 456
 457        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 458                return -EINVAL;
 459
 460        fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
 461        if (!fb)
 462                return -ENOENT;
 463
 464        /* Multi-planar framebuffers need getfb2. */
 465        if (fb->format->num_planes > 1) {
 466                ret = -EINVAL;
 467                goto out;
 468        }
 469
 470        r->height = fb->height;
 471        r->width = fb->width;
 472        r->depth = fb->format->depth;
 473        r->bpp = fb->format->cpp[0] * 8;
 474        r->pitch = fb->pitches[0];
 475        if (fb->funcs->create_handle) {
 476                if (drm_is_current_master(file_priv) || capable(CAP_SYS_ADMIN) ||
 477                    drm_is_control_client(file_priv)) {
 478                        ret = fb->funcs->create_handle(fb, file_priv,
 479                                                       &r->handle);
 480                } else {
 481                        /* GET_FB() is an unprivileged ioctl so we must not
 482                         * return a buffer-handle to non-master processes! For
 483                         * backwards-compatibility reasons, we cannot make
 484                         * GET_FB() privileged, so just return an invalid handle
 485                         * for non-masters. */
 486                        r->handle = 0;
 487                        ret = 0;
 488                }
 489        } else {
 490                ret = -ENODEV;
 491        }
 492
 493out:
 494        drm_framebuffer_put(fb);
 495
 496        return ret;
 497}
 498
 499/**
 500 * drm_mode_dirtyfb_ioctl - flush frontbuffer rendering on an FB
 501 * @dev: drm device for the ioctl
 502 * @data: data pointer for the ioctl
 503 * @file_priv: drm file for the ioctl call
 504 *
 505 * Lookup the FB and flush out the damaged area supplied by userspace as a clip
 506 * rectangle list. Generic userspace which does frontbuffer rendering must call
 507 * this ioctl to flush out the changes on manual-update display outputs, e.g.
 508 * usb display-link, mipi manual update panels or edp panel self refresh modes.
 509 *
 510 * Modesetting drivers which always update the frontbuffer do not need to
 511 * implement the corresponding &drm_framebuffer_funcs.dirty callback.
 512 *
 513 * Called by the user via ioctl.
 514 *
 515 * Returns:
 516 * Zero on success, negative errno on failure.
 517 */
 518int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
 519                           void *data, struct drm_file *file_priv)
 520{
 521        struct drm_clip_rect __user *clips_ptr;
 522        struct drm_clip_rect *clips = NULL;
 523        struct drm_mode_fb_dirty_cmd *r = data;
 524        struct drm_framebuffer *fb;
 525        unsigned flags;
 526        int num_clips;
 527        int ret;
 528
 529        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 530                return -EINVAL;
 531
 532        fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
 533        if (!fb)
 534                return -ENOENT;
 535
 536        num_clips = r->num_clips;
 537        clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
 538
 539        if (!num_clips != !clips_ptr) {
 540                ret = -EINVAL;
 541                goto out_err1;
 542        }
 543
 544        flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
 545
 546        /* If userspace annotates copy, clips must come in pairs */
 547        if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
 548                ret = -EINVAL;
 549                goto out_err1;
 550        }
 551
 552        if (num_clips && clips_ptr) {
 553                if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
 554                        ret = -EINVAL;
 555                        goto out_err1;
 556                }
 557                clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
 558                if (!clips) {
 559                        ret = -ENOMEM;
 560                        goto out_err1;
 561                }
 562
 563                ret = copy_from_user(clips, clips_ptr,
 564                                     num_clips * sizeof(*clips));
 565                if (ret) {
 566                        ret = -EFAULT;
 567                        goto out_err2;
 568                }
 569        }
 570
 571        if (fb->funcs->dirty) {
 572                ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
 573                                       clips, num_clips);
 574        } else {
 575                ret = -ENOSYS;
 576        }
 577
 578out_err2:
 579        kfree(clips);
 580out_err1:
 581        drm_framebuffer_put(fb);
 582
 583        return ret;
 584}
 585
 586/**
 587 * drm_fb_release - remove and free the FBs on this file
 588 * @priv: drm file for the ioctl
 589 *
 590 * Destroy all the FBs associated with @filp.
 591 *
 592 * Called by the user via ioctl.
 593 *
 594 * Returns:
 595 * Zero on success, negative errno on failure.
 596 */
 597void drm_fb_release(struct drm_file *priv)
 598{
 599        struct drm_framebuffer *fb, *tfb;
 600        struct drm_mode_rmfb_work arg;
 601
 602        INIT_LIST_HEAD(&arg.fbs);
 603
 604        /*
 605         * When the file gets released that means no one else can access the fb
 606         * list any more, so no need to grab fpriv->fbs_lock. And we need to
 607         * avoid upsetting lockdep since the universal cursor code adds a
 608         * framebuffer while holding mutex locks.
 609         *
 610         * Note that a real deadlock between fpriv->fbs_lock and the modeset
 611         * locks is impossible here since no one else but this function can get
 612         * at it any more.
 613         */
 614        list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
 615                if (drm_framebuffer_read_refcount(fb) > 1) {
 616                        list_move_tail(&fb->filp_head, &arg.fbs);
 617                } else {
 618                        list_del_init(&fb->filp_head);
 619
 620                        /* This drops the fpriv->fbs reference. */
 621                        drm_framebuffer_put(fb);
 622                }
 623        }
 624
 625        if (!list_empty(&arg.fbs)) {
 626                INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
 627
 628                schedule_work(&arg.work);
 629                flush_work(&arg.work);
 630                destroy_work_on_stack(&arg.work);
 631        }
 632}
 633
 634void drm_framebuffer_free(struct kref *kref)
 635{
 636        struct drm_framebuffer *fb =
 637                        container_of(kref, struct drm_framebuffer, base.refcount);
 638        struct drm_device *dev = fb->dev;
 639
 640        /*
 641         * The lookup idr holds a weak reference, which has not necessarily been
 642         * removed at this point. Check for that.
 643         */
 644        drm_mode_object_unregister(dev, &fb->base);
 645
 646        fb->funcs->destroy(fb);
 647}
 648
 649/**
 650 * drm_framebuffer_init - initialize a framebuffer
 651 * @dev: DRM device
 652 * @fb: framebuffer to be initialized
 653 * @funcs: ... with these functions
 654 *
 655 * Allocates an ID for the framebuffer's parent mode object, sets its mode
 656 * functions & device file and adds it to the master fd list.
 657 *
 658 * IMPORTANT:
 659 * This functions publishes the fb and makes it available for concurrent access
 660 * by other users. Which means by this point the fb _must_ be fully set up -
 661 * since all the fb attributes are invariant over its lifetime, no further
 662 * locking but only correct reference counting is required.
 663 *
 664 * Returns:
 665 * Zero on success, error code on failure.
 666 */
 667int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
 668                         const struct drm_framebuffer_funcs *funcs)
 669{
 670        int ret;
 671
 672        if (WARN_ON_ONCE(fb->dev != dev || !fb->format))
 673                return -EINVAL;
 674
 675        INIT_LIST_HEAD(&fb->filp_head);
 676
 677        fb->funcs = funcs;
 678        strcpy(fb->comm, current->comm);
 679
 680        ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,
 681                                    false, drm_framebuffer_free);
 682        if (ret)
 683                goto out;
 684
 685        mutex_lock(&dev->mode_config.fb_lock);
 686        dev->mode_config.num_fb++;
 687        list_add(&fb->head, &dev->mode_config.fb_list);
 688        mutex_unlock(&dev->mode_config.fb_lock);
 689
 690        drm_mode_object_register(dev, &fb->base);
 691out:
 692        return ret;
 693}
 694EXPORT_SYMBOL(drm_framebuffer_init);
 695
 696/**
 697 * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
 698 * @dev: drm device
 699 * @file_priv: drm file to check for lease against.
 700 * @id: id of the fb object
 701 *
 702 * If successful, this grabs an additional reference to the framebuffer -
 703 * callers need to make sure to eventually unreference the returned framebuffer
 704 * again, using drm_framebuffer_put().
 705 */
 706struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
 707                                               struct drm_file *file_priv,
 708                                               uint32_t id)
 709{
 710        struct drm_mode_object *obj;
 711        struct drm_framebuffer *fb = NULL;
 712
 713        obj = __drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_FB);
 714        if (obj)
 715                fb = obj_to_fb(obj);
 716        return fb;
 717}
 718EXPORT_SYMBOL(drm_framebuffer_lookup);
 719
 720/**
 721 * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
 722 * @fb: fb to unregister
 723 *
 724 * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
 725 * those used for fbdev. Note that the caller must hold a reference of it's own,
 726 * i.e. the object may not be destroyed through this call (since it'll lead to a
 727 * locking inversion).
 728 *
 729 * NOTE: This function is deprecated. For driver-private framebuffers it is not
 730 * recommended to embed a framebuffer struct info fbdev struct, instead, a
 731 * framebuffer pointer is preferred and drm_framebuffer_put() should be called
 732 * when the framebuffer is to be cleaned up.
 733 */
 734void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
 735{
 736        struct drm_device *dev;
 737
 738        if (!fb)
 739                return;
 740
 741        dev = fb->dev;
 742
 743        /* Mark fb as reaped and drop idr ref. */
 744        drm_mode_object_unregister(dev, &fb->base);
 745}
 746EXPORT_SYMBOL(drm_framebuffer_unregister_private);
 747
 748/**
 749 * drm_framebuffer_cleanup - remove a framebuffer object
 750 * @fb: framebuffer to remove
 751 *
 752 * Cleanup framebuffer. This function is intended to be used from the drivers
 753 * &drm_framebuffer_funcs.destroy callback. It can also be used to clean up
 754 * driver private framebuffers embedded into a larger structure.
 755 *
 756 * Note that this function does not remove the fb from active usage - if it is
 757 * still used anywhere, hilarity can ensue since userspace could call getfb on
 758 * the id and get back -EINVAL. Obviously no concern at driver unload time.
 759 *
 760 * Also, the framebuffer will not be removed from the lookup idr - for
 761 * user-created framebuffers this will happen in in the rmfb ioctl. For
 762 * driver-private objects (e.g. for fbdev) drivers need to explicitly call
 763 * drm_framebuffer_unregister_private.
 764 */
 765void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 766{
 767        struct drm_device *dev = fb->dev;
 768
 769        mutex_lock(&dev->mode_config.fb_lock);
 770        list_del(&fb->head);
 771        dev->mode_config.num_fb--;
 772        mutex_unlock(&dev->mode_config.fb_lock);
 773}
 774EXPORT_SYMBOL(drm_framebuffer_cleanup);
 775
 776static int atomic_remove_fb(struct drm_framebuffer *fb)
 777{
 778        struct drm_modeset_acquire_ctx ctx;
 779        struct drm_device *dev = fb->dev;
 780        struct drm_atomic_state *state;
 781        struct drm_plane *plane;
 782        struct drm_connector *conn;
 783        struct drm_connector_state *conn_state;
 784        int i, ret;
 785        unsigned plane_mask;
 786        bool disable_crtcs = false;
 787
 788retry_disable:
 789        drm_modeset_acquire_init(&ctx, 0);
 790
 791        state = drm_atomic_state_alloc(dev);
 792        if (!state) {
 793                ret = -ENOMEM;
 794                goto out;
 795        }
 796        state->acquire_ctx = &ctx;
 797
 798retry:
 799        plane_mask = 0;
 800        ret = drm_modeset_lock_all_ctx(dev, &ctx);
 801        if (ret)
 802                goto unlock;
 803
 804        drm_for_each_plane(plane, dev) {
 805                struct drm_plane_state *plane_state;
 806
 807                if (plane->state->fb != fb)
 808                        continue;
 809
 810                plane_state = drm_atomic_get_plane_state(state, plane);
 811                if (IS_ERR(plane_state)) {
 812                        ret = PTR_ERR(plane_state);
 813                        goto unlock;
 814                }
 815
 816                if (disable_crtcs && plane_state->crtc->primary == plane) {
 817                        struct drm_crtc_state *crtc_state;
 818
 819                        crtc_state = drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
 820
 821                        ret = drm_atomic_add_affected_connectors(state, plane_state->crtc);
 822                        if (ret)
 823                                goto unlock;
 824
 825                        crtc_state->active = false;
 826                        ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
 827                        if (ret)
 828                                goto unlock;
 829                }
 830
 831                drm_atomic_set_fb_for_plane(plane_state, NULL);
 832                ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
 833                if (ret)
 834                        goto unlock;
 835
 836                plane_mask |= BIT(drm_plane_index(plane));
 837
 838                plane->old_fb = plane->fb;
 839        }
 840
 841        /* This list is only filled when disable_crtcs is set. */
 842        for_each_new_connector_in_state(state, conn, conn_state, i) {
 843                ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
 844
 845                if (ret)
 846                        goto unlock;
 847        }
 848
 849        if (plane_mask)
 850                ret = drm_atomic_commit(state);
 851
 852unlock:
 853        if (plane_mask)
 854                drm_atomic_clean_old_fb(dev, plane_mask, ret);
 855
 856        if (ret == -EDEADLK) {
 857                drm_atomic_state_clear(state);
 858                drm_modeset_backoff(&ctx);
 859                goto retry;
 860        }
 861
 862        drm_atomic_state_put(state);
 863
 864out:
 865        drm_modeset_drop_locks(&ctx);
 866        drm_modeset_acquire_fini(&ctx);
 867
 868        if (ret == -EINVAL && !disable_crtcs) {
 869                disable_crtcs = true;
 870                goto retry_disable;
 871        }
 872
 873        return ret;
 874}
 875
 876static void legacy_remove_fb(struct drm_framebuffer *fb)
 877{
 878        struct drm_device *dev = fb->dev;
 879        struct drm_crtc *crtc;
 880        struct drm_plane *plane;
 881
 882        drm_modeset_lock_all(dev);
 883        /* remove from any CRTC */
 884        drm_for_each_crtc(crtc, dev) {
 885                if (crtc->primary->fb == fb) {
 886                        /* should turn off the crtc */
 887                        if (drm_crtc_force_disable(crtc))
 888                                DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
 889                }
 890        }
 891
 892        drm_for_each_plane(plane, dev) {
 893                if (plane->fb == fb)
 894                        drm_plane_force_disable(plane);
 895        }
 896        drm_modeset_unlock_all(dev);
 897}
 898
 899/**
 900 * drm_framebuffer_remove - remove and unreference a framebuffer object
 901 * @fb: framebuffer to remove
 902 *
 903 * Scans all the CRTCs and planes in @dev's mode_config.  If they're
 904 * using @fb, removes it, setting it to NULL. Then drops the reference to the
 905 * passed-in framebuffer. Might take the modeset locks.
 906 *
 907 * Note that this function optimizes the cleanup away if the caller holds the
 908 * last reference to the framebuffer. It is also guaranteed to not take the
 909 * modeset locks in this case.
 910 */
 911void drm_framebuffer_remove(struct drm_framebuffer *fb)
 912{
 913        struct drm_device *dev;
 914
 915        if (!fb)
 916                return;
 917
 918        dev = fb->dev;
 919
 920        WARN_ON(!list_empty(&fb->filp_head));
 921
 922        /*
 923         * drm ABI mandates that we remove any deleted framebuffers from active
 924         * useage. But since most sane clients only remove framebuffers they no
 925         * longer need, try to optimize this away.
 926         *
 927         * Since we're holding a reference ourselves, observing a refcount of 1
 928         * means that we're the last holder and can skip it. Also, the refcount
 929         * can never increase from 1 again, so we don't need any barriers or
 930         * locks.
 931         *
 932         * Note that userspace could try to race with use and instate a new
 933         * usage _after_ we've cleared all current ones. End result will be an
 934         * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
 935         * in this manner.
 936         */
 937        if (drm_framebuffer_read_refcount(fb) > 1) {
 938                if (drm_drv_uses_atomic_modeset(dev)) {
 939                        int ret = atomic_remove_fb(fb);
 940                        WARN(ret, "atomic remove_fb failed with %i\n", ret);
 941                } else
 942                        legacy_remove_fb(fb);
 943        }
 944
 945        drm_framebuffer_put(fb);
 946}
 947EXPORT_SYMBOL(drm_framebuffer_remove);
 948
 949/**
 950 * drm_framebuffer_plane_width - width of the plane given the first plane
 951 * @width: width of the first plane
 952 * @fb: the framebuffer
 953 * @plane: plane index
 954 *
 955 * Returns:
 956 * The width of @plane, given that the width of the first plane is @width.
 957 */
 958int drm_framebuffer_plane_width(int width,
 959                                const struct drm_framebuffer *fb, int plane)
 960{
 961        if (plane >= fb->format->num_planes)
 962                return 0;
 963
 964        return fb_plane_width(width, fb->format, plane);
 965}
 966EXPORT_SYMBOL(drm_framebuffer_plane_width);
 967
 968/**
 969 * drm_framebuffer_plane_height - height of the plane given the first plane
 970 * @height: height of the first plane
 971 * @fb: the framebuffer
 972 * @plane: plane index
 973 *
 974 * Returns:
 975 * The height of @plane, given that the height of the first plane is @height.
 976 */
 977int drm_framebuffer_plane_height(int height,
 978                                 const struct drm_framebuffer *fb, int plane)
 979{
 980        if (plane >= fb->format->num_planes)
 981                return 0;
 982
 983        return fb_plane_height(height, fb->format, plane);
 984}
 985EXPORT_SYMBOL(drm_framebuffer_plane_height);
 986
 987void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
 988                                const struct drm_framebuffer *fb)
 989{
 990        struct drm_format_name_buf format_name;
 991        unsigned int i;
 992
 993        drm_printf_indent(p, indent, "allocated by = %s\n", fb->comm);
 994        drm_printf_indent(p, indent, "refcount=%u\n",
 995                          drm_framebuffer_read_refcount(fb));
 996        drm_printf_indent(p, indent, "format=%s\n",
 997                          drm_get_format_name(fb->format->format, &format_name));
 998        drm_printf_indent(p, indent, "modifier=0x%llx\n", fb->modifier);
 999        drm_printf_indent(p, indent, "size=%ux%u\n", fb->width, fb->height);
1000        drm_printf_indent(p, indent, "layers:\n");
1001
1002        for (i = 0; i < fb->format->num_planes; i++) {
1003                drm_printf_indent(p, indent + 1, "size[%u]=%dx%d\n", i,
1004                                  drm_framebuffer_plane_width(fb->width, fb, i),
1005                                  drm_framebuffer_plane_height(fb->height, fb, i));
1006                drm_printf_indent(p, indent + 1, "pitch[%u]=%u\n", i, fb->pitches[i]);
1007                drm_printf_indent(p, indent + 1, "offset[%u]=%u\n", i, fb->offsets[i]);
1008                drm_printf_indent(p, indent + 1, "obj[%u]:%s\n", i,
1009                                  fb->obj[i] ? "" : "(null)");
1010                if (fb->obj[i])
1011                        drm_gem_print_info(p, indent + 2, fb->obj[i]);
1012        }
1013}
1014
1015#ifdef CONFIG_DEBUG_FS
1016static int drm_framebuffer_info(struct seq_file *m, void *data)
1017{
1018        struct drm_info_node *node = m->private;
1019        struct drm_device *dev = node->minor->dev;
1020        struct drm_printer p = drm_seq_file_printer(m);
1021        struct drm_framebuffer *fb;
1022
1023        mutex_lock(&dev->mode_config.fb_lock);
1024        drm_for_each_fb(fb, dev) {
1025                drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
1026                drm_framebuffer_print_info(&p, 1, fb);
1027        }
1028        mutex_unlock(&dev->mode_config.fb_lock);
1029
1030        return 0;
1031}
1032
1033static const struct drm_info_list drm_framebuffer_debugfs_list[] = {
1034        { "framebuffer", drm_framebuffer_info, 0 },
1035};
1036
1037int drm_framebuffer_debugfs_init(struct drm_minor *minor)
1038{
1039        return drm_debugfs_create_files(drm_framebuffer_debugfs_list,
1040                                ARRAY_SIZE(drm_framebuffer_debugfs_list),
1041                                minor->debugfs_root, minor);
1042}
1043#endif
1044