diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/driver_common.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 31 |
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. */ | ||
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) |