forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/etnaviv/etnaviv_gem.c
....@@ -3,10 +3,11 @@
33 * Copyright (C) 2015-2018 Etnaviv Project
44 */
55
6
-#include <linux/spinlock.h>
6
+#include <drm/drm_prime.h>
7
+#include <linux/dma-mapping.h>
78 #include <linux/shmem_fs.h>
8
-#include <linux/sched/mm.h>
9
-#include <linux/sched/task.h>
9
+#include <linux/spinlock.h>
10
+#include <linux/vmalloc.h>
1011
1112 #include "etnaviv_drv.h"
1213 #include "etnaviv_gem.h"
....@@ -26,7 +27,7 @@
2627 * because display controller, GPU, etc. are not coherent.
2728 */
2829 if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
29
- dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
30
+ dma_map_sgtable(dev->dev, sgt, DMA_BIDIRECTIONAL, 0);
3031 }
3132
3233 static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj)
....@@ -50,7 +51,7 @@
5051 * discard those writes.
5152 */
5253 if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
53
- dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
54
+ dma_unmap_sgtable(dev->dev, sgt, DMA_BIDIRECTIONAL, 0);
5455 }
5556
5657 /* called with etnaviv_obj->lock held */
....@@ -102,7 +103,8 @@
102103 int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
103104 struct sg_table *sgt;
104105
105
- sgt = drm_prime_pages_to_sg(etnaviv_obj->pages, npages);
106
+ sgt = drm_prime_pages_to_sg(etnaviv_obj->base.dev,
107
+ etnaviv_obj->pages, npages);
106108 if (IS_ERR(sgt)) {
107109 dev_err(dev->dev, "failed to allocate sgt: %ld\n",
108110 PTR_ERR(sgt));
....@@ -222,28 +224,16 @@
222224
223225 static struct etnaviv_vram_mapping *
224226 etnaviv_gem_get_vram_mapping(struct etnaviv_gem_object *obj,
225
- struct etnaviv_iommu *mmu)
227
+ struct etnaviv_iommu_context *context)
226228 {
227229 struct etnaviv_vram_mapping *mapping;
228230
229231 list_for_each_entry(mapping, &obj->vram_list, obj_node) {
230
- if (mapping->mmu == mmu)
232
+ if (mapping->context == context)
231233 return mapping;
232234 }
233235
234236 return NULL;
235
-}
236
-
237
-void etnaviv_gem_mapping_reference(struct etnaviv_vram_mapping *mapping)
238
-{
239
- struct etnaviv_gem_object *etnaviv_obj = mapping->object;
240
-
241
- drm_gem_object_get(&etnaviv_obj->base);
242
-
243
- mutex_lock(&etnaviv_obj->lock);
244
- WARN_ON(mapping->use == 0);
245
- mapping->use += 1;
246
- mutex_unlock(&etnaviv_obj->lock);
247237 }
248238
249239 void etnaviv_gem_mapping_unreference(struct etnaviv_vram_mapping *mapping)
....@@ -255,11 +245,12 @@
255245 mapping->use -= 1;
256246 mutex_unlock(&etnaviv_obj->lock);
257247
258
- drm_gem_object_put_unlocked(&etnaviv_obj->base);
248
+ drm_gem_object_put(&etnaviv_obj->base);
259249 }
260250
261251 struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
262
- struct drm_gem_object *obj, struct etnaviv_gpu *gpu)
252
+ struct drm_gem_object *obj, struct etnaviv_iommu_context *mmu_context,
253
+ u64 va)
263254 {
264255 struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
265256 struct etnaviv_vram_mapping *mapping;
....@@ -267,7 +258,7 @@
267258 int ret = 0;
268259
269260 mutex_lock(&etnaviv_obj->lock);
270
- mapping = etnaviv_gem_get_vram_mapping(etnaviv_obj, gpu->mmu);
261
+ mapping = etnaviv_gem_get_vram_mapping(etnaviv_obj, mmu_context);
271262 if (mapping) {
272263 /*
273264 * Holding the object lock prevents the use count changing
....@@ -276,12 +267,12 @@
276267 * the MMU owns this mapping to close this race.
277268 */
278269 if (mapping->use == 0) {
279
- mutex_lock(&gpu->mmu->lock);
280
- if (mapping->mmu == gpu->mmu)
270
+ mutex_lock(&mmu_context->lock);
271
+ if (mapping->context == mmu_context)
281272 mapping->use += 1;
282273 else
283274 mapping = NULL;
284
- mutex_unlock(&gpu->mmu->lock);
275
+ mutex_unlock(&mmu_context->lock);
285276 if (mapping)
286277 goto out;
287278 } else {
....@@ -314,15 +305,18 @@
314305 list_del(&mapping->obj_node);
315306 }
316307
317
- mapping->mmu = gpu->mmu;
308
+ mapping->context = etnaviv_iommu_context_get(mmu_context);
318309 mapping->use = 1;
319310
320
- ret = etnaviv_iommu_map_gem(gpu->mmu, etnaviv_obj, gpu->memory_base,
321
- mapping);
322
- if (ret < 0)
311
+ ret = etnaviv_iommu_map_gem(mmu_context, etnaviv_obj,
312
+ mmu_context->global->memory_base,
313
+ mapping, va);
314
+ if (ret < 0) {
315
+ etnaviv_iommu_context_put(mmu_context);
323316 kfree(mapping);
324
- else
317
+ } else {
325318 list_add_tail(&mapping->obj_node, &etnaviv_obj->vram_list);
319
+ }
326320
327321 out:
328322 mutex_unlock(&etnaviv_obj->lock);
....@@ -379,7 +373,7 @@
379373 }
380374
381375 int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
382
- struct timespec *timeout)
376
+ struct drm_etnaviv_timespec *timeout)
383377 {
384378 struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
385379 struct drm_device *dev = obj->dev;
....@@ -397,22 +391,21 @@
397391 }
398392
399393 if (op & ETNA_PREP_NOSYNC) {
400
- if (!reservation_object_test_signaled_rcu(etnaviv_obj->resv,
394
+ if (!dma_resv_test_signaled_rcu(obj->resv,
401395 write))
402396 return -EBUSY;
403397 } else {
404398 unsigned long remain = etnaviv_timeout_to_jiffies(timeout);
405399
406
- ret = reservation_object_wait_timeout_rcu(etnaviv_obj->resv,
400
+ ret = dma_resv_wait_timeout_rcu(obj->resv,
407401 write, true, remain);
408402 if (ret <= 0)
409403 return ret == 0 ? -ETIMEDOUT : ret;
410404 }
411405
412406 if (etnaviv_obj->flags & ETNA_BO_CACHED) {
413
- dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
414
- etnaviv_obj->sgt->nents,
415
- etnaviv_op_to_dma_dir(op));
407
+ dma_sync_sgtable_for_cpu(dev->dev, etnaviv_obj->sgt,
408
+ etnaviv_op_to_dma_dir(op));
416409 etnaviv_obj->last_cpu_prep_op = op;
417410 }
418411
....@@ -427,8 +420,7 @@
427420 if (etnaviv_obj->flags & ETNA_BO_CACHED) {
428421 /* fini without a prep is almost certainly a userspace error */
429422 WARN_ON(etnaviv_obj->last_cpu_prep_op == 0);
430
- dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl,
431
- etnaviv_obj->sgt->nents,
423
+ dma_sync_sgtable_for_device(dev->dev, etnaviv_obj->sgt,
432424 etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op));
433425 etnaviv_obj->last_cpu_prep_op = 0;
434426 }
....@@ -437,7 +429,7 @@
437429 }
438430
439431 int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj,
440
- struct timespec *timeout)
432
+ struct drm_etnaviv_timespec *timeout)
441433 {
442434 struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
443435
....@@ -449,7 +441,7 @@
449441 const char *type, struct seq_file *m)
450442 {
451443 if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
452
- seq_printf(m, "\t%9s: %s %s seq %u\n",
444
+ seq_printf(m, "\t%9s: %s %s seq %llu\n",
453445 type,
454446 fence->ops->get_driver_name(fence),
455447 fence->ops->get_timeline_name(fence),
....@@ -459,8 +451,8 @@
459451 static void etnaviv_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
460452 {
461453 struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
462
- struct reservation_object *robj = etnaviv_obj->resv;
463
- struct reservation_object_list *fobj;
454
+ struct dma_resv *robj = obj->resv;
455
+ struct dma_resv_list *fobj;
464456 struct dma_fence *fence;
465457 unsigned long off = drm_vma_node_start(&obj->vma_node);
466458
....@@ -536,12 +528,14 @@
536528
537529 list_for_each_entry_safe(mapping, tmp, &etnaviv_obj->vram_list,
538530 obj_node) {
539
- struct etnaviv_iommu *mmu = mapping->mmu;
531
+ struct etnaviv_iommu_context *context = mapping->context;
540532
541533 WARN_ON(mapping->use);
542534
543
- if (mmu)
544
- etnaviv_iommu_unmap_gem(mmu, mapping);
535
+ if (context) {
536
+ etnaviv_iommu_unmap_gem(context, mapping);
537
+ etnaviv_iommu_context_put(context);
538
+ }
545539
546540 list_del(&mapping->obj_node);
547541 kfree(mapping);
....@@ -549,8 +543,6 @@
549543
550544 drm_gem_free_mmap_offset(obj);
551545 etnaviv_obj->ops->release(etnaviv_obj);
552
- if (etnaviv_obj->resv == &etnaviv_obj->_resv)
553
- reservation_object_fini(&etnaviv_obj->_resv);
554546 drm_gem_object_release(obj);
555547
556548 kfree(etnaviv_obj);
....@@ -567,8 +559,7 @@
567559 }
568560
569561 static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags,
570
- struct reservation_object *robj, const struct etnaviv_gem_ops *ops,
571
- struct drm_gem_object **obj)
562
+ const struct etnaviv_gem_ops *ops, struct drm_gem_object **obj)
572563 {
573564 struct etnaviv_gem_object *etnaviv_obj;
574565 unsigned sz = sizeof(*etnaviv_obj);
....@@ -596,12 +587,6 @@
596587
597588 etnaviv_obj->flags = flags;
598589 etnaviv_obj->ops = ops;
599
- if (robj) {
600
- etnaviv_obj->resv = robj;
601
- } else {
602
- etnaviv_obj->resv = &etnaviv_obj->_resv;
603
- reservation_object_init(&etnaviv_obj->_resv);
604
- }
605590
606591 mutex_init(&etnaviv_obj->lock);
607592 INIT_LIST_HEAD(&etnaviv_obj->vram_list);
....@@ -615,12 +600,13 @@
615600 int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
616601 u32 size, u32 flags, u32 *handle)
617602 {
603
+ struct etnaviv_drm_private *priv = dev->dev_private;
618604 struct drm_gem_object *obj = NULL;
619605 int ret;
620606
621607 size = PAGE_ALIGN(size);
622608
623
- ret = etnaviv_gem_new_impl(dev, size, flags, NULL,
609
+ ret = etnaviv_gem_new_impl(dev, size, flags,
624610 &etnaviv_gem_shmem_ops, &obj);
625611 if (ret)
626612 goto fail;
....@@ -628,23 +614,16 @@
628614 lockdep_set_class(&to_etnaviv_bo(obj)->lock, &etnaviv_shm_lock_class);
629615
630616 ret = drm_gem_object_init(dev, obj, size);
631
- if (ret == 0) {
632
- struct address_space *mapping;
633
-
634
- /*
635
- * Our buffers are kept pinned, so allocating them
636
- * from the MOVABLE zone is a really bad idea, and
637
- * conflicts with CMA. See comments above new_inode()
638
- * why this is required _and_ expected if you're
639
- * going to pin these pages.
640
- */
641
- mapping = obj->filp->f_mapping;
642
- mapping_set_gfp_mask(mapping, GFP_HIGHUSER |
643
- __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
644
- }
645
-
646617 if (ret)
647618 goto fail;
619
+
620
+ /*
621
+ * Our buffers are kept pinned, so allocating them from the MOVABLE
622
+ * zone is a really bad idea, and conflicts with CMA. See comments
623
+ * above new_inode() why this is required _and_ expected if you're
624
+ * going to pin these pages.
625
+ */
626
+ mapping_set_gfp_mask(obj->filp->f_mapping, priv->shm_gfp_mask);
648627
649628 etnaviv_gem_obj_add(dev, obj);
650629
....@@ -652,19 +631,18 @@
652631
653632 /* drop reference from allocate - handle holds it now */
654633 fail:
655
- drm_gem_object_put_unlocked(obj);
634
+ drm_gem_object_put(obj);
656635
657636 return ret;
658637 }
659638
660639 int etnaviv_gem_new_private(struct drm_device *dev, size_t size, u32 flags,
661
- struct reservation_object *robj, const struct etnaviv_gem_ops *ops,
662
- struct etnaviv_gem_object **res)
640
+ const struct etnaviv_gem_ops *ops, struct etnaviv_gem_object **res)
663641 {
664642 struct drm_gem_object *obj;
665643 int ret;
666644
667
- ret = etnaviv_gem_new_impl(dev, size, flags, robj, ops, &obj);
645
+ ret = etnaviv_gem_new_impl(dev, size, flags, ops, &obj);
668646 if (ret)
669647 return ret;
670648
....@@ -681,7 +659,7 @@
681659 struct etnaviv_gem_userptr *userptr = &etnaviv_obj->userptr;
682660 int ret, pinned = 0, npages = etnaviv_obj->base.size >> PAGE_SHIFT;
683661
684
- might_lock_read(&current->mm->mmap_sem);
662
+ might_lock_read(&current->mm->mmap_lock);
685663
686664 if (userptr->mm != current->mm)
687665 return -EPERM;
....@@ -695,10 +673,10 @@
695673 uint64_t ptr = userptr->ptr + pinned * PAGE_SIZE;
696674 struct page **pages = pvec + pinned;
697675
698
- ret = get_user_pages_fast(ptr, num_pages,
699
- !userptr->ro ? FOLL_WRITE : 0, pages);
676
+ ret = pin_user_pages_fast(ptr, num_pages,
677
+ FOLL_WRITE | FOLL_FORCE, pages);
700678 if (ret < 0) {
701
- release_pages(pvec, pinned);
679
+ unpin_user_pages(pvec, pinned);
702680 kvfree(pvec);
703681 return ret;
704682 }
....@@ -722,7 +700,7 @@
722700 if (etnaviv_obj->pages) {
723701 int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
724702
725
- release_pages(etnaviv_obj->pages, npages);
703
+ unpin_user_pages(etnaviv_obj->pages, npages);
726704 kvfree(etnaviv_obj->pages);
727705 }
728706 }
....@@ -746,7 +724,7 @@
746724 struct etnaviv_gem_object *etnaviv_obj;
747725 int ret;
748726
749
- ret = etnaviv_gem_new_private(dev, size, ETNA_BO_CACHED, NULL,
727
+ ret = etnaviv_gem_new_private(dev, size, ETNA_BO_CACHED,
750728 &etnaviv_gem_userptr_ops, &etnaviv_obj);
751729 if (ret)
752730 return ret;
....@@ -762,6 +740,6 @@
762740 ret = drm_gem_handle_create(file, &etnaviv_obj->base, handle);
763741
764742 /* drop reference from allocate - handle holds it now */
765
- drm_gem_object_put_unlocked(&etnaviv_obj->base);
743
+ drm_gem_object_put(&etnaviv_obj->base);
766744 return ret;
767745 }