diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 734552a1..c0a25e68 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include "semaphore_gk20a.h" | 58 | #include "semaphore_gk20a.h" |
59 | #include "platform_gk20a.h" | 59 | #include "platform_gk20a.h" |
60 | #include "ctxsw_trace_gk20a.h" | 60 | #include "ctxsw_trace_gk20a.h" |
61 | #include "hw_proj_gk20a.h" | ||
61 | 62 | ||
62 | #define BLK_SIZE (256) | 63 | #define BLK_SIZE (256) |
63 | #define NV_PMM_FBP_STRIDE 0x1000 | 64 | #define NV_PMM_FBP_STRIDE 0x1000 |
@@ -3129,6 +3130,7 @@ static void gk20a_remove_gr_support(struct gr_gk20a *gr) | |||
3129 | 3130 | ||
3130 | memset(&gr->compbit_store, 0, sizeof(struct compbit_store_desc)); | 3131 | memset(&gr->compbit_store, 0, sizeof(struct compbit_store_desc)); |
3131 | 3132 | ||
3133 | kfree(gr->sm_error_states); | ||
3132 | kfree(gr->gpc_tpc_count); | 3134 | kfree(gr->gpc_tpc_count); |
3133 | kfree(gr->gpc_zcb_count); | 3135 | kfree(gr->gpc_zcb_count); |
3134 | kfree(gr->gpc_ppc_count); | 3136 | kfree(gr->gpc_ppc_count); |
@@ -4426,6 +4428,19 @@ restore_fe_go_idle: | |||
4426 | if (err) | 4428 | if (err) |
4427 | goto out; | 4429 | goto out; |
4428 | 4430 | ||
4431 | kfree(gr->sm_error_states); | ||
4432 | |||
4433 | /* we need to allocate this after g->ops.gr.init_fs_state() since | ||
4434 | * we initialize gr->no_of_sm in this function | ||
4435 | */ | ||
4436 | gr->sm_error_states = kzalloc( | ||
4437 | sizeof(struct nvgpu_dbg_gpu_sm_error_state_record) | ||
4438 | * gr->no_of_sm, GFP_KERNEL); | ||
4439 | if (!gr->sm_error_states) { | ||
4440 | err = -ENOMEM; | ||
4441 | goto restore_fe_go_idle; | ||
4442 | } | ||
4443 | |||
4429 | out: | 4444 | out: |
4430 | gk20a_dbg_fn("done"); | 4445 | gk20a_dbg_fn("done"); |
4431 | return 0; | 4446 | return 0; |
@@ -5494,6 +5509,32 @@ u32 gk20a_mask_hww_warp_esr(u32 hww_warp_esr) | |||
5494 | return hww_warp_esr; | 5509 | return hww_warp_esr; |
5495 | } | 5510 | } |
5496 | 5511 | ||
5512 | static int gk20a_gr_record_sm_error_state(struct gk20a *g, u32 gpc, u32 tpc) | ||
5513 | { | ||
5514 | int sm_id; | ||
5515 | struct gr_gk20a *gr = &g->gr; | ||
5516 | u32 offset = proj_gpc_stride_v() * gpc + | ||
5517 | proj_tpc_in_gpc_stride_v() * tpc; | ||
5518 | |||
5519 | mutex_lock(&g->dbg_sessions_lock); | ||
5520 | |||
5521 | sm_id = gr_gpc0_tpc0_sm_cfg_sm_id_v(gk20a_readl(g, | ||
5522 | gr_gpc0_tpc0_sm_cfg_r() + offset)); | ||
5523 | |||
5524 | gr->sm_error_states[sm_id].hww_global_esr = gk20a_readl(g, | ||
5525 | gr_gpc0_tpc0_sm_hww_global_esr_r() + offset); | ||
5526 | gr->sm_error_states[sm_id].hww_warp_esr = gk20a_readl(g, | ||
5527 | gr_gpc0_tpc0_sm_hww_warp_esr_r() + offset); | ||
5528 | gr->sm_error_states[sm_id].hww_global_esr_report_mask = gk20a_readl(g, | ||
5529 | gr_gpcs_tpcs_sm_hww_global_esr_report_mask_r() + offset); | ||
5530 | gr->sm_error_states[sm_id].hww_warp_esr_report_mask = gk20a_readl(g, | ||
5531 | gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_r() + offset); | ||
5532 | |||
5533 | mutex_unlock(&g->dbg_sessions_lock); | ||
5534 | |||
5535 | return 0; | ||
5536 | } | ||
5537 | |||
5497 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | 5538 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, |
5498 | bool *post_event, struct channel_gk20a *fault_ch) | 5539 | bool *post_event, struct channel_gk20a *fault_ch) |
5499 | { | 5540 | { |
@@ -5554,6 +5595,9 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
5554 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 5595 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5555 | "sm hww global %08x warp %08x", global_esr, warp_esr); | 5596 | "sm hww global %08x warp %08x", global_esr, warp_esr); |
5556 | 5597 | ||
5598 | gr_gk20a_elpg_protected_call(g, | ||
5599 | g->ops.gr.record_sm_error_state(g, gpc, tpc)); | ||
5600 | |||
5557 | if (g->ops.gr.pre_process_sm_exception) { | 5601 | if (g->ops.gr.pre_process_sm_exception) { |
5558 | ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, | 5602 | ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, |
5559 | global_esr, warp_esr, | 5603 | global_esr, warp_esr, |
@@ -8370,4 +8414,5 @@ void gk20a_init_gr_ops(struct gpu_ops *gops) | |||
8370 | gops->gr.get_lrf_tex_ltc_dram_override = NULL; | 8414 | gops->gr.get_lrf_tex_ltc_dram_override = NULL; |
8371 | gops->gr.update_smpc_ctxsw_mode = gr_gk20a_update_smpc_ctxsw_mode; | 8415 | gops->gr.update_smpc_ctxsw_mode = gr_gk20a_update_smpc_ctxsw_mode; |
8372 | gops->gr.update_hwpm_ctxsw_mode = gr_gk20a_update_hwpm_ctxsw_mode; | 8416 | gops->gr.update_hwpm_ctxsw_mode = gr_gk20a_update_hwpm_ctxsw_mode; |
8417 | gops->gr.record_sm_error_state = gk20a_gr_record_sm_error_state; | ||
8373 | } | 8418 | } |