forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/gpu/drm/etnaviv/etnaviv_drv.c
....@@ -4,8 +4,17 @@
44 */
55
66 #include <linux/component.h>
7
+#include <linux/dma-mapping.h>
8
+#include <linux/module.h>
79 #include <linux/of_platform.h>
10
+#include <linux/uaccess.h>
11
+
12
+#include <drm/drm_debugfs.h>
13
+#include <drm/drm_drv.h>
14
+#include <drm/drm_file.h>
15
+#include <drm/drm_ioctl.h>
816 #include <drm/drm_of.h>
17
+#include <drm/drm_prime.h>
918
1019 #include "etnaviv_cmdbuf.h"
1120 #include "etnaviv_drv.h"
....@@ -41,26 +50,38 @@
4150 {
4251 struct etnaviv_drm_private *priv = dev->dev_private;
4352 struct etnaviv_file_private *ctx;
44
- int i;
53
+ int ret, i;
4554
4655 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
4756 if (!ctx)
4857 return -ENOMEM;
4958
59
+ ctx->mmu = etnaviv_iommu_context_init(priv->mmu_global,
60
+ priv->cmdbuf_suballoc);
61
+ if (!ctx->mmu) {
62
+ ret = -ENOMEM;
63
+ goto out_free;
64
+ }
65
+
5066 for (i = 0; i < ETNA_MAX_PIPES; i++) {
5167 struct etnaviv_gpu *gpu = priv->gpu[i];
52
- struct drm_sched_rq *rq;
68
+ struct drm_gpu_scheduler *sched;
5369
5470 if (gpu) {
55
- rq = &gpu->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
71
+ sched = &gpu->sched;
5672 drm_sched_entity_init(&ctx->sched_entity[i],
57
- &rq, 1, NULL);
73
+ DRM_SCHED_PRIORITY_NORMAL, &sched,
74
+ 1, NULL);
5875 }
5976 }
6077
6178 file->driver_priv = ctx;
6279
6380 return 0;
81
+
82
+out_free:
83
+ kfree(ctx);
84
+ return ret;
6485 }
6586
6687 static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file)
....@@ -72,15 +93,11 @@
7293 for (i = 0; i < ETNA_MAX_PIPES; i++) {
7394 struct etnaviv_gpu *gpu = priv->gpu[i];
7495
75
- if (gpu) {
76
- mutex_lock(&gpu->lock);
77
- if (gpu->lastctx == ctx)
78
- gpu->lastctx = NULL;
79
- mutex_unlock(&gpu->lock);
80
-
96
+ if (gpu)
8197 drm_sched_entity_destroy(&ctx->sched_entity[i]);
82
- }
8398 }
99
+
100
+ etnaviv_iommu_context_put(ctx->mmu);
84101
85102 kfree(ctx);
86103 }
....@@ -113,12 +130,29 @@
113130 static int etnaviv_mmu_show(struct etnaviv_gpu *gpu, struct seq_file *m)
114131 {
115132 struct drm_printer p = drm_seq_file_printer(m);
133
+ struct etnaviv_iommu_context *mmu_context;
116134
117135 seq_printf(m, "Active Objects (%s):\n", dev_name(gpu->dev));
118136
119
- mutex_lock(&gpu->mmu->lock);
120
- drm_mm_print(&gpu->mmu->mm, &p);
121
- mutex_unlock(&gpu->mmu->lock);
137
+ /*
138
+ * Lock the GPU to avoid a MMU context switch just now and elevate
139
+ * the refcount of the current context to avoid it disappearing from
140
+ * under our feet.
141
+ */
142
+ mutex_lock(&gpu->lock);
143
+ mmu_context = gpu->mmu_context;
144
+ if (mmu_context)
145
+ etnaviv_iommu_context_get(mmu_context);
146
+ mutex_unlock(&gpu->lock);
147
+
148
+ if (!mmu_context)
149
+ return 0;
150
+
151
+ mutex_lock(&mmu_context->lock);
152
+ drm_mm_print(&mmu_context->mm, &p);
153
+ mutex_unlock(&mmu_context->lock);
154
+
155
+ etnaviv_iommu_context_put(mmu_context);
122156
123157 return 0;
124158 }
....@@ -197,21 +231,11 @@
197231 {"ring", show_each_gpu, 0, etnaviv_ring_show},
198232 };
199233
200
-static int etnaviv_debugfs_init(struct drm_minor *minor)
234
+static void etnaviv_debugfs_init(struct drm_minor *minor)
201235 {
202
- struct drm_device *dev = minor->dev;
203
- int ret;
204
-
205
- ret = drm_debugfs_create_files(etnaviv_debugfs_list,
206
- ARRAY_SIZE(etnaviv_debugfs_list),
207
- minor->debugfs_root, minor);
208
-
209
- if (ret) {
210
- dev_err(dev->dev, "could not install etnaviv_debugfs_list\n");
211
- return ret;
212
- }
213
-
214
- return ret;
236
+ drm_debugfs_create_files(etnaviv_debugfs_list,
237
+ ARRAY_SIZE(etnaviv_debugfs_list),
238
+ minor->debugfs_root, minor);
215239 }
216240 #endif
217241
....@@ -249,11 +273,6 @@
249273 args->flags, &args->handle);
250274 }
251275
252
-#define TS(t) ((struct timespec){ \
253
- .tv_sec = (t).tv_sec, \
254
- .tv_nsec = (t).tv_nsec \
255
-})
256
-
257276 static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
258277 struct drm_file *file)
259278 {
....@@ -268,9 +287,9 @@
268287 if (!obj)
269288 return -ENOENT;
270289
271
- ret = etnaviv_gem_cpu_prep(obj, args->op, &TS(args->timeout));
290
+ ret = etnaviv_gem_cpu_prep(obj, args->op, &args->timeout);
272291
273
- drm_gem_object_put_unlocked(obj);
292
+ drm_gem_object_put(obj);
274293
275294 return ret;
276295 }
....@@ -291,7 +310,7 @@
291310
292311 ret = etnaviv_gem_cpu_fini(obj);
293312
294
- drm_gem_object_put_unlocked(obj);
313
+ drm_gem_object_put(obj);
295314
296315 return ret;
297316 }
....@@ -311,7 +330,7 @@
311330 return -ENOENT;
312331
313332 ret = etnaviv_gem_mmap_offset(obj, &args->offset);
314
- drm_gem_object_put_unlocked(obj);
333
+ drm_gem_object_put(obj);
315334
316335 return ret;
317336 }
....@@ -321,7 +340,7 @@
321340 {
322341 struct drm_etnaviv_wait_fence *args = data;
323342 struct etnaviv_drm_private *priv = dev->dev_private;
324
- struct timespec *timeout = &TS(args->timeout);
343
+ struct drm_etnaviv_timespec *timeout = &args->timeout;
325344 struct etnaviv_gpu *gpu;
326345
327346 if (args->flags & ~(ETNA_WAIT_NONBLOCK))
....@@ -345,7 +364,6 @@
345364 struct drm_file *file)
346365 {
347366 struct drm_etnaviv_gem_userptr *args = data;
348
- int access;
349367
350368 if (args->flags & ~(ETNA_USERPTR_READ|ETNA_USERPTR_WRITE) ||
351369 args->flags == 0)
....@@ -357,12 +375,7 @@
357375 args->user_ptr & ~PAGE_MASK)
358376 return -EINVAL;
359377
360
- if (args->flags & ETNA_USERPTR_WRITE)
361
- access = VERIFY_WRITE;
362
- else
363
- access = VERIFY_READ;
364
-
365
- if (!access_ok(access, (void __user *)(unsigned long)args->user_ptr,
378
+ if (!access_ok((void __user *)(unsigned long)args->user_ptr,
366379 args->user_size))
367380 return -EFAULT;
368381
....@@ -376,7 +389,7 @@
376389 {
377390 struct etnaviv_drm_private *priv = dev->dev_private;
378391 struct drm_etnaviv_gem_wait *args = data;
379
- struct timespec *timeout = &TS(args->timeout);
392
+ struct drm_etnaviv_timespec *timeout = &args->timeout;
380393 struct drm_gem_object *obj;
381394 struct etnaviv_gpu *gpu;
382395 int ret;
....@@ -400,7 +413,7 @@
400413
401414 ret = etnaviv_gem_wait_bo(gpu, obj, timeout);
402415
403
- drm_gem_object_put_unlocked(obj);
416
+ drm_gem_object_put(obj);
404417
405418 return ret;
406419 }
....@@ -442,17 +455,17 @@
442455 static const struct drm_ioctl_desc etnaviv_ioctls[] = {
443456 #define ETNA_IOCTL(n, func, flags) \
444457 DRM_IOCTL_DEF_DRV(ETNAVIV_##n, etnaviv_ioctl_##func, flags)
445
- ETNA_IOCTL(GET_PARAM, get_param, DRM_AUTH|DRM_RENDER_ALLOW),
446
- ETNA_IOCTL(GEM_NEW, gem_new, DRM_AUTH|DRM_RENDER_ALLOW),
447
- ETNA_IOCTL(GEM_INFO, gem_info, DRM_AUTH|DRM_RENDER_ALLOW),
448
- ETNA_IOCTL(GEM_CPU_PREP, gem_cpu_prep, DRM_AUTH|DRM_RENDER_ALLOW),
449
- ETNA_IOCTL(GEM_CPU_FINI, gem_cpu_fini, DRM_AUTH|DRM_RENDER_ALLOW),
450
- ETNA_IOCTL(GEM_SUBMIT, gem_submit, DRM_AUTH|DRM_RENDER_ALLOW),
451
- ETNA_IOCTL(WAIT_FENCE, wait_fence, DRM_AUTH|DRM_RENDER_ALLOW),
452
- ETNA_IOCTL(GEM_USERPTR, gem_userptr, DRM_AUTH|DRM_RENDER_ALLOW),
453
- ETNA_IOCTL(GEM_WAIT, gem_wait, DRM_AUTH|DRM_RENDER_ALLOW),
454
- ETNA_IOCTL(PM_QUERY_DOM, pm_query_dom, DRM_AUTH|DRM_RENDER_ALLOW),
455
- ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_AUTH|DRM_RENDER_ALLOW),
458
+ ETNA_IOCTL(GET_PARAM, get_param, DRM_RENDER_ALLOW),
459
+ ETNA_IOCTL(GEM_NEW, gem_new, DRM_RENDER_ALLOW),
460
+ ETNA_IOCTL(GEM_INFO, gem_info, DRM_RENDER_ALLOW),
461
+ ETNA_IOCTL(GEM_CPU_PREP, gem_cpu_prep, DRM_RENDER_ALLOW),
462
+ ETNA_IOCTL(GEM_CPU_FINI, gem_cpu_fini, DRM_RENDER_ALLOW),
463
+ ETNA_IOCTL(GEM_SUBMIT, gem_submit, DRM_RENDER_ALLOW),
464
+ ETNA_IOCTL(WAIT_FENCE, wait_fence, DRM_RENDER_ALLOW),
465
+ ETNA_IOCTL(GEM_USERPTR, gem_userptr, DRM_RENDER_ALLOW),
466
+ ETNA_IOCTL(GEM_WAIT, gem_wait, DRM_RENDER_ALLOW),
467
+ ETNA_IOCTL(PM_QUERY_DOM, pm_query_dom, DRM_RENDER_ALLOW),
468
+ ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_RENDER_ALLOW),
456469 };
457470
458471 static const struct vm_operations_struct vm_ops = {
....@@ -474,18 +487,13 @@
474487 };
475488
476489 static struct drm_driver etnaviv_drm_driver = {
477
- .driver_features = DRIVER_GEM |
478
- DRIVER_PRIME |
479
- DRIVER_RENDER,
490
+ .driver_features = DRIVER_GEM | DRIVER_RENDER,
480491 .open = etnaviv_open,
481492 .postclose = etnaviv_postclose,
482493 .gem_free_object_unlocked = etnaviv_gem_free_object,
483494 .gem_vm_ops = &vm_ops,
484495 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
485496 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
486
- .gem_prime_export = drm_gem_prime_export,
487
- .gem_prime_import = drm_gem_prime_import,
488
- .gem_prime_res_obj = etnaviv_gem_prime_res_obj,
489497 .gem_prime_pin = etnaviv_gem_prime_pin,
490498 .gem_prime_unpin = etnaviv_gem_prime_unpin,
491499 .gem_prime_get_sg_table = etnaviv_gem_prime_get_sg_table,
....@@ -503,7 +511,7 @@
503511 .desc = "etnaviv DRM",
504512 .date = "20151214",
505513 .major = 1,
506
- .minor = 2,
514
+ .minor = 3,
507515 };
508516
509517 /*
....@@ -523,7 +531,7 @@
523531 if (!priv) {
524532 dev_err(dev, "failed to allocate private data\n");
525533 ret = -ENOMEM;
526
- goto out_unref;
534
+ goto out_put;
527535 }
528536 drm->dev_private = priv;
529537
....@@ -533,27 +541,37 @@
533541 mutex_init(&priv->gem_lock);
534542 INIT_LIST_HEAD(&priv->gem_list);
535543 priv->num_gpus = 0;
544
+ priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
545
+
546
+ priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
547
+ if (IS_ERR(priv->cmdbuf_suballoc)) {
548
+ dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
549
+ ret = PTR_ERR(priv->cmdbuf_suballoc);
550
+ goto out_free_priv;
551
+ }
536552
537553 dev_set_drvdata(dev, drm);
538554
539555 ret = component_bind_all(dev, drm);
540556 if (ret < 0)
541
- goto out_bind;
557
+ goto out_destroy_suballoc;
542558
543559 load_gpu(drm);
544560
545561 ret = drm_dev_register(drm, 0);
546562 if (ret)
547
- goto out_register;
563
+ goto out_unbind;
548564
549565 return 0;
550566
551
-out_register:
567
+out_unbind:
552568 component_unbind_all(dev, drm);
553
-out_bind:
569
+out_destroy_suballoc:
570
+ etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
571
+out_free_priv:
554572 kfree(priv);
555
-out_unref:
556
- drm_dev_unref(drm);
573
+out_put:
574
+ drm_dev_put(drm);
557575
558576 return ret;
559577 }
....@@ -569,10 +587,12 @@
569587
570588 dev->dma_parms = NULL;
571589
590
+ etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
591
+
572592 drm->dev_private = NULL;
573593 kfree(priv);
574594
575
- drm_dev_unref(drm);
595
+ drm_dev_put(drm);
576596 }
577597
578598 static const struct component_master_ops etnaviv_master_ops = {
....@@ -706,7 +726,7 @@
706726 module_exit(etnaviv_exit);
707727
708728 MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>");
709
-MODULE_AUTHOR("Russell King <rmk+kernel@arm.linux.org.uk>");
729
+MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
710730 MODULE_AUTHOR("Lucas Stach <l.stach@pengutronix.de>");
711731 MODULE_DESCRIPTION("etnaviv DRM Driver");
712732 MODULE_LICENSE("GPL v2");