diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | 117 |
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 | ||
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 | ||