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 <seemaj@nvidia.com>
Reviewed-on: https://git-master/r/1476108
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: David Martinez Nieto <dmartineznie@nvidia.com>
This commit is contained in:
Seema Khowala
2017-06-20 21:50:36 -07:00
committed by mobile promotions
parent 02d1e7ae97
commit 2eea080584
5 changed files with 64 additions and 14 deletions

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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)
{