linux/drivers/gpu/drm/drm_crtc.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2006-2008 Intel Corporation
   3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
   4 * Copyright (c) 2008 Red Hat Inc.
   5 *
   6 * DRM core CRTC related functions
   7 *
   8 * Permission to use, copy, modify, distribute, and sell this software and its
   9 * documentation for any purpose is hereby granted without fee, provided that
  10 * the above copyright notice appear in all copies and that both that copyright
  11 * notice and this permission notice appear in supporting documentation, and
  12 * that the name of the copyright holders not be used in advertising or
  13 * publicity pertaining to distribution of the software without specific,
  14 * written prior permission.  The copyright holders make no representations
  15 * about the suitability of this software for any purpose.  It is provided "as
  16 * is" without express or implied warranty.
  17 *
  18 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  20 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  24 * OF THIS SOFTWARE.
  25 *
  26 * Authors:
  27 *      Keith Packard
  28 *      Eric Anholt <eric@anholt.net>
  29 *      Dave Airlie <airlied@linux.ie>
  30 *      Jesse Barnes <jesse.barnes@intel.com>
  31 */
  32#include <linux/ctype.h>
  33#include <linux/list.h>
  34#include <linux/slab.h>
  35#include <linux/export.h>
  36#include <linux/dma-fence.h>
  37#include <linux/uaccess.h>
  38#include <drm/drm_crtc.h>
  39#include <drm/drm_edid.h>
  40#include <drm/drm_fourcc.h>
  41#include <drm/drm_modeset_lock.h>
  42#include <drm/drm_atomic.h>
  43#include <drm/drm_auth.h>
  44#include <drm/drm_debugfs_crc.h>
  45#include <drm/drm_drv.h>
  46#include <drm/drm_print.h>
  47#include <drm/drm_file.h>
  48
  49#include "drm_crtc_internal.h"
  50#include "drm_internal.h"
  51
  52/**
  53 * DOC: overview
  54 *
  55 * A CRTC represents the overall display pipeline. It receives pixel data from
  56 * &drm_plane and blends them together. The &drm_display_mode is also attached
  57 * to the CRTC, specifying display timings. On the output side the data is fed
  58 * to one or more &drm_encoder, which are then each connected to one
  59 * &drm_connector.
  60 *
  61 * To create a CRTC, a KMS drivers allocates and zeroes an instances of
  62 * &struct drm_crtc (possibly as part of a larger structure) and registers it
  63 * with a call to drm_crtc_init_with_planes().
  64 *
  65 * The CRTC is also the entry point for legacy modeset operations, see
  66 * &drm_crtc_funcs.set_config, legacy plane operations, see
  67 * &drm_crtc_funcs.page_flip and &drm_crtc_funcs.cursor_set2, and other legacy
  68 * operations like &drm_crtc_funcs.gamma_set. For atomic drivers all these
  69 * features are controlled through &drm_property and
  70 * &drm_mode_config_funcs.atomic_check and &drm_mode_config_funcs.atomic_check.
  71 */
  72
  73/**
  74 * drm_crtc_from_index - find the registered CRTC at an index
  75 * @dev: DRM device
  76 * @idx: index of registered CRTC to find for
  77 *
  78 * Given a CRTC index, return the registered CRTC from DRM device's
  79 * list of CRTCs with matching index. This is the inverse of drm_crtc_index().
  80 * It's useful in the vblank callbacks (like &drm_driver.enable_vblank or
  81 * &drm_driver.disable_vblank), since that still deals with indices instead
  82 * of pointers to &struct drm_crtc."
  83 */
  84struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx)
  85{
  86        struct drm_crtc *crtc;
  87
  88        drm_for_each_crtc(crtc, dev)
  89                if (idx == crtc->index)
  90                        return crtc;
  91
  92        return NULL;
  93}
  94EXPORT_SYMBOL(drm_crtc_from_index);
  95
  96int drm_crtc_force_disable(struct drm_crtc *crtc)
  97{
  98        struct drm_mode_set set = {
  99                .crtc = crtc,
 100        };
 101
 102        WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
 103
 104        return drm_mode_set_config_internal(&set);
 105}
 106
 107static unsigned int drm_num_crtcs(struct drm_device *dev)
 108{
 109        unsigned int num = 0;
 110        struct drm_crtc *tmp;
 111
 112        drm_for_each_crtc(tmp, dev) {
 113                num++;
 114        }
 115
 116        return num;
 117}
 118
 119int drm_crtc_register_all(struct drm_device *dev)
 120{
 121        struct drm_crtc *crtc;
 122        int ret = 0;
 123
 124        drm_for_each_crtc(crtc, dev) {
 125                drm_debugfs_crtc_add(crtc);
 126
 127                if (crtc->funcs->late_register)
 128                        ret = crtc->funcs->late_register(crtc);
 129                if (ret)
 130                        return ret;
 131        }
 132
 133        return 0;
 134}
 135
 136void drm_crtc_unregister_all(struct drm_device *dev)
 137{
 138        struct drm_crtc *crtc;
 139
 140        drm_for_each_crtc(crtc, dev) {
 141                if (crtc->funcs->early_unregister)
 142                        crtc->funcs->early_unregister(crtc);
 143                drm_debugfs_crtc_remove(crtc);
 144        }
 145}
 146
 147static int drm_crtc_crc_init(struct drm_crtc *crtc)
 148{
 149#ifdef CONFIG_DEBUG_FS
 150        spin_lock_init(&crtc->crc.lock);
 151        init_waitqueue_head(&crtc->crc.wq);
 152        crtc->crc.source = kstrdup("auto", GFP_KERNEL);
 153        if (!crtc->crc.source)
 154                return -ENOMEM;
 155#endif
 156        return 0;
 157}
 158
 159static void drm_crtc_crc_fini(struct drm_crtc *crtc)
 160{
 161#ifdef CONFIG_DEBUG_FS
 162        kfree(crtc->crc.source);
 163#endif
 164}
 165
 166static const struct dma_fence_ops drm_crtc_fence_ops;
 167
 168static struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
 169{
 170        BUG_ON(fence->ops != &drm_crtc_fence_ops);
 171        return container_of(fence->lock, struct drm_crtc, fence_lock);
 172}
 173
 174static const char *drm_crtc_fence_get_driver_name(struct dma_fence *fence)
 175{
 176        struct drm_crtc *crtc = fence_to_crtc(fence);
 177
 178        return crtc->dev->driver->name;
 179}
 180
 181static const char *drm_crtc_fence_get_timeline_name(struct dma_fence *fence)
 182{
 183        struct drm_crtc *crtc = fence_to_crtc(fence);
 184
 185        return crtc->timeline_name;
 186}
 187
 188static const struct dma_fence_ops drm_crtc_fence_ops = {
 189        .get_driver_name = drm_crtc_fence_get_driver_name,
 190        .get_timeline_name = drm_crtc_fence_get_timeline_name,
 191};
 192
 193struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
 194{
 195        struct dma_fence *fence;
 196
 197        fence = kzalloc(sizeof(*fence), GFP_KERNEL);
 198        if (!fence)
 199                return NULL;
 200
 201        dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock,
 202                       crtc->fence_context, ++crtc->fence_seqno);
 203
 204        return fence;
 205}
 206
 207/**
 208 * drm_crtc_init_with_planes - Initialise a new CRTC object with
 209 *    specified primary and cursor planes.
 210 * @dev: DRM device
 211 * @crtc: CRTC object to init
 212 * @primary: Primary plane for CRTC
 213 * @cursor: Cursor plane for CRTC
 214 * @funcs: callbacks for the new CRTC
 215 * @name: printf style format string for the CRTC name, or NULL for default name
 216 *
 217 * Inits a new object created as base part of a driver crtc object. Drivers
 218 * should use this function instead of drm_crtc_init(), which is only provided
 219 * for backwards compatibility with drivers which do not yet support universal
 220 * planes). For really simple hardware which has only 1 plane look at
 221 * drm_simple_display_pipe_init() instead.
 222 *
 223 * Returns:
 224 * Zero on success, error code on failure.
 225 */
 226int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 227                              struct drm_plane *primary,
 228                              struct drm_plane *cursor,
 229                              const struct drm_crtc_funcs *funcs,
 230                              const char *name, ...)
 231{
 232        struct drm_mode_config *config = &dev->mode_config;
 233        int ret;
 234
 235        WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
 236        WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
 237
 238        /* crtc index is used with 32bit bitmasks */
 239        if (WARN_ON(config->num_crtc >= 32))
 240                return -EINVAL;
 241
 242        WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
 243                (!funcs->atomic_destroy_state ||
 244                 !funcs->atomic_duplicate_state));
 245
 246        crtc->dev = dev;
 247        crtc->funcs = funcs;
 248
 249        INIT_LIST_HEAD(&crtc->commit_list);
 250        spin_lock_init(&crtc->commit_lock);
 251
 252        drm_modeset_lock_init(&crtc->mutex);
 253        ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
 254        if (ret)
 255                return ret;
 256
 257        if (name) {
 258                va_list ap;
 259
 260                va_start(ap, name);
 261                crtc->name = kvasprintf(GFP_KERNEL, name, ap);
 262                va_end(ap);
 263        } else {
 264                crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
 265                                       drm_num_crtcs(dev));
 266        }
 267        if (!crtc->name) {
 268                drm_mode_object_unregister(dev, &crtc->base);
 269                return -ENOMEM;
 270        }
 271
 272        crtc->fence_context = dma_fence_context_alloc(1);
 273        spin_lock_init(&crtc->fence_lock);
 274        snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),
 275                 "CRTC:%d-%s", crtc->base.id, crtc->name);
 276
 277        crtc->base.properties = &crtc->properties;
 278
 279        list_add_tail(&crtc->head, &config->crtc_list);
 280        crtc->index = config->num_crtc++;
 281
 282        crtc->primary = primary;
 283        crtc->cursor = cursor;
 284        if (primary && !primary->possible_crtcs)
 285                primary->possible_crtcs = drm_crtc_mask(crtc);
 286        if (cursor && !cursor->possible_crtcs)
 287                cursor->possible_crtcs = drm_crtc_mask(crtc);
 288
 289        ret = drm_crtc_crc_init(crtc);
 290        if (ret) {
 291                drm_mode_object_unregister(dev, &crtc->base);
 292                return ret;
 293        }
 294
 295        if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
 296                drm_object_attach_property(&crtc->base, config->prop_active, 0);
 297                drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
 298                drm_object_attach_property(&crtc->base,
 299                                           config->prop_out_fence_ptr, 0);
 300                drm_object_attach_property(&crtc->base,
 301                                           config->prop_vrr_enabled, 0);
 302        }
 303
 304        return 0;
 305}
 306EXPORT_SYMBOL(drm_crtc_init_with_planes);
 307
 308/**
 309 * drm_crtc_cleanup - Clean up the core crtc usage
 310 * @crtc: CRTC to cleanup
 311 *
 312 * This function cleans up @crtc and removes it from the DRM mode setting
 313 * core. Note that the function does *not* free the crtc structure itself,
 314 * this is the responsibility of the caller.
 315 */
 316void drm_crtc_cleanup(struct drm_crtc *crtc)
 317{
 318        struct drm_device *dev = crtc->dev;
 319
 320        /* Note that the crtc_list is considered to be static; should we
 321         * remove the drm_crtc at runtime we would have to decrement all
 322         * the indices on the drm_crtc after us in the crtc_list.
 323         */
 324
 325        drm_crtc_crc_fini(crtc);
 326
 327        kfree(crtc->gamma_store);
 328        crtc->gamma_store = NULL;
 329
 330        drm_modeset_lock_fini(&crtc->mutex);
 331
 332        drm_mode_object_unregister(dev, &crtc->base);
 333        list_del(&crtc->head);
 334        dev->mode_config.num_crtc--;
 335
 336        WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
 337        if (crtc->state && crtc->funcs->atomic_destroy_state)
 338                crtc->funcs->atomic_destroy_state(crtc, crtc->state);
 339
 340        kfree(crtc->name);
 341
 342        memset(crtc, 0, sizeof(*crtc));
 343}
 344EXPORT_SYMBOL(drm_crtc_cleanup);
 345
 346/**
 347 * drm_mode_getcrtc - get CRTC configuration
 348 * @dev: drm device for the ioctl
 349 * @data: data pointer for the ioctl
 350 * @file_priv: drm file for the ioctl call
 351 *
 352 * Construct a CRTC configuration structure to return to the user.
 353 *
 354 * Called by the user via ioctl.
 355 *
 356 * Returns:
 357 * Zero on success, negative errno on failure.
 358 */
 359int drm_mode_getcrtc(struct drm_device *dev,
 360                     void *data, struct drm_file *file_priv)
 361{
 362        struct drm_mode_crtc *crtc_resp = data;
 363        struct drm_crtc *crtc;
 364        struct drm_plane *plane;
 365
 366        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 367                return -EOPNOTSUPP;
 368
 369        crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
 370        if (!crtc)
 371                return -ENOENT;
 372
 373        plane = crtc->primary;
 374
 375        crtc_resp->gamma_size = crtc->gamma_size;
 376
 377        drm_modeset_lock(&plane->mutex, NULL);
 378        if (plane->state && plane->state->fb)
 379                crtc_resp->fb_id = plane->state->fb->base.id;
 380        else if (!plane->state && plane->fb)
 381                crtc_resp->fb_id = plane->fb->base.id;
 382        else
 383                crtc_resp->fb_id = 0;
 384
 385        if (plane->state) {
 386                crtc_resp->x = plane->state->src_x >> 16;
 387                crtc_resp->y = plane->state->src_y >> 16;
 388        }
 389        drm_modeset_unlock(&plane->mutex);
 390
 391        drm_modeset_lock(&crtc->mutex, NULL);
 392        if (crtc->state) {
 393                if (crtc->state->enable) {
 394                        drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
 395                        crtc_resp->mode_valid = 1;
 396                } else {
 397                        crtc_resp->mode_valid = 0;
 398                }
 399        } else {
 400                crtc_resp->x = crtc->x;
 401                crtc_resp->y = crtc->y;
 402
 403                if (crtc->enabled) {
 404                        drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
 405                        crtc_resp->mode_valid = 1;
 406
 407                } else {
 408                        crtc_resp->mode_valid = 0;
 409                }
 410        }
 411        if (!file_priv->aspect_ratio_allowed)
 412                crtc_resp->mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
 413        drm_modeset_unlock(&crtc->mutex);
 414
 415        return 0;
 416}
 417
 418static int __drm_mode_set_config_internal(struct drm_mode_set *set,
 419                                          struct drm_modeset_acquire_ctx *ctx)
 420{
 421        struct drm_crtc *crtc = set->crtc;
 422        struct drm_framebuffer *fb;
 423        struct drm_crtc *tmp;
 424        int ret;
 425
 426        WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
 427
 428        /*
 429         * NOTE: ->set_config can also disable other crtcs (if we steal all
 430         * connectors from it), hence we need to refcount the fbs across all
 431         * crtcs. Atomic modeset will have saner semantics ...
 432         */
 433        drm_for_each_crtc(tmp, crtc->dev) {
 434                struct drm_plane *plane = tmp->primary;
 435
 436                plane->old_fb = plane->fb;
 437        }
 438
 439        fb = set->fb;
 440
 441        ret = crtc->funcs->set_config(set, ctx);
 442        if (ret == 0) {
 443                struct drm_plane *plane = crtc->primary;
 444
 445                plane->crtc = fb ? crtc : NULL;
 446                plane->fb = fb;
 447        }
 448
 449        drm_for_each_crtc(tmp, crtc->dev) {
 450                struct drm_plane *plane = tmp->primary;
 451
 452                if (plane->fb)
 453                        drm_framebuffer_get(plane->fb);
 454                if (plane->old_fb)
 455                        drm_framebuffer_put(plane->old_fb);
 456                plane->old_fb = NULL;
 457        }
 458
 459        return ret;
 460}
 461
 462/**
 463 * drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
 464 * @set: modeset config to set
 465 *
 466 * This is a little helper to wrap internal calls to the
 467 * &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
 468 * correct refcounting dance.
 469 *
 470 * This should only be used by non-atomic legacy drivers.
 471 *
 472 * Returns:
 473 * Zero on success, negative errno on failure.
 474 */
 475int drm_mode_set_config_internal(struct drm_mode_set *set)
 476{
 477        WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev));
 478
 479        return __drm_mode_set_config_internal(set, NULL);
 480}
 481EXPORT_SYMBOL(drm_mode_set_config_internal);
 482
 483/**
 484 * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
 485 *     CRTC viewport
 486 * @crtc: CRTC that framebuffer will be displayed on
 487 * @x: x panning
 488 * @y: y panning
 489 * @mode: mode that framebuffer will be displayed under
 490 * @fb: framebuffer to check size of
 491 */
 492int drm_crtc_check_viewport(const struct drm_crtc *crtc,
 493                            int x, int y,
 494                            const struct drm_display_mode *mode,
 495                            const struct drm_framebuffer *fb)
 496
 497{
 498        int hdisplay, vdisplay;
 499
 500        drm_mode_get_hv_timing(mode, &hdisplay, &vdisplay);
 501
 502        if (crtc->state &&
 503            drm_rotation_90_or_270(crtc->primary->state->rotation))
 504                swap(hdisplay, vdisplay);
 505
 506        return drm_framebuffer_check_src_coords(x << 16, y << 16,
 507                                                hdisplay << 16, vdisplay << 16,
 508                                                fb);
 509}
 510EXPORT_SYMBOL(drm_crtc_check_viewport);
 511
 512/**
 513 * drm_mode_setcrtc - set CRTC configuration
 514 * @dev: drm device for the ioctl
 515 * @data: data pointer for the ioctl
 516 * @file_priv: drm file for the ioctl call
 517 *
 518 * Build a new CRTC configuration based on user request.
 519 *
 520 * Called by the user via ioctl.
 521 *
 522 * Returns:
 523 * Zero on success, negative errno on failure.
 524 */
 525int drm_mode_setcrtc(struct drm_device *dev, void *data,
 526                     struct drm_file *file_priv)
 527{
 528        struct drm_mode_config *config = &dev->mode_config;
 529        struct drm_mode_crtc *crtc_req = data;
 530        struct drm_crtc *crtc;
 531        struct drm_plane *plane;
 532        struct drm_connector **connector_set = NULL, *connector;
 533        struct drm_framebuffer *fb = NULL;
 534        struct drm_display_mode *mode = NULL;
 535        struct drm_mode_set set;
 536        uint32_t __user *set_connectors_ptr;
 537        struct drm_modeset_acquire_ctx ctx;
 538        int ret;
 539        int i;
 540
 541        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 542                return -EOPNOTSUPP;
 543
 544        /*
 545         * Universal plane src offsets are only 16.16, prevent havoc for
 546         * drivers using universal plane code internally.
 547         */
 548        if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
 549                return -ERANGE;
 550
 551        crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
 552        if (!crtc) {
 553                DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
 554                return -ENOENT;
 555        }
 556        DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
 557
 558        plane = crtc->primary;
 559
 560        /* allow disabling with the primary plane leased */
 561        if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id))
 562                return -EACCES;
 563
 564        mutex_lock(&crtc->dev->mode_config.mutex);
 565        DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
 566                                   DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
 567
 568        if (crtc_req->mode_valid) {
 569                /* If we have a mode we need a framebuffer. */
 570                /* If we pass -1, set the mode with the currently bound fb */
 571                if (crtc_req->fb_id == -1) {
 572                        struct drm_framebuffer *old_fb;
 573
 574                        if (plane->state)
 575                                old_fb = plane->state->fb;
 576                        else
 577                                old_fb = plane->fb;
 578
 579                        if (!old_fb) {
 580                                DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
 581                                ret = -EINVAL;
 582                                goto out;
 583                        }
 584
 585                        fb = old_fb;
 586                        /* Make refcounting symmetric with the lookup path. */
 587                        drm_framebuffer_get(fb);
 588                } else {
 589                        fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
 590                        if (!fb) {
 591                                DRM_DEBUG_KMS("Unknown FB ID%d\n",
 592                                                crtc_req->fb_id);
 593                                ret = -ENOENT;
 594                                goto out;
 595                        }
 596                }
 597
 598                mode = drm_mode_create(dev);
 599                if (!mode) {
 600                        ret = -ENOMEM;
 601                        goto out;
 602                }
 603                if (!file_priv->aspect_ratio_allowed &&
 604                    (crtc_req->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK) != DRM_MODE_FLAG_PIC_AR_NONE) {
 605                        DRM_DEBUG_KMS("Unexpected aspect-ratio flag bits\n");
 606                        ret = -EINVAL;
 607                        goto out;
 608                }
 609
 610
 611                ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode);
 612                if (ret) {
 613                        DRM_DEBUG_KMS("Invalid mode (ret=%d, status=%s)\n",
 614                                      ret, drm_get_mode_status_name(mode->status));
 615                        drm_mode_debug_printmodeline(mode);
 616                        goto out;
 617                }
 618
 619                /*
 620                 * Check whether the primary plane supports the fb pixel format.
 621                 * Drivers not implementing the universal planes API use a
 622                 * default formats list provided by the DRM core which doesn't
 623                 * match real hardware capabilities. Skip the check in that
 624                 * case.
 625                 */
 626                if (!plane->format_default) {
 627                        ret = drm_plane_check_pixel_format(plane,
 628                                                           fb->format->format,
 629                                                           fb->modifier);
 630                        if (ret) {
 631                                struct drm_format_name_buf format_name;
 632                                DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
 633                                              drm_get_format_name(fb->format->format,
 634                                                                  &format_name),
 635                                              fb->modifier);
 636                                goto out;
 637                        }
 638                }
 639
 640                ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
 641                                              mode, fb);
 642                if (ret)
 643                        goto out;
 644
 645        }
 646
 647        if (crtc_req->count_connectors == 0 && mode) {
 648                DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
 649                ret = -EINVAL;
 650                goto out;
 651        }
 652
 653        if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
 654                DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
 655                          crtc_req->count_connectors);
 656                ret = -EINVAL;
 657                goto out;
 658        }
 659
 660        if (crtc_req->count_connectors > 0) {
 661                u32 out_id;
 662
 663                /* Avoid unbounded kernel memory allocation */
 664                if (crtc_req->count_connectors > config->num_connector) {
 665                        ret = -EINVAL;
 666                        goto out;
 667                }
 668
 669                connector_set = kmalloc_array(crtc_req->count_connectors,
 670                                              sizeof(struct drm_connector *),
 671                                              GFP_KERNEL);
 672                if (!connector_set) {
 673                        ret = -ENOMEM;
 674                        goto out;
 675                }
 676
 677                for (i = 0; i < crtc_req->count_connectors; i++) {
 678                        connector_set[i] = NULL;
 679                        set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
 680                        if (get_user(out_id, &set_connectors_ptr[i])) {
 681                                ret = -EFAULT;
 682                                goto out;
 683                        }
 684
 685                        connector = drm_connector_lookup(dev, file_priv, out_id);
 686                        if (!connector) {
 687                                DRM_DEBUG_KMS("Connector id %d unknown\n",
 688                                                out_id);
 689                                ret = -ENOENT;
 690                                goto out;
 691                        }
 692                        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 693                                        connector->base.id,
 694                                        connector->name);
 695
 696                        connector_set[i] = connector;
 697                }
 698        }
 699
 700        set.crtc = crtc;
 701        set.x = crtc_req->x;
 702        set.y = crtc_req->y;
 703        set.mode = mode;
 704        set.connectors = connector_set;
 705        set.num_connectors = crtc_req->count_connectors;
 706        set.fb = fb;
 707
 708        if (drm_drv_uses_atomic_modeset(dev))
 709                ret = crtc->funcs->set_config(&set, &ctx);
 710        else
 711                ret = __drm_mode_set_config_internal(&set, &ctx);
 712
 713out:
 714        if (fb)
 715                drm_framebuffer_put(fb);
 716
 717        if (connector_set) {
 718                for (i = 0; i < crtc_req->count_connectors; i++) {
 719                        if (connector_set[i])
 720                                drm_connector_put(connector_set[i]);
 721                }
 722        }
 723        kfree(connector_set);
 724        drm_mode_destroy(dev, mode);
 725
 726        /* In case we need to retry... */
 727        connector_set = NULL;
 728        fb = NULL;
 729        mode = NULL;
 730
 731        DRM_MODESET_LOCK_ALL_END(ctx, ret);
 732        mutex_unlock(&crtc->dev->mode_config.mutex);
 733
 734        return ret;
 735}
 736
 737int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
 738                               struct drm_property *property,
 739                               uint64_t value)
 740{
 741        int ret = -EINVAL;
 742        struct drm_crtc *crtc = obj_to_crtc(obj);
 743
 744        if (crtc->funcs->set_property)
 745                ret = crtc->funcs->set_property(crtc, property, value);
 746        if (!ret)
 747                drm_object_property_set_value(obj, property, value);
 748
 749        return ret;
 750}
 751