summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/common/linux/driver_common.c1
-rw-r--r--drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c1
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c31
4 files changed, 29 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c
index 9029366f..695bb307 100644
--- a/drivers/gpu/nvgpu/common/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/common/linux/driver_common.c
@@ -62,6 +62,7 @@ static void nvgpu_init_vars(struct gk20a *g)
62 nvgpu_mutex_init(&g->client_lock); 62 nvgpu_mutex_init(&g->client_lock);
63 nvgpu_mutex_init(&g->poweron_lock); 63 nvgpu_mutex_init(&g->poweron_lock);
64 nvgpu_mutex_init(&g->poweroff_lock); 64 nvgpu_mutex_init(&g->poweroff_lock);
65 nvgpu_mutex_init(&g->ctxsw_disable_lock);
65 66
66 l->regs_saved = l->regs; 67 l->regs_saved = l->regs;
67 l->bar1_saved = l->bar1; 68 l->bar1_saved = l->bar1;
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
index 1e5efa38..6f040603 100644
--- a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
+++ b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
@@ -76,6 +76,7 @@ static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform)
76 76
77 nvgpu_mutex_init(&g->poweron_lock); 77 nvgpu_mutex_init(&g->poweron_lock);
78 nvgpu_mutex_init(&g->poweroff_lock); 78 nvgpu_mutex_init(&g->poweroff_lock);
79 nvgpu_mutex_init(&g->ctxsw_disable_lock);
79 l->regs_saved = l->regs; 80 l->regs_saved = l->regs;
80 l->bar1_saved = l->bar1; 81 l->bar1_saved = l->bar1;
81 82
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)