linux/drivers/gpu/drm/drm_mode_config.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/uaccess.h>
  24
  25#include <drm/drm_drv.h>
  26#include <drm/drm_encoder.h>
  27#include <drm/drm_file.h>
  28#include <drm/drm_managed.h>
  29#include <drm/drm_mode_config.h>
  30#include <drm/drm_print.h>
  31#include <linux/dma-resv.h>
  32
  33#include "drm_crtc_internal.h"
  34#include "drm_internal.h"
  35
  36int drm_modeset_register_all(struct drm_device *dev)
  37{
  38        int ret;
  39
  40        ret = drm_plane_register_all(dev);
  41        if (ret)
  42                goto err_plane;
  43
  44        ret = drm_crtc_register_all(dev);
  45        if  (ret)
  46                goto err_crtc;
  47
  48        ret = drm_encoder_register_all(dev);
  49        if (ret)
  50                goto err_encoder;
  51
  52        ret = drm_connector_register_all(dev);
  53        if (ret)
  54                goto err_connector;
  55
  56        return 0;
  57
  58err_connector:
  59        drm_encoder_unregister_all(dev);
  60err_encoder:
  61        drm_crtc_unregister_all(dev);
  62err_crtc:
  63        drm_plane_unregister_all(dev);
  64err_plane:
  65        return ret;
  66}
  67
  68void drm_modeset_unregister_all(struct drm_device *dev)
  69{
  70        drm_connector_unregister_all(dev);
  71        drm_encoder_unregister_all(dev);
  72        drm_crtc_unregister_all(dev);
  73        drm_plane_unregister_all(dev);
  74}
  75
  76/**
  77 * drm_mode_getresources - get graphics configuration
  78 * @dev: drm device for the ioctl
  79 * @data: data pointer for the ioctl
  80 * @file_priv: drm file for the ioctl call
  81 *
  82 * Construct a set of configuration description structures and return
  83 * them to the user, including CRTC, connector and framebuffer configuration.
  84 *
  85 * Called by the user via ioctl.
  86 *
  87 * Returns:
  88 * Zero on success, negative errno on failure.
  89 */
  90int drm_mode_getresources(struct drm_device *dev, void *data,
  91                          struct drm_file *file_priv)
  92{
  93        struct drm_mode_card_res *card_res = data;
  94        struct drm_framebuffer *fb;
  95        struct drm_connector *connector;
  96        struct drm_crtc *crtc;
  97        struct drm_encoder *encoder;
  98        int count, ret = 0;
  99        uint32_t __user *fb_id;
 100        uint32_t __user *crtc_id;
 101        uint32_t __user *connector_id;
 102        uint32_t __user *encoder_id;
 103        struct drm_connector_list_iter conn_iter;
 104
 105        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 106                return -EOPNOTSUPP;
 107
 108        mutex_lock(&file_priv->fbs_lock);
 109        count = 0;
 110        fb_id = u64_to_user_ptr(card_res->fb_id_ptr);
 111        list_for_each_entry(fb, &file_priv->fbs, filp_head) {
 112                if (count < card_res->count_fbs &&
 113                    put_user(fb->base.id, fb_id + count)) {
 114                        mutex_unlock(&file_priv->fbs_lock);
 115                        return -EFAULT;
 116                }
 117                count++;
 118        }
 119        card_res->count_fbs = count;
 120        mutex_unlock(&file_priv->fbs_lock);
 121
 122        card_res->max_height = dev->mode_config.max_height;
 123        card_res->min_height = dev->mode_config.min_height;
 124        card_res->max_width = dev->mode_config.max_width;
 125        card_res->min_width = dev->mode_config.min_width;
 126
 127        count = 0;
 128        crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
 129        drm_for_each_crtc(crtc, dev) {
 130                if (drm_lease_held(file_priv, crtc->base.id)) {
 131                        if (count < card_res->count_crtcs &&
 132                            put_user(crtc->base.id, crtc_id + count))
 133                                return -EFAULT;
 134                        count++;
 135                }
 136        }
 137        card_res->count_crtcs = count;
 138
 139        count = 0;
 140        encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr);
 141        drm_for_each_encoder(encoder, dev) {
 142                if (count < card_res->count_encoders &&
 143                    put_user(encoder->base.id, encoder_id + count))
 144                        return -EFAULT;
 145                count++;
 146        }
 147        card_res->count_encoders = count;
 148
 149        drm_connector_list_iter_begin(dev, &conn_iter);
 150        count = 0;
 151        connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
 152        drm_for_each_connector_iter(connector, &conn_iter) {
 153                /* only expose writeback connectors if userspace understands them */
 154                if (!file_priv->writeback_connectors &&
 155                    (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK))
 156                        continue;
 157
 158                if (drm_lease_held(file_priv, connector->base.id)) {
 159                        if (count < card_res->count_connectors &&
 160                            put_user(connector->base.id, connector_id + count)) {
 161                                drm_connector_list_iter_end(&conn_iter);
 162                                return -EFAULT;
 163                        }
 164                        count++;
 165                }
 166        }
 167        card_res->count_connectors = count;
 168        drm_connector_list_iter_end(&conn_iter);
 169
 170        return ret;
 171}
 172
 173/**
 174 * drm_mode_config_reset - call ->reset callbacks
 175 * @dev: drm device
 176 *
 177 * This functions calls all the crtc's, encoder's and connector's ->reset
 178 * callback. Drivers can use this in e.g. their driver load or resume code to
 179 * reset hardware and software state.
 180 */
 181void drm_mode_config_reset(struct drm_device *dev)
 182{
 183        struct drm_crtc *crtc;
 184        struct drm_plane *plane;
 185        struct drm_encoder *encoder;
 186        struct drm_connector *connector;
 187        struct drm_connector_list_iter conn_iter;
 188
 189        drm_for_each_plane(plane, dev)
 190                if (plane->funcs->reset)
 191                        plane->funcs->reset(plane);
 192
 193        drm_for_each_crtc(crtc, dev)
 194                if (crtc->funcs->reset)
 195                        crtc->funcs->reset(crtc);
 196
 197        drm_for_each_encoder(encoder, dev)
 198                if (encoder->funcs && encoder->funcs->reset)
 199                        encoder->funcs->reset(encoder);
 200
 201        drm_connector_list_iter_begin(dev, &conn_iter);
 202        drm_for_each_connector_iter(connector, &conn_iter)
 203                if (connector->funcs->reset)
 204                        connector->funcs->reset(connector);
 205        drm_connector_list_iter_end(&conn_iter);
 206}
 207EXPORT_SYMBOL(drm_mode_config_reset);
 208
 209/*
 210 * Global properties
 211 */
 212static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
 213        { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
 214        { DRM_PLANE_TYPE_PRIMARY, "Primary" },
 215        { DRM_PLANE_TYPE_CURSOR, "Cursor" },
 216};
 217
 218static int drm_mode_create_standard_properties(struct drm_device *dev)
 219{
 220        struct drm_property *prop;
 221        int ret;
 222
 223        ret = drm_connector_create_standard_properties(dev);
 224        if (ret)
 225                return ret;
 226
 227        prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
 228                                        "type", drm_plane_type_enum_list,
 229                                        ARRAY_SIZE(drm_plane_type_enum_list));
 230        if (!prop)
 231                return -ENOMEM;
 232        dev->mode_config.plane_type_property = prop;
 233
 234        prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
 235                        "SRC_X", 0, UINT_MAX);
 236        if (!prop)
 237                return -ENOMEM;
 238        dev->mode_config.prop_src_x = prop;
 239
 240        prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
 241                        "SRC_Y", 0, UINT_MAX);
 242        if (!prop)
 243                return -ENOMEM;
 244        dev->mode_config.prop_src_y = prop;
 245
 246        prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
 247                        "SRC_W", 0, UINT_MAX);
 248        if (!prop)
 249                return -ENOMEM;
 250        dev->mode_config.prop_src_w = prop;
 251
 252        prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
 253                        "SRC_H", 0, UINT_MAX);
 254        if (!prop)
 255                return -ENOMEM;
 256        dev->mode_config.prop_src_h = prop;
 257
 258        prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
 259                        "CRTC_X", INT_MIN, INT_MAX);
 260        if (!prop)
 261                return -ENOMEM;
 262        dev->mode_config.prop_crtc_x = prop;
 263
 264        prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
 265                        "CRTC_Y", INT_MIN, INT_MAX);
 266        if (!prop)
 267                return -ENOMEM;
 268        dev->mode_config.prop_crtc_y = prop;
 269
 270        prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
 271                        "CRTC_W", 0, INT_MAX);
 272        if (!prop)
 273                return -ENOMEM;
 274        dev->mode_config.prop_crtc_w = prop;
 275
 276        prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
 277                        "CRTC_H", 0, INT_MAX);
 278        if (!prop)
 279                return -ENOMEM;
 280        dev->mode_config.prop_crtc_h = prop;
 281
 282        prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
 283                        "FB_ID", DRM_MODE_OBJECT_FB);
 284        if (!prop)
 285                return -ENOMEM;
 286        dev->mode_config.prop_fb_id = prop;
 287
 288        prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
 289                        "IN_FENCE_FD", -1, INT_MAX);
 290        if (!prop)
 291                return -ENOMEM;
 292        dev->mode_config.prop_in_fence_fd = prop;
 293
 294        prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
 295                        "OUT_FENCE_PTR", 0, U64_MAX);
 296        if (!prop)
 297                return -ENOMEM;
 298        dev->mode_config.prop_out_fence_ptr = prop;
 299
 300        prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
 301                        "CRTC_ID", DRM_MODE_OBJECT_CRTC);
 302        if (!prop)
 303                return -ENOMEM;
 304        dev->mode_config.prop_crtc_id = prop;
 305
 306        prop = drm_property_create(dev,
 307                        DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
 308                        "FB_DAMAGE_CLIPS", 0);
 309        if (!prop)
 310                return -ENOMEM;
 311        dev->mode_config.prop_fb_damage_clips = prop;
 312
 313        prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
 314                        "ACTIVE");
 315        if (!prop)
 316                return -ENOMEM;
 317        dev->mode_config.prop_active = prop;
 318
 319        prop = drm_property_create(dev,
 320                        DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
 321                        "MODE_ID", 0);
 322        if (!prop)
 323                return -ENOMEM;
 324        dev->mode_config.prop_mode_id = prop;
 325
 326        prop = drm_property_create_bool(dev, 0,
 327                        "VRR_ENABLED");
 328        if (!prop)
 329                return -ENOMEM;
 330        dev->mode_config.prop_vrr_enabled = prop;
 331
 332        prop = drm_property_create(dev,
 333                        DRM_MODE_PROP_BLOB,
 334                        "DEGAMMA_LUT", 0);
 335        if (!prop)
 336                return -ENOMEM;
 337        dev->mode_config.degamma_lut_property = prop;
 338
 339        prop = drm_property_create_range(dev,
 340                        DRM_MODE_PROP_IMMUTABLE,
 341                        "DEGAMMA_LUT_SIZE", 0, UINT_MAX);
 342        if (!prop)
 343                return -ENOMEM;
 344        dev->mode_config.degamma_lut_size_property = prop;
 345
 346        prop = drm_property_create(dev,
 347                        DRM_MODE_PROP_BLOB,
 348                        "CTM", 0);
 349        if (!prop)
 350                return -ENOMEM;
 351        dev->mode_config.ctm_property = prop;
 352
 353        prop = drm_property_create(dev,
 354                        DRM_MODE_PROP_BLOB,
 355                        "GAMMA_LUT", 0);
 356        if (!prop)
 357                return -ENOMEM;
 358        dev->mode_config.gamma_lut_property = prop;
 359
 360        prop = drm_property_create_range(dev,
 361                        DRM_MODE_PROP_IMMUTABLE,
 362                        "GAMMA_LUT_SIZE", 0, UINT_MAX);
 363        if (!prop)
 364                return -ENOMEM;
 365        dev->mode_config.gamma_lut_size_property = prop;
 366
 367        prop = drm_property_create(dev,
 368                                   DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
 369                                   "IN_FORMATS", 0);
 370        if (!prop)
 371                return -ENOMEM;
 372        dev->mode_config.modifiers_property = prop;
 373
 374        return 0;
 375}
 376
 377static void drm_mode_config_init_release(struct drm_device *dev, void *ptr)
 378{
 379        drm_mode_config_cleanup(dev);
 380}
 381
 382/**
 383 * drmm_mode_config_init - managed DRM mode_configuration structure
 384 *      initialization
 385 * @dev: DRM device
 386 *
 387 * Initialize @dev's mode_config structure, used for tracking the graphics
 388 * configuration of @dev.
 389 *
 390 * Since this initializes the modeset locks, no locking is possible. Which is no
 391 * problem, since this should happen single threaded at init time. It is the
 392 * driver's problem to ensure this guarantee.
 393 *
 394 * Cleanup is automatically handled through registering drm_mode_config_cleanup
 395 * with drmm_add_action().
 396 *
 397 * Returns: 0 on success, negative error value on failure.
 398 */
 399int drmm_mode_config_init(struct drm_device *dev)
 400{
 401        mutex_init(&dev->mode_config.mutex);
 402        drm_modeset_lock_init(&dev->mode_config.connection_mutex);
 403        mutex_init(&dev->mode_config.idr_mutex);
 404        mutex_init(&dev->mode_config.fb_lock);
 405        mutex_init(&dev->mode_config.blob_lock);
 406        INIT_LIST_HEAD(&dev->mode_config.fb_list);
 407        INIT_LIST_HEAD(&dev->mode_config.crtc_list);
 408        INIT_LIST_HEAD(&dev->mode_config.connector_list);
 409        INIT_LIST_HEAD(&dev->mode_config.encoder_list);
 410        INIT_LIST_HEAD(&dev->mode_config.property_list);
 411        INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
 412        INIT_LIST_HEAD(&dev->mode_config.plane_list);
 413        INIT_LIST_HEAD(&dev->mode_config.privobj_list);
 414        idr_init(&dev->mode_config.object_idr);
 415        idr_init(&dev->mode_config.tile_idr);
 416        ida_init(&dev->mode_config.connector_ida);
 417        spin_lock_init(&dev->mode_config.connector_list_lock);
 418
 419        init_llist_head(&dev->mode_config.connector_free_list);
 420        INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn);
 421
 422        drm_mode_create_standard_properties(dev);
 423
 424        /* Just to be sure */
 425        dev->mode_config.num_fb = 0;
 426        dev->mode_config.num_connector = 0;
 427        dev->mode_config.num_crtc = 0;
 428        dev->mode_config.num_encoder = 0;
 429        dev->mode_config.num_total_plane = 0;
 430
 431        if (IS_ENABLED(CONFIG_LOCKDEP)) {
 432                struct drm_modeset_acquire_ctx modeset_ctx;
 433                struct ww_acquire_ctx resv_ctx;
 434                struct dma_resv resv;
 435                int ret;
 436
 437                dma_resv_init(&resv);
 438
 439                drm_modeset_acquire_init(&modeset_ctx, 0);
 440                ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
 441                                       &modeset_ctx);
 442                if (ret == -EDEADLK)
 443                        ret = drm_modeset_backoff(&modeset_ctx);
 444
 445                ww_acquire_init(&resv_ctx, &reservation_ww_class);
 446                ret = dma_resv_lock(&resv, &resv_ctx);
 447                if (ret == -EDEADLK)
 448                        dma_resv_lock_slow(&resv, &resv_ctx);
 449
 450                dma_resv_unlock(&resv);
 451                ww_acquire_fini(&resv_ctx);
 452
 453                drm_modeset_drop_locks(&modeset_ctx);
 454                drm_modeset_acquire_fini(&modeset_ctx);
 455                dma_resv_fini(&resv);
 456        }
 457
 458        return drmm_add_action_or_reset(dev, drm_mode_config_init_release,
 459                                        NULL);
 460}
 461EXPORT_SYMBOL(drmm_mode_config_init);
 462
 463/**
 464 * drm_mode_config_cleanup - free up DRM mode_config info
 465 * @dev: DRM device
 466 *
 467 * Free up all the connectors and CRTCs associated with this DRM device, then
 468 * free up the framebuffers and associated buffer objects.
 469 *
 470 * Note that since this /should/ happen single-threaded at driver/device
 471 * teardown time, no locking is required. It's the driver's job to ensure that
 472 * this guarantee actually holds true.
 473 *
 474 * FIXME: With the managed drmm_mode_config_init() it is no longer necessary for
 475 * drivers to explicitly call this function.
 476 */
 477void drm_mode_config_cleanup(struct drm_device *dev)
 478{
 479        struct drm_connector *connector;
 480        struct drm_connector_list_iter conn_iter;
 481        struct drm_crtc *crtc, *ct;
 482        struct drm_encoder *encoder, *enct;
 483        struct drm_framebuffer *fb, *fbt;
 484        struct drm_property *property, *pt;
 485        struct drm_property_blob *blob, *bt;
 486        struct drm_plane *plane, *plt;
 487
 488        list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 489                                 head) {
 490                encoder->funcs->destroy(encoder);
 491        }
 492
 493        drm_connector_list_iter_begin(dev, &conn_iter);
 494        drm_for_each_connector_iter(connector, &conn_iter) {
 495                /* drm_connector_list_iter holds an full reference to the
 496                 * current connector itself, which means it is inherently safe
 497                 * against unreferencing the current connector - but not against
 498                 * deleting it right away. */
 499                drm_connector_put(connector);
 500        }
 501        drm_connector_list_iter_end(&conn_iter);
 502        /* connector_iter drops references in a work item. */
 503        flush_work(&dev->mode_config.connector_free_work);
 504        if (WARN_ON(!list_empty(&dev->mode_config.connector_list))) {
 505                drm_connector_list_iter_begin(dev, &conn_iter);
 506                drm_for_each_connector_iter(connector, &conn_iter)
 507                        DRM_ERROR("connector %s leaked!\n", connector->name);
 508                drm_connector_list_iter_end(&conn_iter);
 509        }
 510
 511        list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
 512                                 head) {
 513                drm_property_destroy(dev, property);
 514        }
 515
 516        list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
 517                                 head) {
 518                plane->funcs->destroy(plane);
 519        }
 520
 521        list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
 522                crtc->funcs->destroy(crtc);
 523        }
 524
 525        list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
 526                                 head_global) {
 527                drm_property_blob_put(blob);
 528        }
 529
 530        /*
 531         * Single-threaded teardown context, so it's not required to grab the
 532         * fb_lock to protect against concurrent fb_list access. Contrary, it
 533         * would actually deadlock with the drm_framebuffer_cleanup function.
 534         *
 535         * Also, if there are any framebuffers left, that's a driver leak now,
 536         * so politely WARN about this.
 537         */
 538        WARN_ON(!list_empty(&dev->mode_config.fb_list));
 539        list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
 540                struct drm_printer p = drm_debug_printer("[leaked fb]");
 541
 542                drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
 543                drm_framebuffer_print_info(&p, 1, fb);
 544                drm_framebuffer_free(&fb->base.refcount);
 545        }
 546
 547        ida_destroy(&dev->mode_config.connector_ida);
 548        idr_destroy(&dev->mode_config.tile_idr);
 549        idr_destroy(&dev->mode_config.object_idr);
 550        drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
 551}
 552EXPORT_SYMBOL(drm_mode_config_cleanup);
 553
 554static u32 full_encoder_mask(struct drm_device *dev)
 555{
 556        struct drm_encoder *encoder;
 557        u32 encoder_mask = 0;
 558
 559        drm_for_each_encoder(encoder, dev)
 560                encoder_mask |= drm_encoder_mask(encoder);
 561
 562        return encoder_mask;
 563}
 564
 565/*
 566 * For some reason we want the encoder itself included in
 567 * possible_clones. Make life easy for drivers by allowing them
 568 * to leave possible_clones unset if no cloning is possible.
 569 */
 570static void fixup_encoder_possible_clones(struct drm_encoder *encoder)
 571{
 572        if (encoder->possible_clones == 0)
 573                encoder->possible_clones = drm_encoder_mask(encoder);
 574}
 575
 576static void validate_encoder_possible_clones(struct drm_encoder *encoder)
 577{
 578        struct drm_device *dev = encoder->dev;
 579        u32 encoder_mask = full_encoder_mask(dev);
 580        struct drm_encoder *other;
 581
 582        drm_for_each_encoder(other, dev) {
 583                WARN(!!(encoder->possible_clones & drm_encoder_mask(other)) !=
 584                     !!(other->possible_clones & drm_encoder_mask(encoder)),
 585                     "possible_clones mismatch: "
 586                     "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x vs. "
 587                     "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x\n",
 588                     encoder->base.id, encoder->name,
 589                     drm_encoder_mask(encoder), encoder->possible_clones,
 590                     other->base.id, other->name,
 591                     drm_encoder_mask(other), other->possible_clones);
 592        }
 593
 594        WARN((encoder->possible_clones & drm_encoder_mask(encoder)) == 0 ||
 595             (encoder->possible_clones & ~encoder_mask) != 0,
 596             "Bogus possible_clones: "
 597             "[ENCODER:%d:%s] possible_clones=0x%x (full encoder mask=0x%x)\n",
 598             encoder->base.id, encoder->name,
 599             encoder->possible_clones, encoder_mask);
 600}
 601
 602static u32 full_crtc_mask(struct drm_device *dev)
 603{
 604        struct drm_crtc *crtc;
 605        u32 crtc_mask = 0;
 606
 607        drm_for_each_crtc(crtc, dev)
 608                crtc_mask |= drm_crtc_mask(crtc);
 609
 610        return crtc_mask;
 611}
 612
 613static void validate_encoder_possible_crtcs(struct drm_encoder *encoder)
 614{
 615        u32 crtc_mask = full_crtc_mask(encoder->dev);
 616
 617        WARN((encoder->possible_crtcs & crtc_mask) == 0 ||
 618             (encoder->possible_crtcs & ~crtc_mask) != 0,
 619             "Bogus possible_crtcs: "
 620             "[ENCODER:%d:%s] possible_crtcs=0x%x (full crtc mask=0x%x)\n",
 621             encoder->base.id, encoder->name,
 622             encoder->possible_crtcs, crtc_mask);
 623}
 624
 625void drm_mode_config_validate(struct drm_device *dev)
 626{
 627        struct drm_encoder *encoder;
 628        struct drm_crtc *crtc;
 629        struct drm_plane *plane;
 630        u32 primary_with_crtc = 0, cursor_with_crtc = 0;
 631        unsigned int num_primary = 0;
 632
 633        if (!drm_core_check_feature(dev, DRIVER_MODESET))
 634                return;
 635
 636        drm_for_each_encoder(encoder, dev)
 637                fixup_encoder_possible_clones(encoder);
 638
 639        drm_for_each_encoder(encoder, dev) {
 640                validate_encoder_possible_clones(encoder);
 641                validate_encoder_possible_crtcs(encoder);
 642        }
 643
 644        drm_for_each_crtc(crtc, dev) {
 645                WARN(!crtc->primary, "Missing primary plane on [CRTC:%d:%s]\n",
 646                     crtc->base.id, crtc->name);
 647
 648                WARN(crtc->cursor && crtc->funcs->cursor_set,
 649                     "[CRTC:%d:%s] must not have both a cursor plane and a cursor_set func",
 650                     crtc->base.id, crtc->name);
 651                WARN(crtc->cursor && crtc->funcs->cursor_set2,
 652                     "[CRTC:%d:%s] must not have both a cursor plane and a cursor_set2 func",
 653                     crtc->base.id, crtc->name);
 654                WARN(crtc->cursor && crtc->funcs->cursor_move,
 655                     "[CRTC:%d:%s] must not have both a cursor plane and a cursor_move func",
 656                     crtc->base.id, crtc->name);
 657
 658                if (crtc->primary) {
 659                        WARN(!(crtc->primary->possible_crtcs & drm_crtc_mask(crtc)),
 660                             "Bogus primary plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n",
 661                             crtc->primary->base.id, crtc->primary->name,
 662                             crtc->base.id, crtc->name);
 663                        WARN(primary_with_crtc & drm_plane_mask(crtc->primary),
 664                             "Primary plane [PLANE:%d:%s] used for multiple CRTCs",
 665                             crtc->primary->base.id, crtc->primary->name);
 666                        primary_with_crtc |= drm_plane_mask(crtc->primary);
 667                }
 668                if (crtc->cursor) {
 669                        WARN(!(crtc->cursor->possible_crtcs & drm_crtc_mask(crtc)),
 670                             "Bogus cursor plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n",
 671                             crtc->cursor->base.id, crtc->cursor->name,
 672                             crtc->base.id, crtc->name);
 673                        WARN(cursor_with_crtc & drm_plane_mask(crtc->cursor),
 674                             "Cursor plane [PLANE:%d:%s] used for multiple CRTCs",
 675                             crtc->cursor->base.id, crtc->cursor->name);
 676                        cursor_with_crtc |= drm_plane_mask(crtc->cursor);
 677                }
 678        }
 679
 680        drm_for_each_plane(plane, dev) {
 681                if (plane->type == DRM_PLANE_TYPE_PRIMARY)
 682                        num_primary++;
 683        }
 684
 685        WARN(num_primary != dev->mode_config.num_crtc,
 686             "Must have as many primary planes as there are CRTCs, but have %u primary planes and %u CRTCs",
 687             num_primary, dev->mode_config.num_crtc);
 688}
 689