0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/uaccess.h>
0024
0025 #include <drm/drm_drv.h>
0026 #include <drm/drm_encoder.h>
0027 #include <drm/drm_file.h>
0028 #include <drm/drm_framebuffer.h>
0029 #include <drm/drm_managed.h>
0030 #include <drm/drm_mode_config.h>
0031 #include <drm/drm_print.h>
0032 #include <linux/dma-resv.h>
0033
0034 #include "drm_crtc_internal.h"
0035 #include "drm_internal.h"
0036
0037 int drm_modeset_register_all(struct drm_device *dev)
0038 {
0039 int ret;
0040
0041 ret = drm_plane_register_all(dev);
0042 if (ret)
0043 goto err_plane;
0044
0045 ret = drm_crtc_register_all(dev);
0046 if (ret)
0047 goto err_crtc;
0048
0049 ret = drm_encoder_register_all(dev);
0050 if (ret)
0051 goto err_encoder;
0052
0053 ret = drm_connector_register_all(dev);
0054 if (ret)
0055 goto err_connector;
0056
0057 return 0;
0058
0059 err_connector:
0060 drm_encoder_unregister_all(dev);
0061 err_encoder:
0062 drm_crtc_unregister_all(dev);
0063 err_crtc:
0064 drm_plane_unregister_all(dev);
0065 err_plane:
0066 return ret;
0067 }
0068
0069 void drm_modeset_unregister_all(struct drm_device *dev)
0070 {
0071 drm_connector_unregister_all(dev);
0072 drm_encoder_unregister_all(dev);
0073 drm_crtc_unregister_all(dev);
0074 drm_plane_unregister_all(dev);
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 int drm_mode_getresources(struct drm_device *dev, void *data,
0092 struct drm_file *file_priv)
0093 {
0094 struct drm_mode_card_res *card_res = data;
0095 struct drm_framebuffer *fb;
0096 struct drm_connector *connector;
0097 struct drm_crtc *crtc;
0098 struct drm_encoder *encoder;
0099 int count, ret = 0;
0100 uint32_t __user *fb_id;
0101 uint32_t __user *crtc_id;
0102 uint32_t __user *connector_id;
0103 uint32_t __user *encoder_id;
0104 struct drm_connector_list_iter conn_iter;
0105
0106 if (!drm_core_check_feature(dev, DRIVER_MODESET))
0107 return -EOPNOTSUPP;
0108
0109 mutex_lock(&file_priv->fbs_lock);
0110 count = 0;
0111 fb_id = u64_to_user_ptr(card_res->fb_id_ptr);
0112 list_for_each_entry(fb, &file_priv->fbs, filp_head) {
0113 if (count < card_res->count_fbs &&
0114 put_user(fb->base.id, fb_id + count)) {
0115 mutex_unlock(&file_priv->fbs_lock);
0116 return -EFAULT;
0117 }
0118 count++;
0119 }
0120 card_res->count_fbs = count;
0121 mutex_unlock(&file_priv->fbs_lock);
0122
0123 card_res->max_height = dev->mode_config.max_height;
0124 card_res->min_height = dev->mode_config.min_height;
0125 card_res->max_width = dev->mode_config.max_width;
0126 card_res->min_width = dev->mode_config.min_width;
0127
0128 count = 0;
0129 crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
0130 drm_for_each_crtc(crtc, dev) {
0131 if (drm_lease_held(file_priv, crtc->base.id)) {
0132 if (count < card_res->count_crtcs &&
0133 put_user(crtc->base.id, crtc_id + count))
0134 return -EFAULT;
0135 count++;
0136 }
0137 }
0138 card_res->count_crtcs = count;
0139
0140 count = 0;
0141 encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr);
0142 drm_for_each_encoder(encoder, dev) {
0143 if (count < card_res->count_encoders &&
0144 put_user(encoder->base.id, encoder_id + count))
0145 return -EFAULT;
0146 count++;
0147 }
0148 card_res->count_encoders = count;
0149
0150 drm_connector_list_iter_begin(dev, &conn_iter);
0151 count = 0;
0152 connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
0153 drm_for_each_connector_iter(connector, &conn_iter) {
0154
0155 if (!file_priv->writeback_connectors &&
0156 (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK))
0157 continue;
0158
0159 if (drm_lease_held(file_priv, connector->base.id)) {
0160 if (count < card_res->count_connectors &&
0161 put_user(connector->base.id, connector_id + count)) {
0162 drm_connector_list_iter_end(&conn_iter);
0163 return -EFAULT;
0164 }
0165 count++;
0166 }
0167 }
0168 card_res->count_connectors = count;
0169 drm_connector_list_iter_end(&conn_iter);
0170
0171 return ret;
0172 }
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 void drm_mode_config_reset(struct drm_device *dev)
0183 {
0184 struct drm_crtc *crtc;
0185 struct drm_plane *plane;
0186 struct drm_encoder *encoder;
0187 struct drm_connector *connector;
0188 struct drm_connector_list_iter conn_iter;
0189
0190 drm_for_each_plane(plane, dev)
0191 if (plane->funcs->reset)
0192 plane->funcs->reset(plane);
0193
0194 drm_for_each_crtc(crtc, dev)
0195 if (crtc->funcs->reset)
0196 crtc->funcs->reset(crtc);
0197
0198 drm_for_each_encoder(encoder, dev)
0199 if (encoder->funcs && encoder->funcs->reset)
0200 encoder->funcs->reset(encoder);
0201
0202 drm_connector_list_iter_begin(dev, &conn_iter);
0203 drm_for_each_connector_iter(connector, &conn_iter)
0204 if (connector->funcs->reset)
0205 connector->funcs->reset(connector);
0206 drm_connector_list_iter_end(&conn_iter);
0207 }
0208 EXPORT_SYMBOL(drm_mode_config_reset);
0209
0210
0211
0212
0213 static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
0214 { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
0215 { DRM_PLANE_TYPE_PRIMARY, "Primary" },
0216 { DRM_PLANE_TYPE_CURSOR, "Cursor" },
0217 };
0218
0219 static int drm_mode_create_standard_properties(struct drm_device *dev)
0220 {
0221 struct drm_property *prop;
0222 int ret;
0223
0224 ret = drm_connector_create_standard_properties(dev);
0225 if (ret)
0226 return ret;
0227
0228 prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
0229 "type", drm_plane_type_enum_list,
0230 ARRAY_SIZE(drm_plane_type_enum_list));
0231 if (!prop)
0232 return -ENOMEM;
0233 dev->mode_config.plane_type_property = prop;
0234
0235 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
0236 "SRC_X", 0, UINT_MAX);
0237 if (!prop)
0238 return -ENOMEM;
0239 dev->mode_config.prop_src_x = prop;
0240
0241 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
0242 "SRC_Y", 0, UINT_MAX);
0243 if (!prop)
0244 return -ENOMEM;
0245 dev->mode_config.prop_src_y = prop;
0246
0247 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
0248 "SRC_W", 0, UINT_MAX);
0249 if (!prop)
0250 return -ENOMEM;
0251 dev->mode_config.prop_src_w = prop;
0252
0253 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
0254 "SRC_H", 0, UINT_MAX);
0255 if (!prop)
0256 return -ENOMEM;
0257 dev->mode_config.prop_src_h = prop;
0258
0259 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
0260 "CRTC_X", INT_MIN, INT_MAX);
0261 if (!prop)
0262 return -ENOMEM;
0263 dev->mode_config.prop_crtc_x = prop;
0264
0265 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
0266 "CRTC_Y", INT_MIN, INT_MAX);
0267 if (!prop)
0268 return -ENOMEM;
0269 dev->mode_config.prop_crtc_y = prop;
0270
0271 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
0272 "CRTC_W", 0, INT_MAX);
0273 if (!prop)
0274 return -ENOMEM;
0275 dev->mode_config.prop_crtc_w = prop;
0276
0277 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
0278 "CRTC_H", 0, INT_MAX);
0279 if (!prop)
0280 return -ENOMEM;
0281 dev->mode_config.prop_crtc_h = prop;
0282
0283 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
0284 "FB_ID", DRM_MODE_OBJECT_FB);
0285 if (!prop)
0286 return -ENOMEM;
0287 dev->mode_config.prop_fb_id = prop;
0288
0289 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
0290 "IN_FENCE_FD", -1, INT_MAX);
0291 if (!prop)
0292 return -ENOMEM;
0293 dev->mode_config.prop_in_fence_fd = prop;
0294
0295 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
0296 "OUT_FENCE_PTR", 0, U64_MAX);
0297 if (!prop)
0298 return -ENOMEM;
0299 dev->mode_config.prop_out_fence_ptr = prop;
0300
0301 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
0302 "CRTC_ID", DRM_MODE_OBJECT_CRTC);
0303 if (!prop)
0304 return -ENOMEM;
0305 dev->mode_config.prop_crtc_id = prop;
0306
0307 prop = drm_property_create(dev,
0308 DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
0309 "FB_DAMAGE_CLIPS", 0);
0310 if (!prop)
0311 return -ENOMEM;
0312 dev->mode_config.prop_fb_damage_clips = prop;
0313
0314 prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
0315 "ACTIVE");
0316 if (!prop)
0317 return -ENOMEM;
0318 dev->mode_config.prop_active = prop;
0319
0320 prop = drm_property_create(dev,
0321 DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
0322 "MODE_ID", 0);
0323 if (!prop)
0324 return -ENOMEM;
0325 dev->mode_config.prop_mode_id = prop;
0326
0327 prop = drm_property_create_bool(dev, 0,
0328 "VRR_ENABLED");
0329 if (!prop)
0330 return -ENOMEM;
0331 dev->mode_config.prop_vrr_enabled = prop;
0332
0333 prop = drm_property_create(dev,
0334 DRM_MODE_PROP_BLOB,
0335 "DEGAMMA_LUT", 0);
0336 if (!prop)
0337 return -ENOMEM;
0338 dev->mode_config.degamma_lut_property = prop;
0339
0340 prop = drm_property_create_range(dev,
0341 DRM_MODE_PROP_IMMUTABLE,
0342 "DEGAMMA_LUT_SIZE", 0, UINT_MAX);
0343 if (!prop)
0344 return -ENOMEM;
0345 dev->mode_config.degamma_lut_size_property = prop;
0346
0347 prop = drm_property_create(dev,
0348 DRM_MODE_PROP_BLOB,
0349 "CTM", 0);
0350 if (!prop)
0351 return -ENOMEM;
0352 dev->mode_config.ctm_property = prop;
0353
0354 prop = drm_property_create(dev,
0355 DRM_MODE_PROP_BLOB,
0356 "GAMMA_LUT", 0);
0357 if (!prop)
0358 return -ENOMEM;
0359 dev->mode_config.gamma_lut_property = prop;
0360
0361 prop = drm_property_create_range(dev,
0362 DRM_MODE_PROP_IMMUTABLE,
0363 "GAMMA_LUT_SIZE", 0, UINT_MAX);
0364 if (!prop)
0365 return -ENOMEM;
0366 dev->mode_config.gamma_lut_size_property = prop;
0367
0368 prop = drm_property_create(dev,
0369 DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
0370 "IN_FORMATS", 0);
0371 if (!prop)
0372 return -ENOMEM;
0373 dev->mode_config.modifiers_property = prop;
0374
0375 return 0;
0376 }
0377
0378 static void drm_mode_config_init_release(struct drm_device *dev, void *ptr)
0379 {
0380 drm_mode_config_cleanup(dev);
0381 }
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400 int drmm_mode_config_init(struct drm_device *dev)
0401 {
0402 mutex_init(&dev->mode_config.mutex);
0403 drm_modeset_lock_init(&dev->mode_config.connection_mutex);
0404 mutex_init(&dev->mode_config.idr_mutex);
0405 mutex_init(&dev->mode_config.fb_lock);
0406 mutex_init(&dev->mode_config.blob_lock);
0407 INIT_LIST_HEAD(&dev->mode_config.fb_list);
0408 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
0409 INIT_LIST_HEAD(&dev->mode_config.connector_list);
0410 INIT_LIST_HEAD(&dev->mode_config.encoder_list);
0411 INIT_LIST_HEAD(&dev->mode_config.property_list);
0412 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
0413 INIT_LIST_HEAD(&dev->mode_config.plane_list);
0414 INIT_LIST_HEAD(&dev->mode_config.privobj_list);
0415 idr_init(&dev->mode_config.object_idr);
0416 idr_init(&dev->mode_config.tile_idr);
0417 ida_init(&dev->mode_config.connector_ida);
0418 spin_lock_init(&dev->mode_config.connector_list_lock);
0419
0420 init_llist_head(&dev->mode_config.connector_free_list);
0421 INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn);
0422
0423 drm_mode_create_standard_properties(dev);
0424
0425
0426 dev->mode_config.num_fb = 0;
0427 dev->mode_config.num_connector = 0;
0428 dev->mode_config.num_crtc = 0;
0429 dev->mode_config.num_encoder = 0;
0430 dev->mode_config.num_total_plane = 0;
0431
0432 if (IS_ENABLED(CONFIG_LOCKDEP)) {
0433 struct drm_modeset_acquire_ctx modeset_ctx;
0434 struct ww_acquire_ctx resv_ctx;
0435 struct dma_resv resv;
0436 int ret;
0437
0438 dma_resv_init(&resv);
0439
0440 drm_modeset_acquire_init(&modeset_ctx, 0);
0441 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
0442 &modeset_ctx);
0443 if (ret == -EDEADLK)
0444 ret = drm_modeset_backoff(&modeset_ctx);
0445
0446 ww_acquire_init(&resv_ctx, &reservation_ww_class);
0447 ret = dma_resv_lock(&resv, &resv_ctx);
0448 if (ret == -EDEADLK)
0449 dma_resv_lock_slow(&resv, &resv_ctx);
0450
0451 dma_resv_unlock(&resv);
0452 ww_acquire_fini(&resv_ctx);
0453
0454 drm_modeset_drop_locks(&modeset_ctx);
0455 drm_modeset_acquire_fini(&modeset_ctx);
0456 dma_resv_fini(&resv);
0457 }
0458
0459 return drmm_add_action_or_reset(dev, drm_mode_config_init_release,
0460 NULL);
0461 }
0462 EXPORT_SYMBOL(drmm_mode_config_init);
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478 void drm_mode_config_cleanup(struct drm_device *dev)
0479 {
0480 struct drm_connector *connector;
0481 struct drm_connector_list_iter conn_iter;
0482 struct drm_crtc *crtc, *ct;
0483 struct drm_encoder *encoder, *enct;
0484 struct drm_framebuffer *fb, *fbt;
0485 struct drm_property *property, *pt;
0486 struct drm_property_blob *blob, *bt;
0487 struct drm_plane *plane, *plt;
0488
0489 list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
0490 head) {
0491 encoder->funcs->destroy(encoder);
0492 }
0493
0494 drm_connector_list_iter_begin(dev, &conn_iter);
0495 drm_for_each_connector_iter(connector, &conn_iter) {
0496
0497
0498
0499
0500 drm_connector_put(connector);
0501 }
0502 drm_connector_list_iter_end(&conn_iter);
0503
0504 flush_work(&dev->mode_config.connector_free_work);
0505 if (WARN_ON(!list_empty(&dev->mode_config.connector_list))) {
0506 drm_connector_list_iter_begin(dev, &conn_iter);
0507 drm_for_each_connector_iter(connector, &conn_iter)
0508 DRM_ERROR("connector %s leaked!\n", connector->name);
0509 drm_connector_list_iter_end(&conn_iter);
0510 }
0511
0512 list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
0513 head) {
0514 drm_property_destroy(dev, property);
0515 }
0516
0517 list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
0518 head) {
0519 plane->funcs->destroy(plane);
0520 }
0521
0522 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
0523 crtc->funcs->destroy(crtc);
0524 }
0525
0526 list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
0527 head_global) {
0528 drm_property_blob_put(blob);
0529 }
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539 WARN_ON(!list_empty(&dev->mode_config.fb_list));
0540 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
0541 struct drm_printer p = drm_debug_printer("[leaked fb]");
0542
0543 drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
0544 drm_framebuffer_print_info(&p, 1, fb);
0545 drm_framebuffer_free(&fb->base.refcount);
0546 }
0547
0548 ida_destroy(&dev->mode_config.connector_ida);
0549 idr_destroy(&dev->mode_config.tile_idr);
0550 idr_destroy(&dev->mode_config.object_idr);
0551 drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
0552 }
0553 EXPORT_SYMBOL(drm_mode_config_cleanup);
0554
0555 static u32 full_encoder_mask(struct drm_device *dev)
0556 {
0557 struct drm_encoder *encoder;
0558 u32 encoder_mask = 0;
0559
0560 drm_for_each_encoder(encoder, dev)
0561 encoder_mask |= drm_encoder_mask(encoder);
0562
0563 return encoder_mask;
0564 }
0565
0566
0567
0568
0569
0570
0571 static void fixup_encoder_possible_clones(struct drm_encoder *encoder)
0572 {
0573 if (encoder->possible_clones == 0)
0574 encoder->possible_clones = drm_encoder_mask(encoder);
0575 }
0576
0577 static void validate_encoder_possible_clones(struct drm_encoder *encoder)
0578 {
0579 struct drm_device *dev = encoder->dev;
0580 u32 encoder_mask = full_encoder_mask(dev);
0581 struct drm_encoder *other;
0582
0583 drm_for_each_encoder(other, dev) {
0584 WARN(!!(encoder->possible_clones & drm_encoder_mask(other)) !=
0585 !!(other->possible_clones & drm_encoder_mask(encoder)),
0586 "possible_clones mismatch: "
0587 "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x vs. "
0588 "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x\n",
0589 encoder->base.id, encoder->name,
0590 drm_encoder_mask(encoder), encoder->possible_clones,
0591 other->base.id, other->name,
0592 drm_encoder_mask(other), other->possible_clones);
0593 }
0594
0595 WARN((encoder->possible_clones & drm_encoder_mask(encoder)) == 0 ||
0596 (encoder->possible_clones & ~encoder_mask) != 0,
0597 "Bogus possible_clones: "
0598 "[ENCODER:%d:%s] possible_clones=0x%x (full encoder mask=0x%x)\n",
0599 encoder->base.id, encoder->name,
0600 encoder->possible_clones, encoder_mask);
0601 }
0602
0603 static u32 full_crtc_mask(struct drm_device *dev)
0604 {
0605 struct drm_crtc *crtc;
0606 u32 crtc_mask = 0;
0607
0608 drm_for_each_crtc(crtc, dev)
0609 crtc_mask |= drm_crtc_mask(crtc);
0610
0611 return crtc_mask;
0612 }
0613
0614 static void validate_encoder_possible_crtcs(struct drm_encoder *encoder)
0615 {
0616 u32 crtc_mask = full_crtc_mask(encoder->dev);
0617
0618 WARN((encoder->possible_crtcs & crtc_mask) == 0 ||
0619 (encoder->possible_crtcs & ~crtc_mask) != 0,
0620 "Bogus possible_crtcs: "
0621 "[ENCODER:%d:%s] possible_crtcs=0x%x (full crtc mask=0x%x)\n",
0622 encoder->base.id, encoder->name,
0623 encoder->possible_crtcs, crtc_mask);
0624 }
0625
0626 void drm_mode_config_validate(struct drm_device *dev)
0627 {
0628 struct drm_encoder *encoder;
0629 struct drm_crtc *crtc;
0630 struct drm_plane *plane;
0631 u32 primary_with_crtc = 0, cursor_with_crtc = 0;
0632 unsigned int num_primary = 0;
0633
0634 if (!drm_core_check_feature(dev, DRIVER_MODESET))
0635 return;
0636
0637 drm_for_each_encoder(encoder, dev)
0638 fixup_encoder_possible_clones(encoder);
0639
0640 drm_for_each_encoder(encoder, dev) {
0641 validate_encoder_possible_clones(encoder);
0642 validate_encoder_possible_crtcs(encoder);
0643 }
0644
0645 drm_for_each_crtc(crtc, dev) {
0646 WARN(!crtc->primary, "Missing primary plane on [CRTC:%d:%s]\n",
0647 crtc->base.id, crtc->name);
0648
0649 WARN(crtc->cursor && crtc->funcs->cursor_set,
0650 "[CRTC:%d:%s] must not have both a cursor plane and a cursor_set func",
0651 crtc->base.id, crtc->name);
0652 WARN(crtc->cursor && crtc->funcs->cursor_set2,
0653 "[CRTC:%d:%s] must not have both a cursor plane and a cursor_set2 func",
0654 crtc->base.id, crtc->name);
0655 WARN(crtc->cursor && crtc->funcs->cursor_move,
0656 "[CRTC:%d:%s] must not have both a cursor plane and a cursor_move func",
0657 crtc->base.id, crtc->name);
0658
0659 if (crtc->primary) {
0660 WARN(!(crtc->primary->possible_crtcs & drm_crtc_mask(crtc)),
0661 "Bogus primary plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n",
0662 crtc->primary->base.id, crtc->primary->name,
0663 crtc->base.id, crtc->name);
0664 WARN(primary_with_crtc & drm_plane_mask(crtc->primary),
0665 "Primary plane [PLANE:%d:%s] used for multiple CRTCs",
0666 crtc->primary->base.id, crtc->primary->name);
0667 primary_with_crtc |= drm_plane_mask(crtc->primary);
0668 }
0669 if (crtc->cursor) {
0670 WARN(!(crtc->cursor->possible_crtcs & drm_crtc_mask(crtc)),
0671 "Bogus cursor plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n",
0672 crtc->cursor->base.id, crtc->cursor->name,
0673 crtc->base.id, crtc->name);
0674 WARN(cursor_with_crtc & drm_plane_mask(crtc->cursor),
0675 "Cursor plane [PLANE:%d:%s] used for multiple CRTCs",
0676 crtc->cursor->base.id, crtc->cursor->name);
0677 cursor_with_crtc |= drm_plane_mask(crtc->cursor);
0678 }
0679 }
0680
0681 drm_for_each_plane(plane, dev) {
0682 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
0683 num_primary++;
0684 }
0685
0686 WARN(num_primary != dev->mode_config.num_crtc,
0687 "Must have as many primary planes as there are CRTCs, but have %u primary planes and %u CRTCs",
0688 num_primary, dev->mode_config.num_crtc);
0689 }