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                if (drm_debugfs_crtc_add(crtc))
 126                        DRM_ERROR("Failed to initialize debugfs entry for CRTC '%s'.\n",
 127                                  crtc->name);
 128
 129                if (crtc->funcs->late_register)
 130                        ret = crtc->funcs->late_register(crtc);
 131                if (ret)
 132                        return ret;
 133        }
 134
 135        return 0;
 136}
 137
 138void drm_crtc_unregister_all(struct drm_device *dev)
 139{
 140        struct drm_crtc *crtc;
 141
 142        drm_for_each_crtc(crtc, dev) {
 143                if (crtc->funcs->early_unregister)
 144                        crtc->funcs->early_unregister(crtc);
 145                drm_debugfs_crtc_remove(crtc);
 146        }
 147}
 148
 149static int drm_crtc_crc_init(struct drm_crtc *crtc)
 150{
 151#ifdef CONFIG_DEBUG_FS
 152        spin_lock_init(&crtc->crc.lock);
 153        init_waitqueue_head(&crtc->crc.wq);
 154        crtc->crc.source = kstrdup("auto", GFP_KERNEL);
 155        if (!crtc->crc.source)
 156                return -ENOMEM;
 157#endif
 158        return 0;
 159}
 160
 161static void drm_crtc_crc_fini(struct drm_crtc *crtc)
 162{
 163#ifdef CONFIG_DEBUG_FS
 164        kfree(crtc->crc.source);
 165#endif
 166}
 167
 168static const struct dma_fence_ops drm_crtc_fence_ops;
 169
 170static struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
 171{
 172        BUG_ON(fence->ops != &drm_crtc_fence_ops);
 173        return container_of(fence->lock, struct drm_crtc, fence_lock);
 174}
 175
 176static const char *drm_crtc_fence_get_driver_name(struct dma_fence *fence)
 177{
 178        struct drm_crtc *crtc = fence_to_crtc(fence);
 179
 180        return crtc->dev->driver->name;
 181}
 182
 183static const char *drm_crtc_fence_get_timeline_name(struct dma_fence *fence)
 184{
 185        struct drm_crtc *crtc = fence_to_crtc(fence);
 186
 187        return crtc->timeline_name;
 188}
 189
 190static const struct dma_fence_ops drm_crtc_fence_ops = {
 191        .get_driver_name = drm_crtc_fence_get_driver_name,
 192        .get_timeline_name = drm_crtc_fence_get_timeline_name,
 193};
 194
 195struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
 196{
 197        struct dma_fence *fence;
 198
 199        fence = kzalloc(sizeof(*fence), GFP_KERNEL);
 200        if (!fence)
 201                return NULL;
 202
 203        dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock,
 204                       crtc->fence_context, ++crtc->fence_seqno);
 205
 206        return fence;
 207}
 208
 209/**
 210 * drm_crtc_init_with_planes - Initialise a new CRTC object with
 211 *    specified primary and cursor planes.
 212 * @dev: DRM device
 213 * @crtc: CRTC object to init
 214 * @primary: Primary plane for CRTC
 215 * @cursor: Cursor plane for CRTC
 216 * @funcs: callbacks for the new CRTC
 217 * @name: printf style format string for the CRTC name, or NULL for default name
 218 *
 219 * Inits a new object created as base part of a driver crtc object. Drivers
 220 * should use this function instead of drm_crtc_init(), which is only provided
 221 * for backwards compatibility with drivers which do not yet support universal
 222 * planes). For really simple hardware which has only 1 plane look at
 223 * drm_simple_display_pipe_init() instead.
 224 *
 225 * Returns:
 226 * Zero on success, error code on failure.
 227 */
 228int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 229                              struct drm_plane *primary,
 230                              struct drm_plane *cursor,
 231                              const struct drm_crtc_funcs *funcs,
 232                              const char *name, ...)
 233{
 234        struct drm_mode_config *config = &dev->mode_config;
 235        int ret;
 236
 237        WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
 238        WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
 239
 240        /* crtc index is used with 32bit bitmasks */
 241        if (WARN_ON(config->num_crtc >= 32))
 242                return -EINVAL;
 243
 244        WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
 245                (!funcs->atomic_destroy_state ||
 246                 !funcs->atomic_duplicate_state));
 247
 248        crtc->dev = dev;
 249        crtc->funcs = funcs;
 250
 251        INIT_LIST_HEAD(&crtc->commit_list);
 252        spin_lock_init(&crtc->commit_lock);
 253
 254        drm_modeset_lock_init(&crtc->mutex);
 255        ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
 256        if (ret)
 257                return ret;
 258
 259        if (name) {
 260                va_list ap;
 261
 262                va_start(ap, name);
 263                crtc->name = kvasprintf(GFP_KERNEL, name, ap);
 264                va_end(ap);
 265        } else {
 266                crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
 267                                       drm_num_crtcs(dev));
 268        }
 269        if (!crtc->name) {
 270                drm_mode_object_unregister(dev, &crtc->base);
 271                return -ENOMEM;
 272        }
 273
 274        crtc->fence_context = dma_fence_context_alloc(1);
 275        spin_lock_init(&crtc->fence_lock);
 276        snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),
 277                 "CRTC:%d-%s", crtc->base.id, crtc->name);
 278
 279        crtc->base.properties = &crtc->properties;
 280
 281        list_add_tail(&crtc->head, &config->crtc_list);
 282        crtc->index = config->num_crtc++;
 283
 284        crtc->primary = primary;
 285        crtc->cursor = cursor;
 286        if (primary && !primary->possible_crtcs)
 287                primary->possible_crtcs = drm_crtc_mask(crtc);
 288        if (cursor && !cursor->possible_crtcs)
 289                cursor->possible_crtcs = drm_crtc_mask(crtc);
 290
 291        ret = drm_crtc_crc_init(crtc);
 292        if (ret) {
 293                drm_mode_object_unregister(dev, &crtc->base);
 294                return ret;
 295        }
 296
 297        if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
 298                drm_object_attach_property(&crtc->base, config->prop_active, 0);
 299                drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
 300                drm_object_attach_property(&crtc->base,
 301                                           config->prop_out_fence_ptr, 0);
 302                drm_object_attach_property(&crtc->base,
 303                                           config->prop_vrr_enabled, 0);
 304        }
 305
 306        return 0;
 307}
 308EXPORT_SYMBOL(drm_crtc_init_with_planes);
 309
 310/**
 311 * drm_crtc_cleanup - Clean up the core crtc usage
 312 * @crtc: CRTC to cleanup
 313 *
 314 * This function cleans up @crtc and removes it from the DRM mode setting
 315 * core. Note that the function does *not* free the crtc structure itself,
 316 * this is the responsibility of the caller.
 317 */
 318void drm_crtc_cleanup(struct drm_crtc *crtc)
 319{
 320        struct drm_device *dev = crtc->dev;
 321
 322        /* Note that the crtc_list is considered to be static; should we
 323         * remove the drm_crtc at runtime we would have to decrement all
 324         * the indices on the drm_crtc after us in the crtc_list.
 325         */
 326
 327        drm_crtc_crc_fini(crtc);
 328
 329        kfree(crtc->gamma_store);
 330        crtc->gamma_store = NULL;
 331
 332        drm_modeset_lock_fini(&crtc->mutex);
 333
 334        drm_mode_object_unregister(dev, &crtc->base);
 335        list_del(&crtc->head);
 336        dev->mode_config.num_crtc--;
 337
 338        WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
 339        if (crtc->state && crtc->funcs->atomic_destroy_state)
 340                crtc->funcs->atomic_destroy_state(crtc, crtc->state);
 341
 342        kfree(crtc->name);
 343
 344        memset(crtc, 0, sizeof(*crtc));
 345}
 346EXPORT_SYMBOL(drm_crtc_cleanup);
 347
 348/**
 349 * drm_mode_getcrtc - get CRTC configuration
 350 * @dev: drm device for the ioctl
 351 * @data: data pointer for the ioctl
 352 * @file_priv: drm file for the ioctl call
 353 *
 354 * Construct a CRTC configuration structure to return to the user.
 355 *
 356 * Called by the user via ioctl.
 357 *
 358 * Returns:
 359 * Zero on success, negative errno on failure.
 360 */
 361int drm_mode_getcrtc(struct drm_device *dev,
 362                     void *data, struct drm_file *file_priv)
 363{
 364        struct drm_mode_crtc *crtc_resp = data;
 365        struct drm_crtc *crtc;
 366        struct drm_plane *plane;
 367
 368        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 369                return -EOPNOTSUPP;
 370
 371        crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
 372        if (!crtc)
 373                return -ENOENT;
 374
 375        plane = crtc->primary;
 376
 377        crtc_resp->gamma_size = crtc->gamma_size;
 378
 379        drm_modeset_lock(&plane->mutex, NULL);
 380        if (plane->state && plane->state->fb)
 381                crtc_resp->fb_id = plane->state->fb->base.id;
 382        else if (!plane->state && plane->fb)
 383                crtc_resp->fb_id = plane->fb->base.id;
 384        else
 385                crtc_resp->fb_id = 0;
 386
 387        if (plane->state) {
 388                crtc_resp->x = plane->state->src_x >> 16;
 389                crtc_resp->y = plane->state->src_y >> 16;
 390        }
 391        drm_modeset_unlock(&plane->mutex);
 392
 393        drm_modeset_lock(&crtc->mutex, NULL);
 394        if (crtc->state) {
 395                if (crtc->state->enable) {
 396                        drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
 397                        crtc_resp->mode_valid = 1;
 398                } else {
 399                        crtc_resp->mode_valid = 0;
 400                }
 401        } else {
 402                crtc_resp->x = crtc->x;
 403                crtc_resp->y = crtc->y;
 404
 405                if (crtc->enabled) {
 406                        drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
 407                        crtc_resp->mode_valid = 1;
 408
 409                } else {
 410                        crtc_resp->mode_valid = 0;
 411                }
 412        }
 413        if (!file_priv->aspect_ratio_allowed)
 414                crtc_resp->mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
 415        drm_modeset_unlock(&crtc->mutex);
 416
 417        return 0;
 418}
 419
 420static int __drm_mode_set_config_internal(struct drm_mode_set *set,
 421                                          struct drm_modeset_acquire_ctx *ctx)
 422{
 423        struct drm_crtc *crtc = set->crtc;
 424        struct drm_framebuffer *fb;
 425        struct drm_crtc *tmp;
 426        int ret;
 427
 428        WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
 429
 430        /*
 431         * NOTE: ->set_config can also disable other crtcs (if we steal all
 432         * connectors from it), hence we need to refcount the fbs across all
 433         * crtcs. Atomic modeset will have saner semantics ...
 434         */
 435        drm_for_each_crtc(tmp, crtc->dev) {
 436                struct drm_plane *plane = tmp->primary;
 437
 438                plane->old_fb = plane->fb;
 439        }
 440
 441        fb = set->fb;
 442
 443        ret = crtc->funcs->set_config(set, ctx);
 444        if (ret == 0) {
 445                struct drm_plane *plane = crtc->primary;
 446
 447                plane->crtc = fb ? crtc : NULL;
 448                plane->fb = fb;
 449        }
 450
 451        drm_for_each_crtc(tmp, crtc->dev) {
 452                struct drm_plane *plane = tmp->primary;
 453
 454                if (plane->fb)
 455                        drm_framebuffer_get(plane->fb);
 456                if (plane->old_fb)
 457                        drm_framebuffer_put(plane->old_fb);
 458                plane->old_fb = NULL;
 459        }
 460
 461        return ret;
 462}
 463
 464/**
 465 * drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
 466 * @set: modeset config to set
 467 *
 468 * This is a little helper to wrap internal calls to the
 469 * &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
 470 * correct refcounting dance.
 471 *
 472 * This should only be used by non-atomic legacy drivers.
 473 *
 474 * Returns:
 475 * Zero on success, negative errno on failure.
 476 */
 477int drm_mode_set_config_internal(struct drm_mode_set *set)
 478{
 479        WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev));
 480
 481        return __drm_mode_set_config_internal(set, NULL);
 482}
 483EXPORT_SYMBOL(drm_mode_set_config_internal);
 484
 485/**
 486 * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
 487 *     CRTC viewport
 488 * @crtc: CRTC that framebuffer will be displayed on
 489 * @x: x panning
 490 * @y: y panning
 491 * @mode: mode that framebuffer will be displayed under
 492 * @fb: framebuffer to check size of
 493 */
 494int drm_crtc_check_viewport(const struct drm_crtc *crtc,
 495                            int x, int y,
 496                            const struct drm_display_mode *mode,
 497                            const struct drm_framebuffer *fb)
 498
 499{
 500        int hdisplay, vdisplay;
 501
 502        drm_mode_get_hv_timing(mode, &hdisplay, &vdisplay);
 503
 504        if (crtc->state &&
 505            drm_rotation_90_or_270(crtc->primary->state->rotation))
 506                swap(hdisplay, vdisplay);
 507
 508        return drm_framebuffer_check_src_coords(x << 16, y << 16,
 509                                                hdisplay << 16, vdisplay << 16,
 510                                                fb);
 511}
 512EXPORT_SYMBOL(drm_crtc_check_viewport);
 513
 514/**
 515 * drm_mode_setcrtc - set CRTC configuration
 516 * @dev: drm device for the ioctl
 517 * @data: data pointer for the ioctl
 518 * @file_priv: drm file for the ioctl call
 519 *
 520 * Build a new CRTC configuration based on user request.
 521 *
 522 * Called by the user via ioctl.
 523 *
 524 * Returns:
 525 * Zero on success, negative errno on failure.
 526 */
 527int drm_mode_setcrtc(struct drm_device *dev, void *data,
 528                     struct drm_file *file_priv)
 529{
 530        struct drm_mode_config *config = &dev->mode_config;
 531        struct drm_mode_crtc *crtc_req = data;
 532        struct drm_crtc *crtc;
 533        struct drm_plane *plane;
 534        struct drm_connector **connector_set = NULL, *connector;
 535        struct drm_framebuffer *fb = NULL;
 536        struct drm_display_mode *mode = NULL;
 537        struct drm_mode_set set;
 538        uint32_t __user *set_connectors_ptr;
 539        struct drm_modeset_acquire_ctx ctx;
 540        int ret;
 541        int i;
 542
 543        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 544                return -EOPNOTSUPP;
 545
 546        /*
 547         * Universal plane src offsets are only 16.16, prevent havoc for
 548         * drivers using universal plane code internally.
 549         */
 550        if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
 551                return -ERANGE;
 552
 553        crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
 554        if (!crtc) {
 555                DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
 556                return -ENOENT;
 557        }
 558        DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
 559
 560        plane = crtc->primary;
 561
 562        mutex_lock(&crtc->dev->mode_config.mutex);
 563        DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
 564                                   DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
 565
 566        if (crtc_req->mode_valid) {
 567                /* If we have a mode we need a framebuffer. */
 568                /* If we pass -1, set the mode with the currently bound fb */
 569                if (crtc_req->fb_id == -1) {
 570                        struct drm_framebuffer *old_fb;
 571
 572                        if (plane->state)
 573                                old_fb = plane->state->fb;
 574                        else
 575                                old_fb = plane->fb;
 576
 577                        if (!old_fb) {
 578                                DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
 579                                ret = -EINVAL;
 580                                goto out;
 581                        }
 582
 583                        fb = old_fb;
 584                        /* Make refcounting symmetric with the lookup path. */
 585                        drm_framebuffer_get(fb);
 586                } else {
 587                        fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
 588                        if (!fb) {
 589                                DRM_DEBUG_KMS("Unknown FB ID%d\n",
 590                                                crtc_req->fb_id);
 591                                ret = -ENOENT;
 592                                goto out;
 593                        }
 594                }
 595
 596                mode = drm_mode_create(dev);
 597                if (!mode) {
 598                        ret = -ENOMEM;
 599                        goto out;
 600                }
 601                if (!file_priv->aspect_ratio_allowed &&
 602                    (crtc_req->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK) != DRM_MODE_FLAG_PIC_AR_NONE) {
 603                        DRM_DEBUG_KMS("Unexpected aspect-ratio flag bits\n");
 604                        ret = -EINVAL;
 605                        goto out;
 606                }
 607
 608
 609                ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode);
 610                if (ret) {
 611                        DRM_DEBUG_KMS("Invalid mode (ret=%d, status=%s)\n",
 612                                      ret, drm_get_mode_status_name(mode->status));
 613                        drm_mode_debug_printmodeline(mode);
 614                        goto out;
 615                }
 616
 617                /*
 618                 * Check whether the primary plane supports the fb pixel format.
 619                 * Drivers not implementing the universal planes API use a
 620                 * default formats list provided by the DRM core which doesn't
 621                 * match real hardware capabilities. Skip the check in that
 622                 * case.
 623                 */
 624                if (!plane->format_default) {
 625                        ret = drm_plane_check_pixel_format(plane,
 626                                                           fb->format->format,
 627                                                           fb->modifier);
 628                        if (ret) {
 629                                struct drm_format_name_buf format_name;
 630                                DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
 631                                              drm_get_format_name(fb->format->format,
 632                                                                  &format_name),
 633                                              fb->modifier);
 634                                goto out;
 635                        }
 636                }
 637
 638                ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
 639                                              mode, fb);
 640                if (ret)
 641                        goto out;
 642
 643        }
 644
 645        if (crtc_req->count_connectors == 0 && mode) {
 646                DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
 647                ret = -EINVAL;
 648                goto out;
 649        }
 650
 651        if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
 652                DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
 653                          crtc_req->count_connectors);
 654                ret = -EINVAL;
 655                goto out;
 656        }
 657
 658        if (crtc_req->count_connectors > 0) {
 659                u32 out_id;
 660
 661                /* Avoid unbounded kernel memory allocation */
 662                if (crtc_req->count_connectors > config->num_connector) {
 663                        ret = -EINVAL;
 664                        goto out;
 665                }
 666
 667                connector_set = kmalloc_array(crtc_req->count_connectors,
 668                                              sizeof(struct drm_connector *),
 669                                              GFP_KERNEL);
 670                if (!connector_set) {
 671                        ret = -ENOMEM;
 672                        goto out;
 673                }
 674
 675                for (i = 0; i < crtc_req->count_connectors; i++) {
 676                        connector_set[i] = NULL;
 677                        set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
 678                        if (get_user(out_id, &set_connectors_ptr[i])) {
 679                                ret = -EFAULT;
 680                                goto out;
 681                        }
 682
 683                        connector = drm_connector_lookup(dev, file_priv, out_id);
 684                        if (!connector) {
 685                                DRM_DEBUG_KMS("Connector id %d unknown\n",
 686                                                out_id);
 687                                ret = -ENOENT;
 688                                goto out;
 689                        }
 690                        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 691                                        connector->base.id,
 692                                        connector->name);
 693
 694                        connector_set[i] = connector;
 695                }
 696        }
 697
 698        set.crtc = crtc;
 699        set.x = crtc_req->x;
 700        set.y = crtc_req->y;
 701        set.mode = mode;
 702        set.connectors = connector_set;
 703        set.num_connectors = crtc_req->count_connectors;
 704        set.fb = fb;
 705
 706        if (drm_drv_uses_atomic_modeset(dev))
 707                ret = crtc->funcs->set_config(&set, &ctx);
 708        else
 709                ret = __drm_mode_set_config_internal(&set, &ctx);
 710
 711out:
 712        if (fb)
 713                drm_framebuffer_put(fb);
 714
 715        if (connector_set) {
 716                for (i = 0; i < crtc_req->count_connectors; i++) {
 717                        if (connector_set[i])
 718                                drm_connector_put(connector_set[i]);
 719                }
 720        }
 721        kfree(connector_set);
 722        drm_mode_destroy(dev, mode);
 723
 724        /* In case we need to retry... */
 725        connector_set = NULL;
 726        fb = NULL;
 727        mode = NULL;
 728
 729        DRM_MODESET_LOCK_ALL_END(ctx, ret);
 730        mutex_unlock(&crtc->dev->mode_config.mutex);
 731
 732        return ret;
 733}
 734
 735int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
 736                               struct drm_property *property,
 737                               uint64_t value)
 738{
 739        int ret = -EINVAL;
 740        struct drm_crtc *crtc = obj_to_crtc(obj);
 741
 742        if (crtc->funcs->set_property)
 743                ret = crtc->funcs->set_property(crtc, property, value);
 744        if (!ret)
 745                drm_object_property_set_value(obj, property, value);
 746
 747        return ret;
 748}
 749