forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/arm/malidp_drv.c
....@@ -1,11 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
34 * Author: Liviu Dudau <Liviu.Dudau@arm.com>
4
- *
5
- * This program is free software and is provided to you under the terms of the
6
- * GNU General Public License version 2 as published by the Free Software
7
- * Foundation, and any use by you of this program is subject to the terms
8
- * of such GNU licence.
95 *
106 * ARM Mali DP500/DP550/DP650 KMS/DRM driver
117 */
....@@ -19,17 +15,19 @@
1915 #include <linux/pm_runtime.h>
2016 #include <linux/debugfs.h>
2117
22
-#include <drm/drmP.h>
2318 #include <drm/drm_atomic.h>
2419 #include <drm/drm_atomic_helper.h>
2520 #include <drm/drm_crtc.h>
26
-#include <drm/drm_crtc_helper.h>
27
-#include <drm/drm_fb_helper.h>
21
+#include <drm/drm_drv.h>
2822 #include <drm/drm_fb_cma_helper.h>
23
+#include <drm/drm_fb_helper.h>
24
+#include <drm/drm_fourcc.h>
2925 #include <drm/drm_gem_cma_helper.h>
3026 #include <drm/drm_gem_framebuffer_helper.h>
3127 #include <drm/drm_modeset_helper.h>
3228 #include <drm/drm_of.h>
29
+#include <drm/drm_probe_helper.h>
30
+#include <drm/drm_vblank.h>
3331
3432 #include "malidp_drv.h"
3533 #include "malidp_mw.h"
....@@ -37,6 +35,8 @@
3735 #include "malidp_hw.h"
3836
3937 #define MALIDP_CONF_VALID_TIMEOUT 250
38
+#define AFBC_HEADER_SIZE 16
39
+#define AFBC_SUPERBLK_ALIGNMENT 128
4040
4141 static void malidp_write_gamma_table(struct malidp_hw_device *hwdev,
4242 u32 data[MALIDP_COEFFTAB_NUM_COEFFS])
....@@ -269,9 +269,119 @@
269269 .atomic_commit_tail = malidp_atomic_commit_tail,
270270 };
271271
272
+static bool
273
+malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
274
+ const struct drm_mode_fb_cmd2 *mode_cmd)
275
+{
276
+ if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
277
+ mode_cmd->modifier[0]) == false)
278
+ return false;
279
+
280
+ if (mode_cmd->offsets[0] != 0) {
281
+ DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n");
282
+ return false;
283
+ }
284
+
285
+ switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
286
+ case AFBC_SIZE_16X16:
287
+ if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
288
+ DRM_DEBUG_KMS("AFBC buffers must be aligned to 16 pixels\n");
289
+ return false;
290
+ }
291
+ break;
292
+ default:
293
+ DRM_DEBUG_KMS("Unsupported AFBC block size\n");
294
+ return false;
295
+ }
296
+
297
+ return true;
298
+}
299
+
300
+static bool
301
+malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
302
+ struct drm_file *file,
303
+ const struct drm_mode_fb_cmd2 *mode_cmd)
304
+{
305
+ int n_superblocks = 0;
306
+ const struct drm_format_info *info;
307
+ struct drm_gem_object *objs = NULL;
308
+ u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
309
+ u32 afbc_superblock_width = 0, afbc_size = 0;
310
+ int bpp = 0;
311
+
312
+ switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
313
+ case AFBC_SIZE_16X16:
314
+ afbc_superblock_height = 16;
315
+ afbc_superblock_width = 16;
316
+ break;
317
+ default:
318
+ DRM_DEBUG_KMS("AFBC superblock size is not supported\n");
319
+ return false;
320
+ }
321
+
322
+ info = drm_get_format_info(dev, mode_cmd);
323
+
324
+ n_superblocks = (mode_cmd->width / afbc_superblock_width) *
325
+ (mode_cmd->height / afbc_superblock_height);
326
+
327
+ bpp = malidp_format_get_bpp(info->format);
328
+
329
+ afbc_superblock_size = (bpp * afbc_superblock_width * afbc_superblock_height)
330
+ / BITS_PER_BYTE;
331
+
332
+ afbc_size = ALIGN(n_superblocks * AFBC_HEADER_SIZE, AFBC_SUPERBLK_ALIGNMENT);
333
+ afbc_size += n_superblocks * ALIGN(afbc_superblock_size, AFBC_SUPERBLK_ALIGNMENT);
334
+
335
+ if ((mode_cmd->width * bpp) != (mode_cmd->pitches[0] * BITS_PER_BYTE)) {
336
+ DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) (=%u) "
337
+ "should be same as width (=%u) * bpp (=%u)\n",
338
+ (mode_cmd->pitches[0] * BITS_PER_BYTE),
339
+ mode_cmd->width, bpp);
340
+ return false;
341
+ }
342
+
343
+ objs = drm_gem_object_lookup(file, mode_cmd->handles[0]);
344
+ if (!objs) {
345
+ DRM_DEBUG_KMS("Failed to lookup GEM object\n");
346
+ return false;
347
+ }
348
+
349
+ if (objs->size < afbc_size) {
350
+ DRM_DEBUG_KMS("buffer size (%zu) too small for AFBC buffer size = %u\n",
351
+ objs->size, afbc_size);
352
+ drm_gem_object_put(objs);
353
+ return false;
354
+ }
355
+
356
+ drm_gem_object_put(objs);
357
+
358
+ return true;
359
+}
360
+
361
+static bool
362
+malidp_verify_afbc_framebuffer(struct drm_device *dev, struct drm_file *file,
363
+ const struct drm_mode_fb_cmd2 *mode_cmd)
364
+{
365
+ if (malidp_verify_afbc_framebuffer_caps(dev, mode_cmd))
366
+ return malidp_verify_afbc_framebuffer_size(dev, file, mode_cmd);
367
+
368
+ return false;
369
+}
370
+
371
+static struct drm_framebuffer *
372
+malidp_fb_create(struct drm_device *dev, struct drm_file *file,
373
+ const struct drm_mode_fb_cmd2 *mode_cmd)
374
+{
375
+ if (mode_cmd->modifier[0]) {
376
+ if (!malidp_verify_afbc_framebuffer(dev, file, mode_cmd))
377
+ return ERR_PTR(-EINVAL);
378
+ }
379
+
380
+ return drm_gem_fb_create(dev, file, mode_cmd);
381
+}
382
+
272383 static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
273
- .fb_create = drm_gem_fb_create,
274
- .output_poll_changed = drm_fb_helper_output_poll_changed,
384
+ .fb_create = malidp_fb_create,
275385 .atomic_check = drm_atomic_helper_check,
276386 .atomic_commit = drm_atomic_helper_commit,
277387 };
....@@ -290,6 +400,7 @@
290400 drm->mode_config.max_height = hwdev->max_line_size;
291401 drm->mode_config.funcs = &malidp_mode_config_funcs;
292402 drm->mode_config.helper_private = &malidp_mode_config_helpers;
403
+ drm->mode_config.allow_fb_modifiers = true;
293404
294405 ret = malidp_crtc_init(drm);
295406 if (ret)
....@@ -380,9 +491,9 @@
380491 spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
381492 }
382493
383
-void malidp_error_stats_dump(const char *prefix,
384
- struct malidp_error_stats error_stats,
385
- struct seq_file *m)
494
+static void malidp_error_stats_dump(const char *prefix,
495
+ struct malidp_error_stats error_stats,
496
+ struct seq_file *m)
386497 {
387498 seq_printf(m, "[%s] num_errors : %d\n", prefix,
388499 error_stats.num_errors);
....@@ -437,43 +548,22 @@
437548 .release = single_release,
438549 };
439550
440
-static int malidp_debugfs_init(struct drm_minor *minor)
551
+static void malidp_debugfs_init(struct drm_minor *minor)
441552 {
442553 struct malidp_drm *malidp = minor->dev->dev_private;
443
- struct dentry *dentry = NULL;
444554
445555 malidp_error_stats_init(&malidp->de_errors);
446556 malidp_error_stats_init(&malidp->se_errors);
447557 spin_lock_init(&malidp->errors_lock);
448
- dentry = debugfs_create_file("debug",
449
- S_IRUGO | S_IWUSR,
450
- minor->debugfs_root, minor->dev,
451
- &malidp_debugfs_fops);
452
- if (!dentry) {
453
- DRM_ERROR("Cannot create debug file\n");
454
- return -ENOMEM;
455
- }
456
- return 0;
558
+ debugfs_create_file("debug", S_IRUGO | S_IWUSR, minor->debugfs_root,
559
+ minor->dev, &malidp_debugfs_fops);
457560 }
458561
459562 #endif //CONFIG_DEBUG_FS
460563
461564 static struct drm_driver malidp_driver = {
462
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
463
- DRIVER_PRIME,
464
- .lastclose = drm_fb_helper_lastclose,
465
- .gem_free_object_unlocked = drm_gem_cma_free_object,
466
- .gem_vm_ops = &drm_gem_cma_vm_ops,
467
- .dumb_create = malidp_dumb_create,
468
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
469
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
470
- .gem_prime_export = drm_gem_prime_export,
471
- .gem_prime_import = drm_gem_prime_import,
472
- .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
473
- .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
474
- .gem_prime_vmap = drm_gem_cma_prime_vmap,
475
- .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
476
- .gem_prime_mmap = drm_gem_cma_prime_mmap,
565
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
566
+ DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(malidp_dumb_create),
477567 #ifdef CONFIG_DEBUG_FS
478568 .debugfs_init = malidp_debugfs_init,
479569 #endif
....@@ -565,22 +655,13 @@
565655 return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id);
566656 }
567657
568
-DEVICE_ATTR_RO(core_id);
658
+static DEVICE_ATTR_RO(core_id);
569659
570
-static int malidp_init_sysfs(struct device *dev)
571
-{
572
- int ret = device_create_file(dev, &dev_attr_core_id);
573
-
574
- if (ret)
575
- DRM_ERROR("failed to create device file for core_id\n");
576
-
577
- return ret;
578
-}
579
-
580
-static void malidp_fini_sysfs(struct device *dev)
581
-{
582
- device_remove_file(dev, &dev_attr_core_id);
583
-}
660
+static struct attribute *mali_dp_attrs[] = {
661
+ &dev_attr_core_id.attr,
662
+ NULL,
663
+};
664
+ATTRIBUTE_GROUPS(mali_dp);
584665
585666 #define MAX_OUTPUT_CHANNELS 3
586667
....@@ -717,6 +798,12 @@
717798
718799 malidp->core_id = version;
719800
801
+ ret = of_property_read_u32(dev->of_node,
802
+ "arm,malidp-arqos-value",
803
+ &hwdev->arqos_value);
804
+ if (ret)
805
+ hwdev->arqos_value = 0x0;
806
+
720807 /* set the number of lines used for output of RGB data */
721808 ret = of_property_read_u8_array(dev->of_node,
722809 "arm,malidp-output-port-lines",
....@@ -735,10 +822,6 @@
735822 ret = malidp_init(drm);
736823 if (ret < 0)
737824 goto query_hw_fail;
738
-
739
- ret = malidp_init_sysfs(dev);
740
- if (ret)
741
- goto init_fail;
742825
743826 /* Set the CRTC's port so that the encoder component can find it */
744827 malidp->crtc.port = of_graph_get_port_by_id(dev->of_node, 0);
....@@ -765,7 +848,6 @@
765848 drm->irq_enabled = true;
766849
767850 ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
768
- drm_crtc_vblank_reset(&malidp->crtc);
769851 if (ret < 0) {
770852 DRM_ERROR("failed to initialise vblank\n");
771853 goto vblank_fail;
....@@ -774,22 +856,18 @@
774856
775857 drm_mode_config_reset(drm);
776858
777
- ret = drm_fb_cma_fbdev_init(drm, 32, 0);
778
- if (ret)
779
- goto fbdev_fail;
780
-
781859 drm_kms_helper_poll_init(drm);
782860
783861 ret = drm_dev_register(drm, 0);
784862 if (ret)
785863 goto register_fail;
786864
865
+ drm_fbdev_generic_setup(drm, 32);
866
+
787867 return 0;
788868
789869 register_fail:
790
- drm_fb_cma_fbdev_fini(drm);
791870 drm_kms_helper_poll_fini(drm);
792
-fbdev_fail:
793871 pm_runtime_get_sync(dev);
794872 vblank_fail:
795873 malidp_se_irq_fini(hwdev);
....@@ -801,8 +879,6 @@
801879 bind_fail:
802880 of_node_put(malidp->crtc.port);
803881 malidp->crtc.port = NULL;
804
-init_fail:
805
- malidp_fini_sysfs(dev);
806882 malidp_fini(drm);
807883 query_hw_fail:
808884 pm_runtime_put(dev);
....@@ -826,18 +902,15 @@
826902 struct malidp_hw_device *hwdev = malidp->dev;
827903
828904 drm_dev_unregister(drm);
829
- drm_fb_cma_fbdev_fini(drm);
830905 drm_kms_helper_poll_fini(drm);
831906 pm_runtime_get_sync(dev);
832
- drm_crtc_vblank_off(&malidp->crtc);
907
+ drm_atomic_helper_shutdown(drm);
833908 malidp_se_irq_fini(hwdev);
834909 malidp_de_irq_fini(hwdev);
835910 drm->irq_enabled = false;
836
- drm_atomic_helper_shutdown(drm);
837911 component_unbind_all(dev, drm);
838912 of_node_put(malidp->crtc.port);
839913 malidp->crtc.port = NULL;
840
- malidp_fini_sysfs(dev);
841914 malidp_fini(drm);
842915 pm_runtime_put(dev);
843916 if (pm_runtime_enabled(dev))
....@@ -933,6 +1006,7 @@
9331006 .name = "mali-dp",
9341007 .pm = &malidp_pm_ops,
9351008 .of_match_table = malidp_drm_of_match,
1009
+ .dev_groups = mali_dp_groups,
9361010 },
9371011 };
9381012