forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/drm_mode_config.c
....@@ -20,9 +20,15 @@
2020 * OF THIS SOFTWARE.
2121 */
2222
23
+#include <linux/uaccess.h>
24
+
25
+#include <drm/drm_drv.h>
2326 #include <drm/drm_encoder.h>
27
+#include <drm/drm_file.h>
28
+#include <drm/drm_managed.h>
2429 #include <drm/drm_mode_config.h>
25
-#include <drm/drmP.h>
30
+#include <drm/drm_print.h>
31
+#include <linux/dma-resv.h>
2632
2733 #include "drm_crtc_internal.h"
2834 #include "drm_internal.h"
....@@ -97,8 +103,7 @@
97103 struct drm_connector_list_iter conn_iter;
98104
99105 if (!drm_core_check_feature(dev, DRIVER_MODESET))
100
- return -EINVAL;
101
-
106
+ return -EOPNOTSUPP;
102107
103108 mutex_lock(&file_priv->fbs_lock);
104109 count = 0;
....@@ -298,6 +303,13 @@
298303 return -ENOMEM;
299304 dev->mode_config.prop_crtc_id = prop;
300305
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
+
301313 prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
302314 "ACTIVE");
303315 if (!prop)
....@@ -310,6 +322,12 @@
310322 if (!prop)
311323 return -ENOMEM;
312324 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;
313331
314332 prop = drm_property_create(dev,
315333 DRM_MODE_PROP_BLOB,
....@@ -347,20 +365,6 @@
347365 dev->mode_config.gamma_lut_size_property = prop;
348366
349367 prop = drm_property_create(dev,
350
- DRM_MODE_PROP_BLOB,
351
- "CUBIC_LUT", 0);
352
- if (!prop)
353
- return -ENOMEM;
354
- dev->mode_config.cubic_lut_property = prop;
355
-
356
- prop = drm_property_create_range(dev,
357
- DRM_MODE_PROP_IMMUTABLE,
358
- "CUBIC_LUT_SIZE", 0, UINT_MAX);
359
- if (!prop)
360
- return -ENOMEM;
361
- dev->mode_config.cubic_lut_size_property = prop;
362
-
363
- prop = drm_property_create(dev,
364368 DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
365369 "IN_FORMATS", 0);
366370 if (!prop)
....@@ -370,8 +374,14 @@
370374 return 0;
371375 }
372376
377
+static void drm_mode_config_init_release(struct drm_device *dev, void *ptr)
378
+{
379
+ drm_mode_config_cleanup(dev);
380
+}
381
+
373382 /**
374
- * drm_mode_config_init - initialize DRM mode_configuration structure
383
+ * drmm_mode_config_init - managed DRM mode_configuration structure
384
+ * initialization
375385 * @dev: DRM device
376386 *
377387 * Initialize @dev's mode_config structure, used for tracking the graphics
....@@ -381,9 +391,15 @@
381391 * problem, since this should happen single threaded at init time. It is the
382392 * driver's problem to ensure this guarantee.
383393 *
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.
384398 */
385
-void drm_mode_config_init(struct drm_device *dev)
399
+int drmm_mode_config_init(struct drm_device *dev)
386400 {
401
+ int ret;
402
+
387403 mutex_init(&dev->mode_config.mutex);
388404 drm_modeset_lock_init(&dev->mode_config.connection_mutex);
389405 mutex_init(&dev->mode_config.idr_mutex);
....@@ -396,7 +412,8 @@
396412 INIT_LIST_HEAD(&dev->mode_config.property_list);
397413 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
398414 INIT_LIST_HEAD(&dev->mode_config.plane_list);
399
- idr_init(&dev->mode_config.crtc_idr);
415
+ INIT_LIST_HEAD(&dev->mode_config.privobj_list);
416
+ idr_init(&dev->mode_config.object_idr);
400417 idr_init(&dev->mode_config.tile_idr);
401418 ida_init(&dev->mode_config.connector_ida);
402419 spin_lock_init(&dev->mode_config.connector_list_lock);
....@@ -404,7 +421,11 @@
404421 init_llist_head(&dev->mode_config.connector_free_list);
405422 INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn);
406423
407
- drm_mode_create_standard_properties(dev);
424
+ ret = drm_mode_create_standard_properties(dev);
425
+ if (ret) {
426
+ drm_mode_config_cleanup(dev);
427
+ return ret;
428
+ }
408429
409430 /* Just to be sure */
410431 dev->mode_config.num_fb = 0;
....@@ -412,8 +433,38 @@
412433 dev->mode_config.num_crtc = 0;
413434 dev->mode_config.num_encoder = 0;
414435 dev->mode_config.num_total_plane = 0;
436
+
437
+ if (IS_ENABLED(CONFIG_LOCKDEP)) {
438
+ struct drm_modeset_acquire_ctx modeset_ctx;
439
+ struct ww_acquire_ctx resv_ctx;
440
+ struct dma_resv resv;
441
+ int ret;
442
+
443
+ dma_resv_init(&resv);
444
+
445
+ drm_modeset_acquire_init(&modeset_ctx, 0);
446
+ ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
447
+ &modeset_ctx);
448
+ if (ret == -EDEADLK)
449
+ ret = drm_modeset_backoff(&modeset_ctx);
450
+
451
+ ww_acquire_init(&resv_ctx, &reservation_ww_class);
452
+ ret = dma_resv_lock(&resv, &resv_ctx);
453
+ if (ret == -EDEADLK)
454
+ dma_resv_lock_slow(&resv, &resv_ctx);
455
+
456
+ dma_resv_unlock(&resv);
457
+ ww_acquire_fini(&resv_ctx);
458
+
459
+ drm_modeset_drop_locks(&modeset_ctx);
460
+ drm_modeset_acquire_fini(&modeset_ctx);
461
+ dma_resv_fini(&resv);
462
+ }
463
+
464
+ return drmm_add_action_or_reset(dev, drm_mode_config_init_release,
465
+ NULL);
415466 }
416
-EXPORT_SYMBOL(drm_mode_config_init);
467
+EXPORT_SYMBOL(drmm_mode_config_init);
417468
418469 /**
419470 * drm_mode_config_cleanup - free up DRM mode_config info
....@@ -426,7 +477,8 @@
426477 * teardown time, no locking is required. It's the driver's job to ensure that
427478 * this guarantee actually holds true.
428479 *
429
- * FIXME: cleanup any dangling user buffer objects too
480
+ * FIXME: With the managed drmm_mode_config_init() it is no longer necessary for
481
+ * drivers to explicitly call this function.
430482 */
431483 void drm_mode_config_cleanup(struct drm_device *dev)
432484 {
....@@ -492,6 +544,7 @@
492544 WARN_ON(!list_empty(&dev->mode_config.fb_list));
493545 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
494546 struct drm_printer p = drm_debug_printer("[leaked fb]");
547
+
495548 drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
496549 drm_framebuffer_print_info(&p, 1, fb);
497550 drm_framebuffer_free(&fb->base.refcount);
....@@ -499,7 +552,94 @@
499552
500553 ida_destroy(&dev->mode_config.connector_ida);
501554 idr_destroy(&dev->mode_config.tile_idr);
502
- idr_destroy(&dev->mode_config.crtc_idr);
555
+ idr_destroy(&dev->mode_config.object_idr);
503556 drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
504557 }
505558 EXPORT_SYMBOL(drm_mode_config_cleanup);
559
+
560
+static u32 full_encoder_mask(struct drm_device *dev)
561
+{
562
+ struct drm_encoder *encoder;
563
+ u32 encoder_mask = 0;
564
+
565
+ drm_for_each_encoder(encoder, dev)
566
+ encoder_mask |= drm_encoder_mask(encoder);
567
+
568
+ return encoder_mask;
569
+}
570
+
571
+/*
572
+ * For some reason we want the encoder itself included in
573
+ * possible_clones. Make life easy for drivers by allowing them
574
+ * to leave possible_clones unset if no cloning is possible.
575
+ */
576
+static void fixup_encoder_possible_clones(struct drm_encoder *encoder)
577
+{
578
+ if (encoder->possible_clones == 0)
579
+ encoder->possible_clones = drm_encoder_mask(encoder);
580
+}
581
+
582
+static void validate_encoder_possible_clones(struct drm_encoder *encoder)
583
+{
584
+ struct drm_device *dev = encoder->dev;
585
+ u32 encoder_mask = full_encoder_mask(dev);
586
+ struct drm_encoder *other;
587
+
588
+ drm_for_each_encoder(other, dev) {
589
+ WARN(!!(encoder->possible_clones & drm_encoder_mask(other)) !=
590
+ !!(other->possible_clones & drm_encoder_mask(encoder)),
591
+ "possible_clones mismatch: "
592
+ "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x vs. "
593
+ "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x\n",
594
+ encoder->base.id, encoder->name,
595
+ drm_encoder_mask(encoder), encoder->possible_clones,
596
+ other->base.id, other->name,
597
+ drm_encoder_mask(other), other->possible_clones);
598
+ }
599
+
600
+ WARN((encoder->possible_clones & drm_encoder_mask(encoder)) == 0 ||
601
+ (encoder->possible_clones & ~encoder_mask) != 0,
602
+ "Bogus possible_clones: "
603
+ "[ENCODER:%d:%s] possible_clones=0x%x (full encoder mask=0x%x)\n",
604
+ encoder->base.id, encoder->name,
605
+ encoder->possible_clones, encoder_mask);
606
+}
607
+
608
+static u32 full_crtc_mask(struct drm_device *dev)
609
+{
610
+ struct drm_crtc *crtc;
611
+ u32 crtc_mask = 0;
612
+
613
+ drm_for_each_crtc(crtc, dev)
614
+ crtc_mask |= drm_crtc_mask(crtc);
615
+
616
+ return crtc_mask;
617
+}
618
+
619
+static void validate_encoder_possible_crtcs(struct drm_encoder *encoder)
620
+{
621
+ u32 crtc_mask = full_crtc_mask(encoder->dev);
622
+
623
+ WARN((encoder->possible_crtcs & crtc_mask) == 0 ||
624
+ (encoder->possible_crtcs & ~crtc_mask) != 0,
625
+ "Bogus possible_crtcs: "
626
+ "[ENCODER:%d:%s] possible_crtcs=0x%x (full crtc mask=0x%x)\n",
627
+ encoder->base.id, encoder->name,
628
+ encoder->possible_crtcs, crtc_mask);
629
+}
630
+
631
+void drm_mode_config_validate(struct drm_device *dev)
632
+{
633
+ struct drm_encoder *encoder;
634
+
635
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
636
+ return;
637
+
638
+ drm_for_each_encoder(encoder, dev)
639
+ fixup_encoder_possible_clones(encoder);
640
+
641
+ drm_for_each_encoder(encoder, dev) {
642
+ validate_encoder_possible_clones(encoder);
643
+ validate_encoder_possible_crtcs(encoder);
644
+ }
645
+}