diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index 94486064..39941aae 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "dbg_gpu_gk20a.h" | 28 | #include "dbg_gpu_gk20a.h" |
29 | #include "regops_gk20a.h" | 29 | #include "regops_gk20a.h" |
30 | #include "hw_therm_gk20a.h" | 30 | #include "hw_therm_gk20a.h" |
31 | #include "hw_gr_gk20a.h" | ||
31 | 32 | ||
32 | struct dbg_gpu_session_ops dbg_gpu_session_ops_gk20a = { | 33 | struct dbg_gpu_session_ops dbg_gpu_session_ops_gk20a = { |
33 | .exec_reg_ops = exec_regops_gk20a, | 34 | .exec_reg_ops = exec_regops_gk20a, |
@@ -359,6 +360,11 @@ static int nvgpu_ioctl_powergate_gk20a(struct dbg_session_gk20a *dbg_s, | |||
359 | static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, | 360 | static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, |
360 | struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *args); | 361 | struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *args); |
361 | 362 | ||
363 | static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm( | ||
364 | struct dbg_session_gk20a *dbg_s, | ||
365 | struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *args); | ||
366 | |||
367 | |||
362 | long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, | 368 | long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, |
363 | unsigned long arg) | 369 | unsigned long arg) |
364 | { | 370 | { |
@@ -418,8 +424,13 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, | |||
418 | (struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *)buf); | 424 | (struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *)buf); |
419 | break; | 425 | break; |
420 | 426 | ||
427 | case NVGPU_DBG_GPU_IOCTL_SUSPEND_RESUME_ALL_SMS: | ||
428 | err = nvgpu_dbg_gpu_ioctl_suspend_resume_sm(dbg_s, | ||
429 | (struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *)buf); | ||
430 | break; | ||
431 | |||
421 | default: | 432 | default: |
422 | dev_dbg(dev_from_gk20a(g), | 433 | gk20a_err(dev_from_gk20a(g), |
423 | "unrecognized dbg gpu ioctl cmd: 0x%x", | 434 | "unrecognized dbg gpu ioctl cmd: 0x%x", |
424 | cmd); | 435 | cmd); |
425 | err = -ENOTTY; | 436 | err = -ENOTTY; |
@@ -693,3 +704,63 @@ static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, | |||
693 | mutex_unlock(&g->dbg_sessions_lock); | 704 | mutex_unlock(&g->dbg_sessions_lock); |
694 | return err; | 705 | return err; |
695 | } | 706 | } |
707 | |||
708 | static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm( | ||
709 | struct dbg_session_gk20a *dbg_s, | ||
710 | struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *args) | ||
711 | { | ||
712 | struct gk20a *g = get_gk20a(dbg_s->pdev); | ||
713 | struct channel_gk20a *ch = dbg_s->ch; | ||
714 | bool ch_is_curr_ctx; | ||
715 | int err = 0, action = args->mode; | ||
716 | |||
717 | mutex_lock(&g->dbg_sessions_lock); | ||
718 | |||
719 | /* Suspend GPU context switching */ | ||
720 | /* Disable channel switching. | ||
721 | * at that point the hardware state can be inspected to | ||
722 | * determine if the context we're interested in is current. | ||
723 | */ | ||
724 | err = gr_gk20a_disable_ctxsw(g); | ||
725 | if (err) { | ||
726 | gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw"); | ||
727 | /* this should probably be ctx-fatal... */ | ||
728 | goto clean_up; | ||
729 | } | ||
730 | |||
731 | /* find out whether the current channel is resident */ | ||
732 | ch_is_curr_ctx = gk20a_is_channel_ctx_resident(ch); | ||
733 | |||
734 | if (ch_is_curr_ctx) { | ||
735 | switch (action) { | ||
736 | case NVGPU_DBG_GPU_SUSPEND_ALL_SMS: | ||
737 | gk20a_suspend_all_sms(g); | ||
738 | break; | ||
739 | |||
740 | case NVGPU_DBG_GPU_RESUME_ALL_SMS: | ||
741 | gk20a_resume_all_sms(g); | ||
742 | break; | ||
743 | } | ||
744 | } else { | ||
745 | switch (action) { | ||
746 | case NVGPU_DBG_GPU_SUSPEND_ALL_SMS: | ||
747 | /* Disable the channel */ | ||
748 | channel_gk20a_disable(ch); | ||
749 | break; | ||
750 | |||
751 | case NVGPU_DBG_GPU_RESUME_ALL_SMS: | ||
752 | /* Enable the channel */ | ||
753 | channel_gk20a_enable(ch); | ||
754 | break; | ||
755 | } | ||
756 | } | ||
757 | |||
758 | /* Resume GPU context switching */ | ||
759 | err = gr_gk20a_enable_ctxsw(g); | ||
760 | if (err) | ||
761 | gk20a_err(dev_from_gk20a(g), "unable to restart ctxsw!\n"); | ||
762 | |||
763 | clean_up: | ||
764 | mutex_unlock(&g->dbg_sessions_lock); | ||
765 | return err; | ||
766 | } | ||