hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.c
....@@ -1,31 +1,30 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2012 Samsung Electronics Co.Ltd
34 * Authors: Joonyoung Shim <jy0922.shim@samsung.com>
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2 as
7
- * published by the Free Software Foundationr
85 */
96
10
-#include <linux/kernel.h>
117 #include <linux/clk.h>
128 #include <linux/component.h>
9
+#include <linux/delay.h>
10
+#include <linux/dma-mapping.h>
1311 #include <linux/err.h>
1412 #include <linux/interrupt.h>
1513 #include <linux/io.h>
14
+#include <linux/kernel.h>
15
+#include <linux/of.h>
1616 #include <linux/platform_device.h>
1717 #include <linux/pm_runtime.h>
1818 #include <linux/slab.h>
19
+#include <linux/uaccess.h>
1920 #include <linux/workqueue.h>
20
-#include <linux/dma-mapping.h>
21
-#include <linux/of.h>
2221
23
-#include <drm/drmP.h>
22
+#include <drm/drm_file.h>
2423 #include <drm/exynos_drm.h>
24
+
2525 #include "exynos_drm_drv.h"
2626 #include "exynos_drm_g2d.h"
2727 #include "exynos_drm_gem.h"
28
-#include "exynos_drm_iommu.h"
2928
3029 #define G2D_HW_MAJOR_VER 4
3130 #define G2D_HW_MINOR_VER 1
....@@ -233,6 +232,7 @@
233232
234233 struct g2d_data {
235234 struct device *dev;
235
+ void *dma_priv;
236236 struct clk *gate_clk;
237237 void __iomem *regs;
238238 int irq;
....@@ -268,7 +268,7 @@
268268 static int g2d_init_cmdlist(struct g2d_data *g2d)
269269 {
270270 struct device *dev = g2d->dev;
271
- struct g2d_cmdlist_node *node = g2d->cmdlist_node;
271
+ struct g2d_cmdlist_node *node;
272272 int nr;
273273 int ret;
274274 struct g2d_buf_info *buf_info;
....@@ -395,8 +395,8 @@
395395 return;
396396
397397 out:
398
- dma_unmap_sg(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt->sgl,
399
- g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
398
+ dma_unmap_sgtable(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt,
399
+ DMA_BIDIRECTIONAL, 0);
400400
401401 pages = frame_vector_pages(g2d_userptr->vec);
402402 if (!IS_ERR(pages)) {
....@@ -430,7 +430,7 @@
430430 int ret;
431431
432432 if (!size) {
433
- DRM_ERROR("invalid userptr size.\n");
433
+ DRM_DEV_ERROR(g2d->dev, "invalid userptr size.\n");
434434 return ERR_PTR(-EINVAL);
435435 }
436436
....@@ -483,7 +483,8 @@
483483 ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE,
484484 g2d_userptr->vec);
485485 if (ret != npages) {
486
- DRM_ERROR("failed to get user pages from userptr.\n");
486
+ DRM_DEV_ERROR(g2d->dev,
487
+ "failed to get user pages from userptr.\n");
487488 if (ret < 0)
488489 goto err_destroy_framevec;
489490 ret = -EFAULT;
....@@ -504,16 +505,16 @@
504505 frame_vector_pages(g2d_userptr->vec),
505506 npages, offset, size, GFP_KERNEL);
506507 if (ret < 0) {
507
- DRM_ERROR("failed to get sgt from pages.\n");
508
+ DRM_DEV_ERROR(g2d->dev, "failed to get sgt from pages.\n");
508509 goto err_free_sgt;
509510 }
510511
511512 g2d_userptr->sgt = sgt;
512513
513
- if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents,
514
- DMA_BIDIRECTIONAL)) {
515
- DRM_ERROR("failed to map sgt with dma region.\n");
516
- ret = -ENOMEM;
514
+ ret = dma_map_sgtable(to_dma_dev(g2d->drm_dev), sgt,
515
+ DMA_BIDIRECTIONAL, 0);
516
+ if (ret) {
517
+ DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n");
517518 goto err_sg_free_table;
518519 }
519520
....@@ -561,7 +562,7 @@
561562 g2d->current_pool = 0;
562563 }
563564
564
-static enum g2d_reg_type g2d_get_reg_type(int reg_offset)
565
+static enum g2d_reg_type g2d_get_reg_type(struct g2d_data *g2d, int reg_offset)
565566 {
566567 enum g2d_reg_type reg_type;
567568
....@@ -594,7 +595,8 @@
594595 break;
595596 default:
596597 reg_type = REG_TYPE_NONE;
597
- DRM_ERROR("Unknown register offset![%d]\n", reg_offset);
598
+ DRM_DEV_ERROR(g2d->dev, "Unknown register offset![%d]\n",
599
+ reg_offset);
598600 break;
599601 }
600602
....@@ -628,9 +630,10 @@
628630 return bpp;
629631 }
630632
631
-static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc,
632
- enum g2d_reg_type reg_type,
633
- unsigned long size)
633
+static bool g2d_check_buf_desc_is_valid(struct g2d_data *g2d,
634
+ struct g2d_buf_desc *buf_desc,
635
+ enum g2d_reg_type reg_type,
636
+ unsigned long size)
634637 {
635638 int width, height;
636639 unsigned long bpp, last_pos;
....@@ -645,14 +648,15 @@
645648 /* This check also makes sure that right_x > left_x. */
646649 width = (int)buf_desc->right_x - (int)buf_desc->left_x;
647650 if (width < G2D_LEN_MIN || width > G2D_LEN_MAX) {
648
- DRM_ERROR("width[%d] is out of range!\n", width);
651
+ DRM_DEV_ERROR(g2d->dev, "width[%d] is out of range!\n", width);
649652 return false;
650653 }
651654
652655 /* This check also makes sure that bottom_y > top_y. */
653656 height = (int)buf_desc->bottom_y - (int)buf_desc->top_y;
654657 if (height < G2D_LEN_MIN || height > G2D_LEN_MAX) {
655
- DRM_ERROR("height[%d] is out of range!\n", height);
658
+ DRM_DEV_ERROR(g2d->dev,
659
+ "height[%d] is out of range!\n", height);
656660 return false;
657661 }
658662
....@@ -671,8 +675,8 @@
671675 */
672676
673677 if (last_pos >= size) {
674
- DRM_ERROR("last engine access position [%lu] "
675
- "is out of range [%lu]!\n", last_pos, size);
678
+ DRM_DEV_ERROR(g2d->dev, "last engine access position [%lu] "
679
+ "is out of range [%lu]!\n", last_pos, size);
676680 return false;
677681 }
678682
....@@ -702,7 +706,7 @@
702706 offset = cmdlist->data[reg_pos];
703707 handle = cmdlist->data[reg_pos + 1];
704708
705
- reg_type = g2d_get_reg_type(offset);
709
+ reg_type = g2d_get_reg_type(g2d, offset);
706710 if (reg_type == REG_TYPE_NONE) {
707711 ret = -EFAULT;
708712 goto err;
....@@ -719,7 +723,7 @@
719723 goto err;
720724 }
721725
722
- if (!g2d_check_buf_desc_is_valid(buf_desc,
726
+ if (!g2d_check_buf_desc_is_valid(g2d, buf_desc,
723727 reg_type, exynos_gem->size)) {
724728 exynos_drm_gem_put(exynos_gem);
725729 ret = -EFAULT;
....@@ -737,8 +741,9 @@
737741 goto err;
738742 }
739743
740
- if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type,
741
- g2d_userptr.size)) {
744
+ if (!g2d_check_buf_desc_is_valid(g2d, buf_desc,
745
+ reg_type,
746
+ g2d_userptr.size)) {
742747 ret = -EFAULT;
743748 goto err;
744749 }
....@@ -846,7 +851,7 @@
846851 *
847852 * Has to be called under runqueue lock.
848853 */
849
-static void g2d_remove_runqueue_nodes(struct g2d_data *g2d, struct drm_file* file)
854
+static void g2d_remove_runqueue_nodes(struct g2d_data *g2d, struct drm_file *file)
850855 {
851856 struct g2d_runqueue_node *node, *n;
852857
....@@ -1045,7 +1050,7 @@
10451050 if (!for_addr)
10461051 goto err;
10471052
1048
- reg_type = g2d_get_reg_type(reg_offset);
1053
+ reg_type = g2d_get_reg_type(g2d, reg_offset);
10491054
10501055 /* check userptr buffer type. */
10511056 if ((cmdlist->data[index] & ~0x7fffffff) >> 31) {
....@@ -1059,7 +1064,7 @@
10591064 if (for_addr)
10601065 goto err;
10611066
1062
- reg_type = g2d_get_reg_type(reg_offset);
1067
+ reg_type = g2d_get_reg_type(g2d, reg_offset);
10631068
10641069 buf_desc = &buf_info->descs[reg_type];
10651070 buf_desc->stride = cmdlist->data[index + 1];
....@@ -1069,7 +1074,7 @@
10691074 if (for_addr)
10701075 goto err;
10711076
1072
- reg_type = g2d_get_reg_type(reg_offset);
1077
+ reg_type = g2d_get_reg_type(g2d, reg_offset);
10731078
10741079 buf_desc = &buf_info->descs[reg_type];
10751080 value = cmdlist->data[index + 1];
....@@ -1081,7 +1086,7 @@
10811086 if (for_addr)
10821087 goto err;
10831088
1084
- reg_type = g2d_get_reg_type(reg_offset);
1089
+ reg_type = g2d_get_reg_type(g2d, reg_offset);
10851090
10861091 buf_desc = &buf_info->descs[reg_type];
10871092 value = cmdlist->data[index + 1];
....@@ -1094,7 +1099,7 @@
10941099 if (for_addr)
10951100 goto err;
10961101
1097
- reg_type = g2d_get_reg_type(reg_offset);
1102
+ reg_type = g2d_get_reg_type(g2d, reg_offset);
10981103
10991104 buf_desc = &buf_info->descs[reg_type];
11001105 value = cmdlist->data[index + 1];
....@@ -1405,7 +1410,7 @@
14051410 return ret;
14061411 }
14071412
1408
- ret = drm_iommu_attach_device(drm_dev, dev);
1413
+ ret = exynos_drm_register_dma(drm_dev, dev, &g2d->dma_priv);
14091414 if (ret < 0) {
14101415 dev_err(dev, "failed to enable iommu.\n");
14111416 g2d_fini_cmdlist(g2d);
....@@ -1430,7 +1435,7 @@
14301435 priv->g2d_dev = NULL;
14311436
14321437 cancel_work_sync(&g2d->runqueue_work);
1433
- drm_iommu_detach_device(g2d->drm_dev, dev);
1438
+ exynos_drm_unregister_dma(g2d->drm_dev, dev, &g2d->dma_priv);
14341439 }
14351440
14361441 static const struct component_ops g2d_component_ops = {
....@@ -1493,7 +1498,6 @@
14931498
14941499 g2d->irq = platform_get_irq(pdev, 0);
14951500 if (g2d->irq < 0) {
1496
- dev_err(dev, "failed to get irq\n");
14971501 ret = g2d->irq;
14981502 goto err_put_clk;
14991503 }