forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/mediatek/mtk_drm_gem.c
....@@ -1,19 +1,14 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015 MediaTek Inc.
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
124 */
135
14
-#include <drm/drmP.h>
15
-#include <drm/drm_gem.h>
166 #include <linux/dma-buf.h>
7
+
8
+#include <drm/drm.h>
9
+#include <drm/drm_device.h>
10
+#include <drm/drm_gem.h>
11
+#include <drm/drm_prime.h>
1712
1813 #include "mtk_drm_drv.h"
1914 #include "mtk_drm_gem.h"
....@@ -122,7 +117,7 @@
122117 goto err_handle_create;
123118
124119 /* drop reference from allocate - handle holds it now. */
125
- drm_gem_object_put_unlocked(&mtk_gem->base);
120
+ drm_gem_object_put(&mtk_gem->base);
126121
127122 return 0;
128123
....@@ -144,12 +139,9 @@
144139 * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap().
145140 */
146141 vma->vm_flags &= ~VM_PFNMAP;
147
- vma->vm_pgoff = 0;
148142
149143 ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie,
150144 mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs);
151
- if (ret)
152
- drm_gem_vm_close(vma);
153145
154146 return ret;
155147 }
....@@ -175,6 +167,12 @@
175167 return ret;
176168
177169 obj = vma->vm_private_data;
170
+
171
+ /*
172
+ * Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the
173
+ * whole buffer from the start.
174
+ */
175
+ vma->vm_pgoff = 0;
178176
179177 return mtk_drm_gem_object_mmap(obj, vma);
180178 }
....@@ -212,32 +210,64 @@
212210 struct dma_buf_attachment *attach, struct sg_table *sg)
213211 {
214212 struct mtk_drm_gem_obj *mtk_gem;
215
- int ret;
216
- struct scatterlist *s;
217
- unsigned int i;
218
- dma_addr_t expected;
213
+
214
+ /* check if the entries in the sg_table are contiguous */
215
+ if (drm_prime_get_contiguous_size(sg) < attach->dmabuf->size) {
216
+ DRM_ERROR("sg_table is not contiguous");
217
+ return ERR_PTR(-EINVAL);
218
+ }
219219
220220 mtk_gem = mtk_drm_gem_init(dev, attach->dmabuf->size);
221
-
222221 if (IS_ERR(mtk_gem))
223222 return ERR_CAST(mtk_gem);
224
-
225
- expected = sg_dma_address(sg->sgl);
226
- for_each_sg(sg->sgl, s, sg->nents, i) {
227
- if (sg_dma_address(s) != expected) {
228
- DRM_ERROR("sg_table is not contiguous");
229
- ret = -EINVAL;
230
- goto err_gem_free;
231
- }
232
- expected = sg_dma_address(s) + sg_dma_len(s);
233
- }
234223
235224 mtk_gem->dma_addr = sg_dma_address(sg->sgl);
236225 mtk_gem->sg = sg;
237226
238227 return &mtk_gem->base;
228
+}
239229
240
-err_gem_free:
241
- kfree(mtk_gem);
242
- return ERR_PTR(ret);
230
+void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj)
231
+{
232
+ struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
233
+ struct sg_table *sgt;
234
+ unsigned int npages;
235
+
236
+ if (mtk_gem->kvaddr)
237
+ return mtk_gem->kvaddr;
238
+
239
+ sgt = mtk_gem_prime_get_sg_table(obj);
240
+ if (IS_ERR(sgt))
241
+ return NULL;
242
+
243
+ npages = obj->size >> PAGE_SHIFT;
244
+ mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL);
245
+ if (!mtk_gem->pages)
246
+ goto out;
247
+
248
+ drm_prime_sg_to_page_addr_arrays(sgt, mtk_gem->pages, NULL, npages);
249
+
250
+ mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP,
251
+ pgprot_writecombine(PAGE_KERNEL));
252
+ if (!mtk_gem->kvaddr) {
253
+ kfree(sgt);
254
+ kfree(mtk_gem->pages);
255
+ return NULL;
256
+ }
257
+out:
258
+ kfree(sgt);
259
+
260
+ return mtk_gem->kvaddr;
261
+}
262
+
263
+void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
264
+{
265
+ struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
266
+
267
+ if (!mtk_gem->pages)
268
+ return;
269
+
270
+ vunmap(vaddr);
271
+ mtk_gem->kvaddr = NULL;
272
+ kfree(mtk_gem->pages);
243273 }