summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c31
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. */
622int gr_gk20a_disable_ctxsw(struct gk20a *g) 620int 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 */
630int gr_gk20a_enable_ctxsw(struct gk20a *g) 637int 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
637int gr_gk20a_halt_pipe(struct gk20a *g) 654int gr_gk20a_halt_pipe(struct gk20a *g)