From f6eb64fcb56bebb61894272f26498bc0cc92169e Mon Sep 17 00:00:00 2001 From: Ashutosh Jain Date: Wed, 9 Dec 2015 21:48:39 +0530 Subject: gpu: nvgpu: Add 3 functions to regops interface. This change adds the following IOCTLS: - NVGPU_GPU_IOCTL_RESUME_FROM_PAUSE - NVGPU_GPU_IOCTL_TRIGGER_SUSPEND - NVGPU_GPU_IOCTL_CLEAR_SM_ERRORS Bug 1619430 Change-Id: Iac37d515a753d8b799e631224eae2fa168b43e2c Signed-off-by: ashutosh jain Reviewed-on: http://git-master/r/921378 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 85 ++++++++++++++++++++++++++++++++++- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 2 +- drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 2 + drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h | 4 ++ 4 files changed, 91 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a') diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index e17e239b..3c668013 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c @@ -388,6 +388,26 @@ static int nvgpu_gpu_ioctl_set_debug_mode( return err; } +static int nvgpu_gpu_ioctl_trigger_suspend(struct gk20a *g) +{ + int err = 0; + u32 dbgr_control0; + + mutex_lock(&g->dbg_sessions_lock); + /* assert stop trigger. uniformity assumption: all SMs will have + * the same state in dbg_control0. */ + dbgr_control0 = + gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r()); + dbgr_control0 |= gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(); + + /* broadcast write */ + gk20a_writel(g, + gr_gpcs_tpcs_sm_dbgr_control0_r(), dbgr_control0); + + mutex_unlock(&g->dbg_sessions_lock); + return err; +} + static int nvgpu_gpu_ioctl_wait_for_pause(struct gk20a *g, struct nvgpu_gpu_wait_pause_args *args) { @@ -441,6 +461,57 @@ end: return err; } +static int nvgpu_gpu_ioctl_resume_from_pause(struct gk20a *g) +{ + int err = 0; + + mutex_lock(&g->dbg_sessions_lock); + + /* Clear the pause mask to tell the GPU we want to resume everyone */ + gk20a_writel(g, + gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_r(), 0); + + /* explicitly re-enable forwarding of SM interrupts upon any resume */ + gk20a_writel(g, gr_gpcs_tpcs_tpccs_tpc_exception_en_r(), + gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f()); + + /* Now resume all sms, write a 0 to the stop trigger + * then a 1 to the run trigger */ + gk20a_resume_all_sms(g); + + mutex_unlock(&g->dbg_sessions_lock); + return err; +} + +static int nvgpu_gpu_ioctl_clear_sm_errors(struct gk20a *g) +{ + int ret = 0; + u32 gpc_offset, tpc_offset, gpc, tpc; + struct gr_gk20a *gr = &g->gr; + u32 global_esr; + + for (gpc = 0; gpc < gr->gpc_count; gpc++) { + + gpc_offset = proj_gpc_stride_v() * gpc; + + /* check if any tpc has an exception */ + for (tpc = 0; tpc < gr->tpc_count; tpc++) { + + tpc_offset = proj_tpc_in_gpc_stride_v() * tpc; + + global_esr = gk20a_readl(g, + gr_gpc0_tpc0_sm_hww_global_esr_r() + + gpc_offset + tpc_offset); + + /* clear the hwws, also causes tpc and gpc + * exceptions to be cleared */ + gk20a_gr_clear_sm_hww(g, gpc, tpc, global_esr); + } + } + + return ret; +} + static int nvgpu_gpu_ioctl_has_any_exception( struct gk20a *g, struct nvgpu_gpu_tpc_exception_en_status_args *args) @@ -694,11 +765,23 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg nvgpu_gpu_ioctl_set_debug_mode(g, (struct nvgpu_gpu_sm_debug_mode_args *)buf)); break; + case NVGPU_GPU_IOCTL_TRIGGER_SUSPEND: + err = nvgpu_gpu_ioctl_trigger_suspend(g); + break; + case NVGPU_GPU_IOCTL_WAIT_FOR_PAUSE: - err = nvgpu_gpu_ioctl_wait_for_pause(g, + err = nvgpu_gpu_ioctl_wait_for_pause(g, (struct nvgpu_gpu_wait_pause_args *)buf); break; + case NVGPU_GPU_IOCTL_RESUME_FROM_PAUSE: + err = nvgpu_gpu_ioctl_resume_from_pause(g); + break; + + case NVGPU_GPU_IOCTL_CLEAR_SM_ERRORS: + err = nvgpu_gpu_ioctl_clear_sm_errors(g); + break; + case NVGPU_GPU_IOCTL_GET_TPC_EXCEPTION_EN_STATUS: err = nvgpu_gpu_ioctl_has_any_exception(g, (struct nvgpu_gpu_tpc_exception_en_status_args *)buf); diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index ea6bca2f..30beb962 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -5159,7 +5159,7 @@ bool gk20a_gr_sm_debugger_attached(struct gk20a *g) return false; } -static void gk20a_gr_clear_sm_hww(struct gk20a *g, +void gk20a_gr_clear_sm_hww(struct gk20a *g, u32 gpc, u32 tpc, u32 global_esr) { u32 offset = proj_gpc_stride_v() * gpc + diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index 55c5ceb7..51b87ac8 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h @@ -431,6 +431,8 @@ void gr_gk20a_init_blcg_mode(struct gk20a *g, u32 mode, u32 engine); /* sm */ bool gk20a_gr_sm_debugger_attached(struct gk20a *g); +void gk20a_gr_clear_sm_hww(struct gk20a *g, + u32 gpc, u32 tpc, u32 global_esr); #define gr_gk20a_elpg_protected_call(g, func) \ ({ \ diff --git a/drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h index 726d0ad3..6a155ccc 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h @@ -3110,6 +3110,10 @@ static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_r(void) { return 0x00504634; } +static inline u32 gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00419e24; +} static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_stop_on_any_warp_disable_v(void) { return 0x00000000; -- cgit v1.2.2