diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 31 |
2 files changed, 27 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 3442861c..4ebdb6a4 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -1191,6 +1191,9 @@ struct gk20a { | |||
1191 | 1191 | ||
1192 | nvgpu_atomic_t usage_count; | 1192 | nvgpu_atomic_t usage_count; |
1193 | 1193 | ||
1194 | struct nvgpu_mutex ctxsw_disable_lock; | ||
1195 | int ctxsw_disable_count; | ||
1196 | |||
1194 | struct nvgpu_ref refcount; | 1197 | struct nvgpu_ref refcount; |
1195 | 1198 | ||
1196 | const char *name; | 1199 | const char *name; |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 61975106..8a3f98af 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -616,22 +616,39 @@ static int gr_gk20a_ctrl_ctxsw(struct gk20a *g, u32 fecs_method, u32 *ret) | |||
616 | .cond.fail = GR_IS_UCODE_OP_EQUAL }, true); | 616 | .cond.fail = GR_IS_UCODE_OP_EQUAL }, true); |
617 | } | 617 | } |
618 | 618 | ||
619 | /* Stop processing (stall) context switches at FECS. | 619 | /* Stop processing (stall) context switches at FECS. */ |
620 | * The caller must hold the dbg_sessions_lock, else if mutliple stop methods | ||
621 | * are sent to the ucode in sequence, it can get into an undefined state. */ | ||
622 | int gr_gk20a_disable_ctxsw(struct gk20a *g) | 620 | int gr_gk20a_disable_ctxsw(struct gk20a *g) |
623 | { | 621 | { |
622 | int err = 0; | ||
623 | |||
624 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); | 624 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); |
625 | return gr_gk20a_ctrl_ctxsw(g, | 625 | |
626 | gr_fecs_method_push_adr_stop_ctxsw_v(), NULL); | 626 | nvgpu_mutex_acquire(&g->ctxsw_disable_lock); |
627 | g->ctxsw_disable_count++; | ||
628 | if (g->ctxsw_disable_count == 1) | ||
629 | err = gr_gk20a_ctrl_ctxsw(g, | ||
630 | gr_fecs_method_push_adr_stop_ctxsw_v(), NULL); | ||
631 | nvgpu_mutex_release(&g->ctxsw_disable_lock); | ||
632 | |||
633 | return err; | ||
627 | } | 634 | } |
628 | 635 | ||
629 | /* Start processing (continue) context switches at FECS */ | 636 | /* Start processing (continue) context switches at FECS */ |
630 | int gr_gk20a_enable_ctxsw(struct gk20a *g) | 637 | int gr_gk20a_enable_ctxsw(struct gk20a *g) |
631 | { | 638 | { |
639 | int err = 0; | ||
640 | |||
632 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); | 641 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); |
633 | return gr_gk20a_ctrl_ctxsw(g, | 642 | |
634 | gr_fecs_method_push_adr_start_ctxsw_v(), NULL); | 643 | nvgpu_mutex_acquire(&g->ctxsw_disable_lock); |
644 | g->ctxsw_disable_count--; | ||
645 | WARN_ON(g->ctxsw_disable_count < 0); | ||
646 | if (g->ctxsw_disable_count == 0) | ||
647 | err = gr_gk20a_ctrl_ctxsw(g, | ||
648 | gr_fecs_method_push_adr_start_ctxsw_v(), NULL); | ||
649 | nvgpu_mutex_release(&g->ctxsw_disable_lock); | ||
650 | |||
651 | return err; | ||
635 | } | 652 | } |
636 | 653 | ||
637 | int gr_gk20a_halt_pipe(struct gk20a *g) | 654 | int gr_gk20a_halt_pipe(struct gk20a *g) |