hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/rknpu/rknpu_gem.c
....@@ -13,7 +13,6 @@
1313 #include <linux/shmem_fs.h>
1414 #include <linux/dma-buf.h>
1515 #include <linux/iommu.h>
16
-#include <linux/dma-iommu.h>
1716 #include <linux/pfn_t.h>
1817 #include <linux/version.h>
1918 #include <asm/cacheflush.h>
....@@ -68,6 +67,7 @@
6867 rknpu_obj->size);
6968 goto free_sgt;
7069 }
70
+ iommu_flush_iotlb_all(iommu_get_domain_for_dev(drm->dev));
7171
7272 if (rknpu_obj->flags & RKNPU_MEM_KERNEL_MAPPING) {
7373 rknpu_obj->cookie = vmap(rknpu_obj->pages, rknpu_obj->num_pages,
....@@ -182,7 +182,9 @@
182182 if (rknpu_obj->flags & RKNPU_MEM_ZEROING)
183183 gfp_mask |= __GFP_ZERO;
184184
185
- if (!(rknpu_obj->flags & RKNPU_MEM_NON_DMA32)) {
185
+ if (!rknpu_dev->iommu_en ||
186
+ rknpu_dev->config->dma_mask <= DMA_BIT_MASK(32) ||
187
+ (rknpu_obj->flags & RKNPU_MEM_DMA32)) {
186188 gfp_mask &= ~__GFP_HIGHMEM;
187189 gfp_mask |= __GFP_DMA32;
188190 }
....@@ -253,10 +255,15 @@
253255 i, &s->dma_address, s->length);
254256 }
255257
256
- if (drm_prime_sg_to_page_addr_arrays(sgt, rknpu_obj->pages, NULL,
257
- nr_pages)) {
258
- LOG_DEV_ERROR(drm->dev, "invalid sgtable.\n");
259
- ret = -EINVAL;
258
+#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
259
+ ret = drm_prime_sg_to_page_addr_arrays(sgt, rknpu_obj->pages, NULL,
260
+ nr_pages);
261
+#else
262
+ ret = drm_prime_sg_to_page_array(sgt, rknpu_obj->pages, nr_pages);
263
+#endif
264
+
265
+ if (ret < 0) {
266
+ LOG_DEV_ERROR(drm->dev, "invalid sgtable, ret: %d\n", ret);
260267 goto err_free_sg_table;
261268 }
262269
....@@ -335,9 +342,28 @@
335342 return drm_gem_handle_delete(file_priv, handle);
336343 }
337344
345
+#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
346
+static const struct vm_operations_struct vm_ops = {
347
+ .fault = rknpu_gem_fault,
348
+ .open = drm_gem_vm_open,
349
+ .close = drm_gem_vm_close,
350
+};
351
+
352
+static const struct drm_gem_object_funcs rknpu_gem_object_funcs = {
353
+ .free = rknpu_gem_free_object,
354
+ .export = drm_gem_prime_export,
355
+ .get_sg_table = rknpu_gem_prime_get_sg_table,
356
+ .vmap = rknpu_gem_prime_vmap,
357
+ .vunmap = rknpu_gem_prime_vunmap,
358
+ .mmap = rknpu_gem_mmap_obj,
359
+ .vm_ops = &vm_ops,
360
+};
361
+#endif
362
+
338363 static struct rknpu_gem_object *rknpu_gem_init(struct drm_device *drm,
339364 unsigned long size)
340365 {
366
+ struct rknpu_device *rknpu_dev = drm->dev_private;
341367 struct rknpu_gem_object *rknpu_obj = NULL;
342368 struct drm_gem_object *obj = NULL;
343369 gfp_t gfp_mask;
....@@ -348,6 +374,9 @@
348374 return ERR_PTR(-ENOMEM);
349375
350376 obj = &rknpu_obj->base;
377
+#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
378
+ obj->funcs = &rknpu_gem_object_funcs;
379
+#endif
351380
352381 ret = drm_gem_object_init(drm, obj, size);
353382 if (ret < 0) {
....@@ -363,7 +392,9 @@
363392 if (rknpu_obj->flags & RKNPU_MEM_ZEROING)
364393 gfp_mask |= __GFP_ZERO;
365394
366
- if (!(rknpu_obj->flags & RKNPU_MEM_NON_DMA32)) {
395
+ if (!rknpu_dev->iommu_en ||
396
+ rknpu_dev->config->dma_mask <= DMA_BIT_MASK(32) ||
397
+ (rknpu_obj->flags & RKNPU_MEM_DMA32)) {
367398 gfp_mask &= ~__GFP_HIGHMEM;
368399 gfp_mask |= __GFP_DMA32;
369400 }
....@@ -422,7 +453,7 @@
422453 return -EINVAL;
423454 }
424455
425
- cookie = domain->iova_cookie;
456
+ cookie = (void *)domain->iova_cookie;
426457 iovad = &cookie->iovad;
427458 rknpu_obj->iova_size = iova_align(iovad, cache_size + rknpu_obj->size);
428459 rknpu_obj->iova_start = rknpu_iommu_dma_alloc_iova(
....@@ -534,8 +565,8 @@
534565 iommu_unmap(domain, rknpu_obj->iova_start, cache_size);
535566
536567 free_iova:
537
- rknpu_iommu_dma_free_iova(domain->iova_cookie, rknpu_obj->iova_start,
538
- rknpu_obj->iova_size);
568
+ rknpu_iommu_dma_free_iova((void *)domain->iova_cookie,
569
+ rknpu_obj->iova_start, rknpu_obj->iova_size);
539570
540571 return ret;
541572 }
....@@ -566,7 +597,7 @@
566597 if (rknpu_obj->size > 0)
567598 iommu_unmap(domain, rknpu_obj->iova_start + cache_size,
568599 rknpu_obj->size);
569
- rknpu_iommu_dma_free_iova(domain->iova_cookie,
600
+ rknpu_iommu_dma_free_iova((void *)domain->iova_cookie,
570601 rknpu_obj->iova_start,
571602 rknpu_obj->iova_size);
572603 }
....@@ -954,6 +985,7 @@
954985 * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map
955986 * the whole buffer.
956987 */
988
+ vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
957989 vma->vm_flags &= ~VM_PFNMAP;
958990 vma->vm_pgoff = 0;
959991
....@@ -1148,8 +1180,7 @@
11481180 }
11491181 #endif
11501182
1151
-static int rknpu_gem_mmap_obj(struct drm_gem_object *obj,
1152
- struct vm_area_struct *vma)
1183
+int rknpu_gem_mmap_obj(struct drm_gem_object *obj, struct vm_area_struct *vma)
11531184 {
11541185 struct rknpu_gem_object *rknpu_obj = to_rknpu_obj(obj);
11551186 int ret = -EINVAL;
....@@ -1246,8 +1277,12 @@
12461277 goto err;
12471278 }
12481279
1280
+#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
12491281 ret = drm_prime_sg_to_page_addr_arrays(sgt, rknpu_obj->pages, NULL,
12501282 npages);
1283
+#else
1284
+ ret = drm_prime_sg_to_page_array(sgt, rknpu_obj->pages, npages);
1285
+#endif
12511286 if (ret < 0)
12521287 goto err_free_large;
12531288
....@@ -1275,6 +1310,7 @@
12751310 return ERR_PTR(ret);
12761311 }
12771312
1313
+#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
12781314 void *rknpu_gem_prime_vmap(struct drm_gem_object *obj)
12791315 {
12801316 struct rknpu_gem_object *rknpu_obj = to_rknpu_obj(obj);
....@@ -1290,6 +1326,35 @@
12901326 {
12911327 vunmap(vaddr);
12921328 }
1329
+#else
1330
+int rknpu_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
1331
+{
1332
+ struct rknpu_gem_object *rknpu_obj = to_rknpu_obj(obj);
1333
+ void *vaddr = NULL;
1334
+
1335
+ if (!rknpu_obj->pages)
1336
+ return -EINVAL;
1337
+
1338
+ vaddr = vmap(rknpu_obj->pages, rknpu_obj->num_pages, VM_MAP,
1339
+ PAGE_KERNEL);
1340
+ if (!vaddr)
1341
+ return -ENOMEM;
1342
+
1343
+ iosys_map_set_vaddr(map, vaddr);
1344
+
1345
+ return 0;
1346
+}
1347
+
1348
+void rknpu_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
1349
+{
1350
+ struct rknpu_gem_object *rknpu_obj = to_rknpu_obj(obj);
1351
+
1352
+ if (rknpu_obj->pages) {
1353
+ vunmap(map->vaddr);
1354
+ map->vaddr = NULL;
1355
+ }
1356
+}
1357
+#endif
12931358
12941359 int rknpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
12951360 {
....@@ -1306,6 +1371,7 @@
13061371 unsigned long *length, unsigned long *offset,
13071372 enum rknpu_cache_type cache_type)
13081373 {
1374
+#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
13091375 struct drm_gem_object *obj = &rknpu_obj->base;
13101376 struct rknpu_device *rknpu_dev = obj->dev->dev_private;
13111377 void __iomem *cache_base_io = NULL;
....@@ -1348,6 +1414,8 @@
13481414 *length -= cache_length;
13491415 *offset = 0;
13501416 }
1417
+#endif
1418
+
13511419 return 0;
13521420 }
13531421
....@@ -1355,10 +1423,12 @@
13551423 struct drm_file *file_priv)
13561424 {
13571425 struct rknpu_gem_object *rknpu_obj = NULL;
1426
+ struct rknpu_device *rknpu_dev = dev->dev_private;
13581427 struct rknpu_mem_sync *args = data;
13591428 struct scatterlist *sg;
1429
+ dma_addr_t sg_phys_addr;
13601430 unsigned long length, offset = 0;
1361
- unsigned long sg_left, size = 0;
1431
+ unsigned long sg_offset, sg_left, size = 0;
13621432 unsigned long len = 0;
13631433 int i;
13641434
....@@ -1382,6 +1452,8 @@
13821452 DMA_FROM_DEVICE);
13831453 }
13841454 } else {
1455
+ WARN_ON(!rknpu_dev->fake_dev);
1456
+
13851457 length = args->size;
13861458 offset = args->offset;
13871459
....@@ -1405,17 +1477,23 @@
14051477 if (len <= offset)
14061478 continue;
14071479
1480
+ sg_phys_addr = sg_phys(sg);
1481
+
14081482 sg_left = len - offset;
1483
+ sg_offset = sg->length - sg_left;
1484
+
14091485 size = (length < sg_left) ? length : sg_left;
14101486
14111487 if (args->flags & RKNPU_MEM_SYNC_TO_DEVICE) {
1412
- dma_sync_sg_for_device(dev->dev, sg, 1,
1413
- DMA_TO_DEVICE);
1488
+ dma_sync_single_range_for_device(
1489
+ rknpu_dev->fake_dev, sg_phys_addr,
1490
+ sg_offset, size, DMA_TO_DEVICE);
14141491 }
14151492
14161493 if (args->flags & RKNPU_MEM_SYNC_FROM_DEVICE) {
1417
- dma_sync_sg_for_cpu(dev->dev, sg, 1,
1418
- DMA_FROM_DEVICE);
1494
+ dma_sync_single_range_for_cpu(
1495
+ rknpu_dev->fake_dev, sg_phys_addr,
1496
+ sg_offset, size, DMA_FROM_DEVICE);
14191497 }
14201498
14211499 offset += size;