summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2018-04-18 01:33:02 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-05-10 11:40:02 -0400
commit4dfd6e43cfe303c8b23421ef32738db2ee52e291 (patch)
tree510ce3c59745ea98e44b355d9c4c4cf101bab9c2
parent90b2f780d414d993571dceccafbc01b371068782 (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>
-rw-r--r--drivers/gpu/nvgpu/Makefile4
-rw-r--r--drivers/gpu/nvgpu/common/linux/os_fence_android.c71
-rw-r--r--drivers/gpu/nvgpu/common/linux/os_fence_android_sema.c107
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c117
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h5
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h42
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/os_fence.h111
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
163nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o 163nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o \
164 common/linux/os_fence_android.o \
165 common/linux/os_fence_android_sema.o
164 166
165nvgpu-$(CONFIG_GK20A_PCI) += common/linux/pci.o \ 167nvgpu-$(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
24inline 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
30static 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
37void 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
46void 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
55int 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
30int 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
69static 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
74int 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
96int 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
476void 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
475static int gk20a_channel_semaphore_wait_syncpt( 493static 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
487static 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
538put_fence:
539 sync_fence_put(sync_fence);
540 return err;
541}
542#endif
543
544static int gk20a_channel_semaphore_wait_fd( 504static 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
560static int __gk20a_channel_semaphore_incr( 527static 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;
32struct channel_gk20a; 32struct channel_gk20a;
33struct gk20a_fence; 33struct gk20a_fence;
34struct gk20a; 34struct gk20a;
35struct nvgpu_semaphore;
35 36
36struct gk20a_channel_sync { 37struct 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
107void 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
106void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync, 111void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync,
107 bool set_safe_state); 112 bool set_safe_state);
108struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c, 113struct 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
26struct gk20a;
27struct nvgpu_os_fence;
28struct sync_fence;
29struct channel_gk20a;
30
31struct sync_fence *nvgpu_get_sync_fence(struct nvgpu_os_fence *s);
32
33void nvgpu_os_fence_android_drop_ref(struct nvgpu_os_fence *s);
34
35int nvgpu_os_fence_sema_fdget(struct nvgpu_os_fence *fence_out,
36 struct channel_gk20a *c, int fd);
37
38void 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
28struct nvgpu_semaphore;
29struct channel_gk20a;
30struct 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 */
39struct nvgpu_os_fence;
40
41/*
42 * struct nvgpu_os_fence depends on the following ops structure
43 */
44struct 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 */
68struct 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 */
77static 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
84int nvgpu_os_fence_sema_create(
85 struct nvgpu_os_fence *fence_out,
86 struct channel_gk20a *c,
87 struct nvgpu_semaphore *sema);
88
89int nvgpu_os_fence_fdget(
90 struct nvgpu_os_fence *fence_out,
91 struct channel_gk20a *c, int fd);
92
93#else
94
95static 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}
102static 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__ */