diff options
author | Debarshi Dutta <ddutta@nvidia.com> | 2018-04-18 01:33:02 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-05-10 11:40:02 -0400 |
commit | 4dfd6e43cfe303c8b23421ef32738db2ee52e291 (patch) | |
tree | 510ce3c59745ea98e44b355d9c4c4cf101bab9c2 /drivers/gpu | |
parent | 90b2f780d414d993571dceccafbc01b371068782 (diff) |
gpu: nvgpu: create a wrapper over sync_fences
This patch constructs an abstraction to hide the sync_fence
functionality from the common code. struct nvgpu_os_fence acts as an
abstraction for struct sync_fence.
struct nvgpu_os_fence consists of an ops structure named nvgpu_os_fence_ops
which contains an API to do pushbuffer programming to generate wait
commands for the fence.
The current implementation of nvgpu only allows for wait method on a
sync_fence which was generated using a similar backend(i.e. either
Nvhost Syncpoints or Semaphores). In this patch, a
generic API is introduced which will decide the type of the underlying
implementation of the struct nvgpu_os_fence at runtime and run the
corresponding wait implementation on it.
This patch changes the channel_sync_gk20a's semaphore specific
implementation to use the abstract API. A subsequent patch will make
the changes for the nvhost_syncpoint based implementations as well.
JIRA NVGPU-66
Change-Id: If6675bfde5885c3d15d2ca380bb6c7c0e240e734
Signed-off-by: Debarshi Dutta <ddutta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1667218
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/Makefile | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/os_fence_android.c | 71 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/os_fence_android_sema.c | 107 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | 117 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h | 42 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/os_fence.h | 111 |
7 files changed, 379 insertions, 78 deletions
diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 32166f31..9a46f12c 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile | |||
@@ -160,7 +160,9 @@ nvgpu-$(CONFIG_TEGRA_GK20A) += \ | |||
160 | common/linux/platform_gp10b_tegra.o \ | 160 | common/linux/platform_gp10b_tegra.o \ |
161 | common/linux/platform_gv11b_tegra.o | 161 | common/linux/platform_gv11b_tegra.o |
162 | 162 | ||
163 | nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o | 163 | nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o \ |
164 | common/linux/os_fence_android.o \ | ||
165 | common/linux/os_fence_android_sema.o | ||
164 | 166 | ||
165 | nvgpu-$(CONFIG_GK20A_PCI) += common/linux/pci.o \ | 167 | nvgpu-$(CONFIG_GK20A_PCI) += common/linux/pci.o \ |
166 | common/linux/pci_usermode.o \ | 168 | common/linux/pci_usermode.o \ |
diff --git a/drivers/gpu/nvgpu/common/linux/os_fence_android.c b/drivers/gpu/nvgpu/common/linux/os_fence_android.c new file mode 100644 index 00000000..d689a2a8 --- /dev/null +++ b/drivers/gpu/nvgpu/common/linux/os_fence_android.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | #include <nvgpu/types.h> | ||
17 | #include <nvgpu/os_fence.h> | ||
18 | #include <nvgpu/linux/os_fence_android.h> | ||
19 | |||
20 | #include "gk20a/gk20a.h" | ||
21 | |||
22 | #include "../drivers/staging/android/sync.h" | ||
23 | |||
24 | inline struct sync_fence *nvgpu_get_sync_fence(struct nvgpu_os_fence *s) | ||
25 | { | ||
26 | struct sync_fence *fence = (struct sync_fence *)s->priv; | ||
27 | return fence; | ||
28 | } | ||
29 | |||
30 | static void nvgpu_os_fence_clear(struct nvgpu_os_fence *fence_out) | ||
31 | { | ||
32 | fence_out->priv = NULL; | ||
33 | fence_out->g = NULL; | ||
34 | fence_out->ops = NULL; | ||
35 | } | ||
36 | |||
37 | void nvgpu_os_fence_init(struct nvgpu_os_fence *fence_out, | ||
38 | struct gk20a *g, const struct nvgpu_os_fence_ops *fops, | ||
39 | struct sync_fence *fence) | ||
40 | { | ||
41 | fence_out->g = g; | ||
42 | fence_out->ops = fops; | ||
43 | fence_out->priv = (void *)fence; | ||
44 | } | ||
45 | |||
46 | void nvgpu_os_fence_android_drop_ref(struct nvgpu_os_fence *s) | ||
47 | { | ||
48 | struct sync_fence *fence = nvgpu_get_sync_fence(s); | ||
49 | |||
50 | sync_fence_put(fence); | ||
51 | |||
52 | nvgpu_os_fence_clear(s); | ||
53 | } | ||
54 | |||
55 | int nvgpu_os_fence_fdget(struct nvgpu_os_fence *fence_out, | ||
56 | struct channel_gk20a *c, int fd) | ||
57 | { | ||
58 | int err; | ||
59 | |||
60 | err = nvgpu_os_fence_sema_fdget(fence_out, c, fd); | ||
61 | |||
62 | /* TO-DO | ||
63 | * check if fence is empty and if CONFIG_TEGRA_GK20A_NVHOST | ||
64 | * is enabled, try to get a sync_fence using | ||
65 | * corresponding nvhost method. | ||
66 | */ | ||
67 | if (err) | ||
68 | nvgpu_err(c->g, "error obtaining fence from fd %d", fd); | ||
69 | |||
70 | return err; | ||
71 | } | ||
diff --git a/drivers/gpu/nvgpu/common/linux/os_fence_android_sema.c b/drivers/gpu/nvgpu/common/linux/os_fence_android_sema.c new file mode 100644 index 00000000..b61bd893 --- /dev/null +++ b/drivers/gpu/nvgpu/common/linux/os_fence_android_sema.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <nvgpu/errno.h> | ||
18 | |||
19 | #include <nvgpu/types.h> | ||
20 | #include <nvgpu/os_fence.h> | ||
21 | #include <nvgpu/linux/os_fence_android.h> | ||
22 | #include <nvgpu/semaphore.h> | ||
23 | |||
24 | #include "gk20a/sync_gk20a.h" | ||
25 | #include "gk20a/channel_sync_gk20a.h" | ||
26 | #include "gk20a/mm_gk20a.h" | ||
27 | |||
28 | #include "../drivers/staging/android/sync.h" | ||
29 | |||
30 | int nvgpu_os_fence_sema_wait_gen_cmd(struct nvgpu_os_fence *s, | ||
31 | struct priv_cmd_entry *wait_cmd, | ||
32 | struct channel_gk20a *c, | ||
33 | int max_wait_cmds) | ||
34 | { | ||
35 | int err; | ||
36 | const int wait_cmd_size = 8; | ||
37 | int num_wait_cmds; | ||
38 | int i; | ||
39 | struct nvgpu_semaphore *sema; | ||
40 | struct sync_fence *sync_fence = nvgpu_get_sync_fence(s); | ||
41 | |||
42 | num_wait_cmds = sync_fence->num_fences; | ||
43 | if (num_wait_cmds == 0) | ||
44 | return 0; | ||
45 | |||
46 | if (max_wait_cmds && num_wait_cmds > max_wait_cmds) | ||
47 | return -EINVAL; | ||
48 | |||
49 | err = gk20a_channel_alloc_priv_cmdbuf(c, | ||
50 | wait_cmd_size * num_wait_cmds, | ||
51 | wait_cmd); | ||
52 | if (err) { | ||
53 | nvgpu_err(c->g, "not enough priv cmd buffer space"); | ||
54 | return err; | ||
55 | } | ||
56 | |||
57 | for (i = 0; i < num_wait_cmds; i++) { | ||
58 | struct fence *f = sync_fence->cbs[i].sync_pt; | ||
59 | struct sync_pt *pt = sync_pt_from_fence(f); | ||
60 | |||
61 | sema = gk20a_sync_pt_sema(pt); | ||
62 | gk20a_channel_gen_sema_wait_cmd(c, sema, wait_cmd, | ||
63 | wait_cmd_size, i); | ||
64 | } | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static const struct nvgpu_os_fence_ops sema_ops = { | ||
70 | .program_waits = nvgpu_os_fence_sema_wait_gen_cmd, | ||
71 | .drop_ref = nvgpu_os_fence_android_drop_ref, | ||
72 | }; | ||
73 | |||
74 | int nvgpu_os_fence_sema_create( | ||
75 | struct nvgpu_os_fence *fence_out, | ||
76 | struct channel_gk20a *c, | ||
77 | struct nvgpu_semaphore *sema) | ||
78 | { | ||
79 | struct sync_fence *fence; | ||
80 | |||
81 | fence = gk20a_sync_fence_create(c, sema, "f-gk20a-0x%04x", | ||
82 | nvgpu_semaphore_gpu_ro_va(sema)); | ||
83 | |||
84 | if (!fence) { | ||
85 | nvgpu_err(c->g, "error constructing new fence: f-gk20a-0x%04x", | ||
86 | (u32)nvgpu_semaphore_gpu_ro_va(sema)); | ||
87 | |||
88 | return -ENOMEM; | ||
89 | } | ||
90 | |||
91 | nvgpu_os_fence_init(fence_out, c->g, &sema_ops, fence); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | int nvgpu_os_fence_sema_fdget(struct nvgpu_os_fence *fence_out, | ||
97 | struct channel_gk20a *c, int fd) | ||
98 | { | ||
99 | struct sync_fence *fence = gk20a_sync_fence_fdget(fd); | ||
100 | |||
101 | if (!fence) | ||
102 | return -EINVAL; | ||
103 | |||
104 | nvgpu_os_fence_init(fence_out, c->g, &sema_ops, fence); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c index c0e035ea..a0b0ac1e 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <nvgpu/bug.h> | 29 | #include <nvgpu/bug.h> |
30 | #include <nvgpu/list.h> | 30 | #include <nvgpu/list.h> |
31 | #include <nvgpu/nvhost.h> | 31 | #include <nvgpu/nvhost.h> |
32 | #include <nvgpu/os_fence.h> | ||
32 | 33 | ||
33 | #include "channel_sync_gk20a.h" | 34 | #include "channel_sync_gk20a.h" |
34 | #include "gk20a.h" | 35 | #include "gk20a.h" |
@@ -472,6 +473,23 @@ static void add_sema_cmd(struct gk20a *g, struct channel_gk20a *c, | |||
472 | va, cmd->gva, cmd->mem->gpu_va, ob); | 473 | va, cmd->gva, cmd->mem->gpu_va, ob); |
473 | } | 474 | } |
474 | 475 | ||
476 | void gk20a_channel_gen_sema_wait_cmd(struct channel_gk20a *c, | ||
477 | struct nvgpu_semaphore *sema, struct priv_cmd_entry *wait_cmd, | ||
478 | u32 wait_cmd_size, int pos) | ||
479 | { | ||
480 | if (!sema) { | ||
481 | /* expired */ | ||
482 | nvgpu_memset(c->g, wait_cmd->mem, | ||
483 | (wait_cmd->off + pos * wait_cmd_size) * sizeof(u32), | ||
484 | 0, wait_cmd_size * sizeof(u32)); | ||
485 | } else { | ||
486 | WARN_ON(!sema->incremented); | ||
487 | add_sema_cmd(c->g, c, sema, wait_cmd, | ||
488 | pos * wait_cmd_size, true, false); | ||
489 | nvgpu_semaphore_put(sema); | ||
490 | } | ||
491 | } | ||
492 | |||
475 | static int gk20a_channel_semaphore_wait_syncpt( | 493 | static int gk20a_channel_semaphore_wait_syncpt( |
476 | struct gk20a_channel_sync *s, u32 id, | 494 | struct gk20a_channel_sync *s, u32 id, |
477 | u32 thresh, struct priv_cmd_entry *entry) | 495 | u32 thresh, struct priv_cmd_entry *entry) |
@@ -483,64 +501,6 @@ static int gk20a_channel_semaphore_wait_syncpt( | |||
483 | return -ENODEV; | 501 | return -ENODEV; |
484 | } | 502 | } |
485 | 503 | ||
486 | #ifdef CONFIG_SYNC | ||
487 | static int semaphore_wait_fd_native(struct channel_gk20a *c, int fd, | ||
488 | struct priv_cmd_entry *wait_cmd, int max_wait_cmds) | ||
489 | { | ||
490 | struct sync_fence *sync_fence; | ||
491 | int err; | ||
492 | const int wait_cmd_size = 8; | ||
493 | int num_wait_cmds; | ||
494 | int i; | ||
495 | |||
496 | sync_fence = gk20a_sync_fence_fdget(fd); | ||
497 | if (!sync_fence) | ||
498 | return -EINVAL; | ||
499 | |||
500 | num_wait_cmds = sync_fence->num_fences; | ||
501 | if (num_wait_cmds == 0) { | ||
502 | err = 0; | ||
503 | goto put_fence; | ||
504 | } | ||
505 | |||
506 | if (max_wait_cmds && sync_fence->num_fences > max_wait_cmds) { | ||
507 | err = -EINVAL; | ||
508 | goto put_fence; | ||
509 | } | ||
510 | |||
511 | err = gk20a_channel_alloc_priv_cmdbuf(c, | ||
512 | wait_cmd_size * num_wait_cmds, | ||
513 | wait_cmd); | ||
514 | if (err) { | ||
515 | nvgpu_err(c->g, "not enough priv cmd buffer space"); | ||
516 | goto put_fence; | ||
517 | } | ||
518 | |||
519 | for (i = 0; i < sync_fence->num_fences; i++) { | ||
520 | struct fence *f = sync_fence->cbs[i].sync_pt; | ||
521 | struct sync_pt *pt = sync_pt_from_fence(f); | ||
522 | struct nvgpu_semaphore *sema; | ||
523 | |||
524 | sema = gk20a_sync_pt_sema(pt); | ||
525 | if (!sema) { | ||
526 | /* expired */ | ||
527 | nvgpu_memset(c->g, wait_cmd->mem, | ||
528 | (wait_cmd->off + i * wait_cmd_size) * sizeof(u32), | ||
529 | 0, wait_cmd_size * sizeof(u32)); | ||
530 | } else { | ||
531 | WARN_ON(!sema->incremented); | ||
532 | add_sema_cmd(c->g, c, sema, wait_cmd, | ||
533 | i * wait_cmd_size, true, false); | ||
534 | nvgpu_semaphore_put(sema); | ||
535 | } | ||
536 | } | ||
537 | |||
538 | put_fence: | ||
539 | sync_fence_put(sync_fence); | ||
540 | return err; | ||
541 | } | ||
542 | #endif | ||
543 | |||
544 | static int gk20a_channel_semaphore_wait_fd( | 504 | static int gk20a_channel_semaphore_wait_fd( |
545 | struct gk20a_channel_sync *s, int fd, | 505 | struct gk20a_channel_sync *s, int fd, |
546 | struct priv_cmd_entry *entry, int max_wait_cmds) | 506 | struct priv_cmd_entry *entry, int max_wait_cmds) |
@@ -548,13 +508,20 @@ static int gk20a_channel_semaphore_wait_fd( | |||
548 | struct gk20a_channel_semaphore *sema = | 508 | struct gk20a_channel_semaphore *sema = |
549 | container_of(s, struct gk20a_channel_semaphore, ops); | 509 | container_of(s, struct gk20a_channel_semaphore, ops); |
550 | struct channel_gk20a *c = sema->c; | 510 | struct channel_gk20a *c = sema->c; |
551 | #ifdef CONFIG_SYNC | 511 | |
552 | return semaphore_wait_fd_native(c, fd, entry, max_wait_cmds); | 512 | struct nvgpu_os_fence os_fence = {0}; |
553 | #else | 513 | int err; |
554 | nvgpu_err(c->g, | 514 | |
555 | "trying to use sync fds with CONFIG_SYNC disabled"); | 515 | err = nvgpu_os_fence_fdget(&os_fence, c, fd); |
556 | return -ENODEV; | 516 | if (err) |
557 | #endif | 517 | return err; |
518 | |||
519 | err = os_fence.ops->program_waits(&os_fence, | ||
520 | entry, c, max_wait_cmds); | ||
521 | |||
522 | os_fence.ops->drop_ref(&os_fence); | ||
523 | |||
524 | return err; | ||
558 | } | 525 | } |
559 | 526 | ||
560 | static int __gk20a_channel_semaphore_incr( | 527 | static int __gk20a_channel_semaphore_incr( |
@@ -570,6 +537,7 @@ static int __gk20a_channel_semaphore_incr( | |||
570 | struct nvgpu_semaphore *semaphore; | 537 | struct nvgpu_semaphore *semaphore; |
571 | int err = 0; | 538 | int err = 0; |
572 | struct sync_fence *sync_fence = NULL; | 539 | struct sync_fence *sync_fence = NULL; |
540 | struct nvgpu_os_fence os_fence = {0}; | ||
573 | 541 | ||
574 | semaphore = nvgpu_semaphore_alloc(c); | 542 | semaphore = nvgpu_semaphore_alloc(c); |
575 | if (!semaphore) { | 543 | if (!semaphore) { |
@@ -589,18 +557,15 @@ static int __gk20a_channel_semaphore_incr( | |||
589 | /* Release the completion semaphore. */ | 557 | /* Release the completion semaphore. */ |
590 | add_sema_cmd(c->g, c, semaphore, incr_cmd, 0, false, wfi_cmd); | 558 | add_sema_cmd(c->g, c, semaphore, incr_cmd, 0, false, wfi_cmd); |
591 | 559 | ||
592 | #ifdef CONFIG_SYNC | ||
593 | if (need_sync_fence) { | 560 | if (need_sync_fence) { |
594 | sync_fence = gk20a_sync_fence_create(c, | 561 | err = nvgpu_os_fence_sema_create(&os_fence, c, |
595 | semaphore, "f-gk20a-0x%04x", | 562 | semaphore); |
596 | nvgpu_semaphore_gpu_ro_va(semaphore)); | ||
597 | 563 | ||
598 | if (!sync_fence) { | 564 | if (err) |
599 | err = -ENOMEM; | ||
600 | goto clean_up_sema; | 565 | goto clean_up_sema; |
601 | } | 566 | |
567 | sync_fence = (struct sync_fence *)os_fence.priv; | ||
602 | } | 568 | } |
603 | #endif | ||
604 | 569 | ||
605 | err = gk20a_fence_from_semaphore(fence, | 570 | err = gk20a_fence_from_semaphore(fence, |
606 | semaphore, | 571 | semaphore, |
@@ -608,10 +573,8 @@ static int __gk20a_channel_semaphore_incr( | |||
608 | sync_fence); | 573 | sync_fence); |
609 | 574 | ||
610 | if (err) { | 575 | if (err) { |
611 | #ifdef CONFIG_SYNC | 576 | if (nvgpu_os_fence_is_initialized(&os_fence)) |
612 | if (sync_fence) | 577 | os_fence.ops->drop_ref(&os_fence); |
613 | sync_fence_put(sync_fence); | ||
614 | #endif | ||
615 | goto clean_up_sema; | 578 | goto clean_up_sema; |
616 | } | 579 | } |
617 | 580 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h index d63b358f..565b4f86 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h | |||
@@ -32,6 +32,7 @@ struct priv_cmd_entry; | |||
32 | struct channel_gk20a; | 32 | struct channel_gk20a; |
33 | struct gk20a_fence; | 33 | struct gk20a_fence; |
34 | struct gk20a; | 34 | struct gk20a; |
35 | struct nvgpu_semaphore; | ||
35 | 36 | ||
36 | struct gk20a_channel_sync { | 37 | struct gk20a_channel_sync { |
37 | nvgpu_atomic_t refcount; | 38 | nvgpu_atomic_t refcount; |
@@ -103,6 +104,10 @@ struct gk20a_channel_sync { | |||
103 | void (*destroy)(struct gk20a_channel_sync *s); | 104 | void (*destroy)(struct gk20a_channel_sync *s); |
104 | }; | 105 | }; |
105 | 106 | ||
107 | void gk20a_channel_gen_sema_wait_cmd(struct channel_gk20a *c, | ||
108 | struct nvgpu_semaphore *sema, struct priv_cmd_entry *wait_cmd, | ||
109 | u32 wait_cmd_size, int pos); | ||
110 | |||
106 | void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync, | 111 | void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync, |
107 | bool set_safe_state); | 112 | bool set_safe_state); |
108 | struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c, | 113 | struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c, |
diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h b/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h new file mode 100644 index 00000000..79cc51ea --- /dev/null +++ b/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | * DEALINGS IN THE SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #ifndef __NVGPU_OS_FENCE_ANDROID_H__ | ||
24 | #define __NVGPU_OS_FENCE_ANDROID_H__ | ||
25 | |||
26 | struct gk20a; | ||
27 | struct nvgpu_os_fence; | ||
28 | struct sync_fence; | ||
29 | struct channel_gk20a; | ||
30 | |||
31 | struct sync_fence *nvgpu_get_sync_fence(struct nvgpu_os_fence *s); | ||
32 | |||
33 | void nvgpu_os_fence_android_drop_ref(struct nvgpu_os_fence *s); | ||
34 | |||
35 | int nvgpu_os_fence_sema_fdget(struct nvgpu_os_fence *fence_out, | ||
36 | struct channel_gk20a *c, int fd); | ||
37 | |||
38 | void nvgpu_os_fence_init(struct nvgpu_os_fence *fence_out, | ||
39 | struct gk20a *g, const struct nvgpu_os_fence_ops *fops, | ||
40 | struct sync_fence *fence); | ||
41 | |||
42 | #endif \ No newline at end of file | ||
diff --git a/drivers/gpu/nvgpu/include/nvgpu/os_fence.h b/drivers/gpu/nvgpu/include/nvgpu/os_fence.h new file mode 100644 index 00000000..c8d24fc2 --- /dev/null +++ b/drivers/gpu/nvgpu/include/nvgpu/os_fence.h | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * nvgpu os fence | ||
3 | * | ||
4 | * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
22 | * DEALINGS IN THE SOFTWARE. | ||
23 | */ | ||
24 | |||
25 | #ifndef __NVGPU_OS_FENCE__ | ||
26 | #define __NVGPU_OS_FENCE__ | ||
27 | |||
28 | struct nvgpu_semaphore; | ||
29 | struct channel_gk20a; | ||
30 | struct priv_cmd_entry; | ||
31 | |||
32 | /* | ||
33 | * struct nvgpu_os_fence adds an abstraction to the earlier Android Sync | ||
34 | * Framework, specifically the sync-fence mechanism and the newer DMA sync | ||
35 | * APIs from linux-4.9. This abstraction provides the high-level definition | ||
36 | * as well as APIs that can be used by other OSes in future to have their own | ||
37 | * alternatives for the sync-framework. | ||
38 | */ | ||
39 | struct nvgpu_os_fence; | ||
40 | |||
41 | /* | ||
42 | * struct nvgpu_os_fence depends on the following ops structure | ||
43 | */ | ||
44 | struct nvgpu_os_fence_ops { | ||
45 | /* | ||
46 | * This API is used to iterate through multiple fence points within the | ||
47 | * fence and program the pushbuffer method for wait command. | ||
48 | */ | ||
49 | int (*program_waits)(struct nvgpu_os_fence *s, | ||
50 | struct priv_cmd_entry *wait_cmd, | ||
51 | struct channel_gk20a *c, | ||
52 | int max_wait_cmds); | ||
53 | |||
54 | /* | ||
55 | * This should be the last operation on the OS fence. The | ||
56 | * OS fence acts as a place-holder for the underlying fence | ||
57 | * implementation e.g. sync_fences. For each construct/fdget call | ||
58 | * there needs to be a drop_ref call. This reduces a reference count | ||
59 | * for the underlying sync_fence. | ||
60 | */ | ||
61 | void (*drop_ref)(struct nvgpu_os_fence *s); | ||
62 | }; | ||
63 | |||
64 | /* | ||
65 | * The priv structure here is used to contain the struct sync_fence | ||
66 | * for LINUX_VERSION <= 4.9 and dma_fence for LINUX_VERSION > 4.9 | ||
67 | */ | ||
68 | struct nvgpu_os_fence { | ||
69 | void *priv; | ||
70 | struct gk20a *g; | ||
71 | const struct nvgpu_os_fence_ops *ops; | ||
72 | }; | ||
73 | |||
74 | /* | ||
75 | * This API is used to validate the nvgpu_os_fence | ||
76 | */ | ||
77 | static inline int nvgpu_os_fence_is_initialized(struct nvgpu_os_fence *fence) | ||
78 | { | ||
79 | return (fence->ops != NULL); | ||
80 | } | ||
81 | |||
82 | #ifdef CONFIG_SYNC | ||
83 | |||
84 | int nvgpu_os_fence_sema_create( | ||
85 | struct nvgpu_os_fence *fence_out, | ||
86 | struct channel_gk20a *c, | ||
87 | struct nvgpu_semaphore *sema); | ||
88 | |||
89 | int nvgpu_os_fence_fdget( | ||
90 | struct nvgpu_os_fence *fence_out, | ||
91 | struct channel_gk20a *c, int fd); | ||
92 | |||
93 | #else | ||
94 | |||
95 | static inline int nvgpu_os_fence_sema_create( | ||
96 | struct nvgpu_os_fence *fence_out, | ||
97 | struct channel_gk20a *c, | ||
98 | struct nvgpu_semaphore *sema) | ||
99 | { | ||
100 | return -ENOSYS; | ||
101 | } | ||
102 | static inline int nvgpu_os_fence_fdget( | ||
103 | struct nvgpu_os_fence *fence_out, | ||
104 | struct channel_gk20a *c, int fd) | ||
105 | { | ||
106 | return -ENOSYS; | ||
107 | } | ||
108 | |||
109 | #endif /* CONFIG_SYNC */ | ||
110 | |||
111 | #endif /* __NVGPU_OS_FENCE__ */ | ||