From 2eea080584b36747d7f8a7d5120d60be25d12242 Mon Sep 17 00:00:00 2001 From: Seema Khowala Date: Tue, 20 Jun 2017 21:50:36 -0700 Subject: gpu: nvgpu: Support multiple SM for t19x -Add sm input param for handle_sm_exception and pre_process_sm_exception for gr ops/functions. -Add functions to calculate gpc and tpc reg offsets. -Add function to find SMs which raised SM exception. JIRA GPUT19X-75 Change-Id: I257e7342ddabadb1556c9551c50a54d34b0f9d1e Signed-off-by: Seema Khowala Reviewed-on: https://git-master/r/1476108 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom Reviewed-by: David Martinez Nieto --- drivers/gpu/nvgpu/gk20a/gk20a.h | 13 ++++++---- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 50 ++++++++++++++++++++++++++++++++++---- drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 6 ++++- drivers/gpu/nvgpu/gm20b/gr_gm20b.c | 1 + drivers/gpu/nvgpu/gp10b/gr_gp10b.c | 8 +++--- 5 files changed, 64 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 8f291f92..e0434360 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -285,12 +285,15 @@ struct gpu_ops { struct channel_gk20a *ch, struct gr_gk20a_isr_data *isr_data); int (*pre_process_sm_exception)(struct gk20a *g, - u32 gpc, u32 tpc, u32 global_esr, u32 warp_esr, - bool sm_debugger_attached, - struct channel_gk20a *fault_ch, - bool *early_exit, bool *ignore_debugger); + u32 gpc, u32 tpc, u32 sm, u32 global_esr, u32 warp_esr, + bool sm_debugger_attached, + struct channel_gk20a *fault_ch, + bool *early_exit, bool *ignore_debugger); u32 (*mask_hww_warp_esr)(u32 hww_warp_esr); - int (*handle_sm_exception)(struct gk20a *g, u32 gpc, u32 tpc, + void (*get_esr_sm_sel)(struct gk20a *g, u32 gpc, u32 tpc, + u32 *esr_sm_sel); + int (*handle_sm_exception)(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, bool *post_event, struct channel_gk20a *fault_ch, u32 *hww_global_esr); int (*handle_gcc_exception)(struct gk20a *g, u32 gpc, u32 tpc, diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 2afa79f1..2ee2048c 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -820,6 +820,23 @@ clean_up_mem: return ret; } +u32 gk20a_gr_gpc_offset(struct gk20a *g, u32 gpc) +{ + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 gpc_offset = gpc_stride * gpc; + + return gpc_offset; +} + +u32 gk20a_gr_tpc_offset(struct gk20a *g, u32 tpc) +{ + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, + GPU_LIT_TPC_IN_GPC_STRIDE); + u32 tpc_offset = tpc_in_gpc_stride * tpc; + + return tpc_offset; +} + static int gr_gk20a_commit_global_cb_manager(struct gk20a *g, struct channel_gk20a *c, bool patch) { @@ -6163,7 +6180,7 @@ fail: return err; } -int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, +int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, bool *post_event, struct channel_gk20a *fault_ch, u32 *hww_global_esr) { @@ -6206,7 +6223,7 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, *hww_global_esr = global_esr; if (g->ops.gr.pre_process_sm_exception) { - ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, + ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, sm, global_esr, warp_esr, sm_debugger_attached, fault_ch, @@ -6290,6 +6307,12 @@ int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, return ret; } +void gk20a_gr_get_esr_sm_sel(struct gk20a *g, u32 gpc, u32 tpc, + u32 *esr_sm_sel) +{ + *esr_sm_sel = 1; +} + static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, bool *post_event, struct channel_gk20a *fault_ch, u32 *hww_global_esr) @@ -6300,17 +6323,33 @@ static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 offset = gpc_stride * gpc + tpc_in_gpc_stride * tpc; u32 tpc_exception = gk20a_readl(g, gr_gpc0_tpc0_tpccs_tpc_exception_r() + offset); + u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, ""); /* check if an sm exeption is pending */ if (gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(tpc_exception) == gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v()) { + u32 esr_sm_sel, sm; + gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "GPC%d TPC%d: SM exception pending", gpc, tpc); - ret = g->ops.gr.handle_sm_exception(g, gpc, tpc, - post_event, fault_ch, - hww_global_esr); + g->ops.gr.get_esr_sm_sel(g, gpc, tpc, &esr_sm_sel); + + for (sm = 0; sm < sm_per_tpc; sm++) { + + if (!(esr_sm_sel & (1 << sm))) + continue; + + gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d TPC%d: SM%d exception pending", + gpc, tpc, sm); + + ret = g->ops.gr.handle_sm_exception(g, + gpc, tpc, sm, post_event, fault_ch, + hww_global_esr); + } + } /* check if a tex exeption is pending */ @@ -9621,4 +9660,5 @@ void gk20a_init_gr_ops(struct gpu_ops *gops) gops->gr.resume_from_pause = gr_gk20a_resume_from_pause; gops->gr.clear_sm_errors = gr_gk20a_clear_sm_errors; gops->gr.tpc_enabled_exceptions = gr_gk20a_tpc_enabled_exceptions; + gops->gr.get_esr_sm_sel = gk20a_gr_get_esr_sm_sel; } diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index de80c5e3..745848ab 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h @@ -636,7 +636,7 @@ int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); int gr_gk20a_wait_idle(struct gk20a *g, unsigned long duration_ms, u32 expect_delay); -int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, +int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, bool *post_event, struct channel_gk20a *fault_ch, u32 *hww_global_esr); int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, @@ -730,6 +730,10 @@ void gr_gk20a_write_zcull_ptr(struct gk20a *g, void gr_gk20a_write_pm_ptr(struct gk20a *g, struct nvgpu_mem *mem, u64 gpu_va); +u32 gk20a_gr_gpc_offset(struct gk20a *g, u32 gpc); +u32 gk20a_gr_tpc_offset(struct gk20a *g, u32 tpc); +void gk20a_gr_get_esr_sm_sel(struct gk20a *g, u32 gpc, u32 tpc, + u32 *esr_sm_sel); static inline const char *gr_gk20a_graphics_preempt_mode_name(u32 graphics_preempt_mode) { diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index b7fb1ac5..c84d2109 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c @@ -1628,4 +1628,5 @@ void gm20b_init_gr(struct gpu_ops *gops) gops->gr.resume_from_pause = gr_gk20a_resume_from_pause; gops->gr.clear_sm_errors = gr_gk20a_clear_sm_errors; gops->gr.tpc_enabled_exceptions = gr_gk20a_tpc_enabled_exceptions; + gops->gr.get_esr_sm_sel = gk20a_gr_get_esr_sm_sel; } diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c index f27e2605..64466936 100644 --- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c @@ -118,7 +118,8 @@ static void gr_gp10b_sm_lrf_ecc_overcount_war(int single_err, *count_to_adjust = 0; } -static int gr_gp10b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, +static int gr_gp10b_handle_sm_exception(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, bool *post_event, struct channel_gk20a *fault_ch, u32 *hww_global_esr) { @@ -130,7 +131,8 @@ static int gr_gp10b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 lrf_single_count_delta, lrf_double_count_delta; u32 shm_ecc_status; - gr_gk20a_handle_sm_exception(g, gpc, tpc, post_event, fault_ch, hww_global_esr); + gr_gk20a_handle_sm_exception(g, + gpc, tpc, sm, post_event, fault_ch, hww_global_esr); /* Check for LRF ECC errors. */ lrf_ecc_status = gk20a_readl(g, @@ -1764,7 +1766,7 @@ static int gr_gp10b_clear_cilp_preempt_pending(struct gk20a *g, * On Pascal, if we are in CILP preemtion mode, preempt the channel and handle errors with special processing */ static int gr_gp10b_pre_process_sm_exception(struct gk20a *g, - u32 gpc, u32 tpc, u32 global_esr, u32 warp_esr, + u32 gpc, u32 tpc, u32 sm, u32 global_esr, u32 warp_esr, bool sm_debugger_attached, struct channel_gk20a *fault_ch, bool *early_exit, bool *ignore_debugger) { -- cgit v1.2.2