drm_mode_config.c (20807B)
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}