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.c102
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
293static void gk20a_channel_syncpt_signal_timeline(
294 struct gk20a_channel_sync *s)
295{
296 /* Nothing to do. */
297}
298
299static int gk20a_channel_syncpt_id(struct gk20a_channel_sync *s) 312static 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
391static void add_sema_cmd(struct gk20a *g, struct channel_gk20a *c, 400static 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
668static 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
676static int gk20a_channel_semaphore_syncpt_id(struct gk20a_channel_sync *s) 697static 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 *
700gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed) 726gk20a_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;