summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c117
1 files changed, 40 insertions, 77 deletions
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