diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c index bf467210..c0e035ea 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | |||
@@ -183,6 +183,7 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s, | |||
183 | struct gk20a_channel_syncpt *sp = | 183 | struct gk20a_channel_syncpt *sp = |
184 | container_of(s, struct gk20a_channel_syncpt, ops); | 184 | container_of(s, struct gk20a_channel_syncpt, ops); |
185 | struct channel_gk20a *c = sp->c; | 185 | struct channel_gk20a *c = sp->c; |
186 | struct sync_fence *sync_fence = NULL; | ||
186 | 187 | ||
187 | err = gk20a_channel_alloc_priv_cmdbuf(c, | 188 | err = gk20a_channel_alloc_priv_cmdbuf(c, |
188 | c->g->ops.fifo.get_syncpt_incr_cmd_size(wfi_cmd), | 189 | c->g->ops.fifo.get_syncpt_incr_cmd_size(wfi_cmd), |
@@ -224,10 +225,28 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s, | |||
224 | } | 225 | } |
225 | } | 226 | } |
226 | 227 | ||
227 | err = gk20a_fence_from_syncpt(fence, sp->nvhost_dev, sp->id, thresh, | 228 | #ifdef CONFIG_SYNC |
228 | need_sync_fence); | 229 | if (need_sync_fence) { |
229 | if (err) | 230 | sync_fence = nvgpu_nvhost_sync_create_fence(sp->nvhost_dev, |
231 | sp->id, thresh, "fence"); | ||
232 | |||
233 | if (IS_ERR(sync_fence)) { | ||
234 | err = PTR_ERR(sync_fence); | ||
235 | goto clean_up_priv_cmd; | ||
236 | } | ||
237 | } | ||
238 | #endif | ||
239 | |||
240 | err = gk20a_fence_from_syncpt(fence, sp->nvhost_dev, | ||
241 | sp->id, thresh, sync_fence); | ||
242 | |||
243 | if (err) { | ||
244 | #ifdef CONFIG_SYNC | ||
245 | if (sync_fence) | ||
246 | sync_fence_put(sync_fence); | ||
247 | #endif | ||
230 | goto clean_up_priv_cmd; | 248 | goto clean_up_priv_cmd; |
249 | } | ||
231 | 250 | ||
232 | return 0; | 251 | return 0; |
233 | 252 | ||
@@ -290,12 +309,6 @@ static void gk20a_channel_syncpt_set_safe_state(struct gk20a_channel_sync *s) | |||
290 | nvgpu_nvhost_syncpt_set_safe_state(sp->nvhost_dev, sp->id); | 309 | nvgpu_nvhost_syncpt_set_safe_state(sp->nvhost_dev, sp->id); |
291 | } | 310 | } |
292 | 311 | ||
293 | static void gk20a_channel_syncpt_signal_timeline( | ||
294 | struct gk20a_channel_sync *s) | ||
295 | { | ||
296 | /* Nothing to do. */ | ||
297 | } | ||
298 | |||
299 | static int gk20a_channel_syncpt_id(struct gk20a_channel_sync *s) | 312 | static int gk20a_channel_syncpt_id(struct gk20a_channel_sync *s) |
300 | { | 313 | { |
301 | struct gk20a_channel_syncpt *sp = | 314 | struct gk20a_channel_syncpt *sp = |
@@ -368,7 +381,6 @@ gk20a_channel_syncpt_create(struct channel_gk20a *c, bool user_managed) | |||
368 | sp->ops.incr_user = gk20a_channel_syncpt_incr_user; | 381 | sp->ops.incr_user = gk20a_channel_syncpt_incr_user; |
369 | sp->ops.set_min_eq_max = gk20a_channel_syncpt_set_min_eq_max; | 382 | sp->ops.set_min_eq_max = gk20a_channel_syncpt_set_min_eq_max; |
370 | sp->ops.set_safe_state = gk20a_channel_syncpt_set_safe_state; | 383 | sp->ops.set_safe_state = gk20a_channel_syncpt_set_safe_state; |
371 | sp->ops.signal_timeline = gk20a_channel_syncpt_signal_timeline; | ||
372 | sp->ops.syncpt_id = gk20a_channel_syncpt_id; | 384 | sp->ops.syncpt_id = gk20a_channel_syncpt_id; |
373 | sp->ops.syncpt_address = gk20a_channel_syncpt_address; | 385 | sp->ops.syncpt_address = gk20a_channel_syncpt_address; |
374 | sp->ops.destroy = gk20a_channel_syncpt_destroy; | 386 | sp->ops.destroy = gk20a_channel_syncpt_destroy; |
@@ -383,9 +395,6 @@ struct gk20a_channel_semaphore { | |||
383 | 395 | ||
384 | /* A semaphore pool owned by this channel. */ | 396 | /* A semaphore pool owned by this channel. */ |
385 | struct nvgpu_semaphore_pool *pool; | 397 | struct nvgpu_semaphore_pool *pool; |
386 | |||
387 | /* A sync timeline that advances when gpu completes work. */ | ||
388 | struct sync_timeline *timeline; | ||
389 | }; | 398 | }; |
390 | 399 | ||
391 | static void add_sema_cmd(struct gk20a *g, struct channel_gk20a *c, | 400 | static void add_sema_cmd(struct gk20a *g, struct channel_gk20a *c, |
@@ -560,6 +569,7 @@ static int __gk20a_channel_semaphore_incr( | |||
560 | struct channel_gk20a *c = sp->c; | 569 | struct channel_gk20a *c = sp->c; |
561 | struct nvgpu_semaphore *semaphore; | 570 | struct nvgpu_semaphore *semaphore; |
562 | int err = 0; | 571 | int err = 0; |
572 | struct sync_fence *sync_fence = NULL; | ||
563 | 573 | ||
564 | semaphore = nvgpu_semaphore_alloc(c); | 574 | semaphore = nvgpu_semaphore_alloc(c); |
565 | if (!semaphore) { | 575 | if (!semaphore) { |
@@ -579,12 +589,31 @@ static int __gk20a_channel_semaphore_incr( | |||
579 | /* Release the completion semaphore. */ | 589 | /* Release the completion semaphore. */ |
580 | add_sema_cmd(c->g, c, semaphore, incr_cmd, 0, false, wfi_cmd); | 590 | add_sema_cmd(c->g, c, semaphore, incr_cmd, 0, false, wfi_cmd); |
581 | 591 | ||
582 | err = gk20a_fence_from_semaphore(c->g, fence, | 592 | #ifdef CONFIG_SYNC |
583 | sp->timeline, semaphore, | 593 | if (need_sync_fence) { |
584 | &c->semaphore_wq, | 594 | sync_fence = gk20a_sync_fence_create(c, |
585 | need_sync_fence); | 595 | semaphore, "f-gk20a-0x%04x", |
586 | if (err) | 596 | nvgpu_semaphore_gpu_ro_va(semaphore)); |
597 | |||
598 | if (!sync_fence) { | ||
599 | err = -ENOMEM; | ||
600 | goto clean_up_sema; | ||
601 | } | ||
602 | } | ||
603 | #endif | ||
604 | |||
605 | err = gk20a_fence_from_semaphore(fence, | ||
606 | semaphore, | ||
607 | &c->semaphore_wq, | ||
608 | sync_fence); | ||
609 | |||
610 | if (err) { | ||
611 | #ifdef CONFIG_SYNC | ||
612 | if (sync_fence) | ||
613 | sync_fence_put(sync_fence); | ||
614 | #endif | ||
587 | goto clean_up_sema; | 615 | goto clean_up_sema; |
616 | } | ||
588 | 617 | ||
589 | return 0; | 618 | return 0; |
590 | 619 | ||
@@ -665,14 +694,6 @@ static void gk20a_channel_semaphore_set_safe_state(struct gk20a_channel_sync *s) | |||
665 | /* Nothing to do. */ | 694 | /* Nothing to do. */ |
666 | } | 695 | } |
667 | 696 | ||
668 | static void gk20a_channel_semaphore_signal_timeline( | ||
669 | struct gk20a_channel_sync *s) | ||
670 | { | ||
671 | struct gk20a_channel_semaphore *sp = | ||
672 | container_of(s, struct gk20a_channel_semaphore, ops); | ||
673 | gk20a_sync_timeline_signal(sp->timeline); | ||
674 | } | ||
675 | |||
676 | static int gk20a_channel_semaphore_syncpt_id(struct gk20a_channel_sync *s) | 697 | static int gk20a_channel_semaphore_syncpt_id(struct gk20a_channel_sync *s) |
677 | { | 698 | { |
678 | return -EINVAL; | 699 | return -EINVAL; |
@@ -687,8 +708,13 @@ static void gk20a_channel_semaphore_destroy(struct gk20a_channel_sync *s) | |||
687 | { | 708 | { |
688 | struct gk20a_channel_semaphore *sema = | 709 | struct gk20a_channel_semaphore *sema = |
689 | container_of(s, struct gk20a_channel_semaphore, ops); | 710 | container_of(s, struct gk20a_channel_semaphore, ops); |
690 | if (sema->timeline) | 711 | |
691 | gk20a_sync_timeline_destroy(sema->timeline); | 712 | struct channel_gk20a *c = sema->c; |
713 | struct gk20a *g = c->g; | ||
714 | |||
715 | if (c->has_os_fence_framework_support && | ||
716 | g->os_channel.os_fence_framework_inst_exists(c)) | ||
717 | g->os_channel.destroy_os_fence_framework(c); | ||
692 | 718 | ||
693 | /* The sema pool is cleaned up by the VM destroy. */ | 719 | /* The sema pool is cleaned up by the VM destroy. */ |
694 | sema->pool = NULL; | 720 | sema->pool = NULL; |
@@ -700,10 +726,10 @@ static struct gk20a_channel_sync * | |||
700 | gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed) | 726 | gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed) |
701 | { | 727 | { |
702 | struct gk20a_channel_semaphore *sema; | 728 | struct gk20a_channel_semaphore *sema; |
729 | struct gk20a *g = c->g; | ||
703 | char pool_name[20]; | 730 | char pool_name[20]; |
704 | #ifdef CONFIG_SYNC | ||
705 | int asid = -1; | 731 | int asid = -1; |
706 | #endif | 732 | int err; |
707 | 733 | ||
708 | if (WARN_ON(!c->vm)) | 734 | if (WARN_ON(!c->vm)) |
709 | return NULL; | 735 | return NULL; |
@@ -716,17 +742,20 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed) | |||
716 | sprintf(pool_name, "semaphore_pool-%d", c->chid); | 742 | sprintf(pool_name, "semaphore_pool-%d", c->chid); |
717 | sema->pool = c->vm->sema_pool; | 743 | sema->pool = c->vm->sema_pool; |
718 | 744 | ||
719 | #ifdef CONFIG_SYNC | ||
720 | if (c->vm->as_share) | 745 | if (c->vm->as_share) |
721 | asid = c->vm->as_share->id; | 746 | asid = c->vm->as_share->id; |
722 | 747 | ||
723 | sema->timeline = gk20a_sync_timeline_create( | 748 | if (c->has_os_fence_framework_support) { |
749 | /*Init the sync_timeline for this channel */ | ||
750 | err = g->os_channel.init_os_fence_framework(c, | ||
724 | "gk20a_ch%d_as%d", c->chid, asid); | 751 | "gk20a_ch%d_as%d", c->chid, asid); |
725 | if (!sema->timeline) { | 752 | |
726 | gk20a_channel_semaphore_destroy(&sema->ops); | 753 | if (err) { |
727 | return NULL; | 754 | nvgpu_kfree(g, sema); |
755 | return NULL; | ||
756 | } | ||
728 | } | 757 | } |
729 | #endif | 758 | |
730 | nvgpu_atomic_set(&sema->ops.refcount, 0); | 759 | nvgpu_atomic_set(&sema->ops.refcount, 0); |
731 | sema->ops.wait_syncpt = gk20a_channel_semaphore_wait_syncpt; | 760 | sema->ops.wait_syncpt = gk20a_channel_semaphore_wait_syncpt; |
732 | sema->ops.wait_fd = gk20a_channel_semaphore_wait_fd; | 761 | sema->ops.wait_fd = gk20a_channel_semaphore_wait_fd; |
@@ -735,7 +764,6 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed) | |||
735 | sema->ops.incr_user = gk20a_channel_semaphore_incr_user; | 764 | sema->ops.incr_user = gk20a_channel_semaphore_incr_user; |
736 | sema->ops.set_min_eq_max = gk20a_channel_semaphore_set_min_eq_max; | 765 | sema->ops.set_min_eq_max = gk20a_channel_semaphore_set_min_eq_max; |
737 | sema->ops.set_safe_state = gk20a_channel_semaphore_set_safe_state; | 766 | sema->ops.set_safe_state = gk20a_channel_semaphore_set_safe_state; |
738 | sema->ops.signal_timeline = gk20a_channel_semaphore_signal_timeline; | ||
739 | sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id; | 767 | sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id; |
740 | sema->ops.syncpt_address = gk20a_channel_semaphore_syncpt_address; | 768 | sema->ops.syncpt_address = gk20a_channel_semaphore_syncpt_address; |
741 | sema->ops.destroy = gk20a_channel_semaphore_destroy; | 769 | sema->ops.destroy = gk20a_channel_semaphore_destroy; |