root/drivers/gpu/drm/drm_crtc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. drm_crtc_from_index
  2. drm_crtc_force_disable
  3. drm_num_crtcs
  4. drm_crtc_register_all
  5. drm_crtc_unregister_all
  6. drm_crtc_crc_init
  7. drm_crtc_crc_fini
  8. fence_to_crtc
  9. drm_crtc_fence_get_driver_name
  10. drm_crtc_fence_get_timeline_name
  11. drm_crtc_create_fence
  12. drm_crtc_init_with_planes
  13. drm_crtc_cleanup
  14. drm_mode_getcrtc
  15. __drm_mode_set_config_internal
  16. drm_mode_set_config_internal
  17. drm_crtc_check_viewport
  18. drm_mode_setcrtc
  19. drm_mode_crtc_set_obj_prop

   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  */
  84 struct 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 }
  94 EXPORT_SYMBOL(drm_crtc_from_index);
  95 
  96 int 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 
 107 static 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 
 119 int 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 
 136 void 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 
 147 static 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 
 159 static void drm_crtc_crc_fini(struct drm_crtc *crtc)
 160 {
 161 #ifdef CONFIG_DEBUG_FS
 162         kfree(crtc->crc.source);
 163 #endif
 164 }
 165 
 166 static const struct dma_fence_ops drm_crtc_fence_ops;
 167 
 168 static 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 
 174 static 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 
 181 static 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 
 188 static 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 
 193 struct 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  */
 226 int 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 }
 306 EXPORT_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  */
 316 void 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 }
 344 EXPORT_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  */
 359 int 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 
 418 static 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  */
 475 int 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 }
 481 EXPORT_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  */
 492 int 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 }
 510 EXPORT_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  */
 525 int 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 
 713 out:
 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 
 737 int 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 }

/* [<][>][^][v][top][bottom][index][help] */