diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 78 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 3 |
3 files changed, 50 insertions, 34 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 7eb98a2c..6f735af9 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -264,7 +264,8 @@ struct gpu_ops { | |||
264 | bool *early_exit, bool *ignore_debugger); | 264 | bool *early_exit, bool *ignore_debugger); |
265 | u32 (*mask_hww_warp_esr)(u32 hww_warp_esr); | 265 | u32 (*mask_hww_warp_esr)(u32 hww_warp_esr); |
266 | int (*handle_sm_exception)(struct gk20a *g, u32 gpc, u32 tpc, | 266 | int (*handle_sm_exception)(struct gk20a *g, u32 gpc, u32 tpc, |
267 | bool *post_event, struct channel_gk20a *fault_ch); | 267 | bool *post_event, struct channel_gk20a *fault_ch, |
268 | u32 *hww_global_esr); | ||
268 | int (*handle_tex_exception)(struct gk20a *g, u32 gpc, u32 tpc, | 269 | int (*handle_tex_exception)(struct gk20a *g, u32 gpc, u32 tpc, |
269 | bool *post_event); | 270 | bool *post_event); |
270 | void (*create_gr_sysfs)(struct device *dev); | 271 | void (*create_gr_sysfs)(struct device *dev); |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 979f69ba..271c384a 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -5869,7 +5869,8 @@ fail: | |||
5869 | } | 5869 | } |
5870 | 5870 | ||
5871 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | 5871 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, |
5872 | bool *post_event, struct channel_gk20a *fault_ch) | 5872 | bool *post_event, struct channel_gk20a *fault_ch, |
5873 | u32 *hww_global_esr) | ||
5873 | { | 5874 | { |
5874 | int ret = 0; | 5875 | int ret = 0; |
5875 | bool do_warp_sync = false, early_exit = false, ignore_debugger = false; | 5876 | bool do_warp_sync = false, early_exit = false, ignore_debugger = false; |
@@ -5901,35 +5902,12 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
5901 | return -EFAULT; | 5902 | return -EFAULT; |
5902 | } | 5903 | } |
5903 | 5904 | ||
5904 | if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f()) { | ||
5905 | if (gk20a_is_channel_marked_as_tsg(fault_ch)) { | ||
5906 | struct tsg_gk20a *tsg = &g->fifo.tsg[fault_ch->tsgid]; | ||
5907 | |||
5908 | gk20a_tsg_event_id_post_event(tsg, | ||
5909 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT); | ||
5910 | } else { | ||
5911 | gk20a_channel_event_id_post_event(fault_ch, | ||
5912 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT); | ||
5913 | } | ||
5914 | } | ||
5915 | |||
5916 | if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f()) { | ||
5917 | if (gk20a_is_channel_marked_as_tsg(fault_ch)) { | ||
5918 | struct tsg_gk20a *tsg = &g->fifo.tsg[fault_ch->tsgid]; | ||
5919 | |||
5920 | gk20a_tsg_event_id_post_event(tsg, | ||
5921 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE); | ||
5922 | } else { | ||
5923 | gk20a_channel_event_id_post_event(fault_ch, | ||
5924 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE); | ||
5925 | } | ||
5926 | } | ||
5927 | |||
5928 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 5905 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5929 | "sm hww global %08x warp %08x", global_esr, warp_esr); | 5906 | "sm hww global %08x warp %08x", global_esr, warp_esr); |
5930 | 5907 | ||
5931 | gr_gk20a_elpg_protected_call(g, | 5908 | gr_gk20a_elpg_protected_call(g, |
5932 | g->ops.gr.record_sm_error_state(g, gpc, tpc)); | 5909 | g->ops.gr.record_sm_error_state(g, gpc, tpc)); |
5910 | *hww_global_esr = global_esr; | ||
5933 | 5911 | ||
5934 | if (g->ops.gr.pre_process_sm_exception) { | 5912 | if (g->ops.gr.pre_process_sm_exception) { |
5935 | ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, | 5913 | ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, |
@@ -5946,7 +5924,7 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
5946 | 5924 | ||
5947 | if (early_exit) { | 5925 | if (early_exit) { |
5948 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 5926 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5949 | "returning early, skipping event posting"); | 5927 | "returning early"); |
5950 | return ret; | 5928 | return ret; |
5951 | } | 5929 | } |
5952 | 5930 | ||
@@ -6009,7 +5987,8 @@ int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
6009 | } | 5987 | } |
6010 | 5988 | ||
6011 | static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, | 5989 | static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, |
6012 | bool *post_event, struct channel_gk20a *fault_ch) | 5990 | bool *post_event, struct channel_gk20a *fault_ch, |
5991 | u32 *hww_global_esr) | ||
6013 | { | 5992 | { |
6014 | int ret = 0; | 5993 | int ret = 0; |
6015 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | 5994 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); |
@@ -6026,7 +6005,8 @@ static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
6026 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 6005 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
6027 | "GPC%d TPC%d: SM exception pending", gpc, tpc); | 6006 | "GPC%d TPC%d: SM exception pending", gpc, tpc); |
6028 | ret = g->ops.gr.handle_sm_exception(g, gpc, tpc, | 6007 | ret = g->ops.gr.handle_sm_exception(g, gpc, tpc, |
6029 | post_event, fault_ch); | 6008 | post_event, fault_ch, |
6009 | hww_global_esr); | ||
6030 | } | 6010 | } |
6031 | 6011 | ||
6032 | /* check if a tex exeption is pending */ | 6012 | /* check if a tex exeption is pending */ |
@@ -6041,7 +6021,7 @@ static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
6041 | } | 6021 | } |
6042 | 6022 | ||
6043 | static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | 6023 | static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, |
6044 | struct channel_gk20a *fault_ch) | 6024 | struct channel_gk20a *fault_ch, u32 *hww_global_esr) |
6045 | { | 6025 | { |
6046 | int ret = 0; | 6026 | int ret = 0; |
6047 | u32 gpc_offset, tpc_offset, gpc, tpc; | 6027 | u32 gpc_offset, tpc_offset, gpc, tpc; |
@@ -6081,7 +6061,7 @@ static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | |||
6081 | gpc_offset + tpc_offset); | 6061 | gpc_offset + tpc_offset); |
6082 | 6062 | ||
6083 | ret = gk20a_gr_handle_tpc_exception(g, gpc, tpc, | 6063 | ret = gk20a_gr_handle_tpc_exception(g, gpc, tpc, |
6084 | post_event, fault_ch); | 6064 | post_event, fault_ch, hww_global_esr); |
6085 | 6065 | ||
6086 | /* clear the hwws, also causes tpc and gpc | 6066 | /* clear the hwws, also causes tpc and gpc |
6087 | * exceptions to be cleared */ | 6067 | * exceptions to be cleared */ |
@@ -6092,6 +6072,35 @@ static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | |||
6092 | return ret; | 6072 | return ret; |
6093 | } | 6073 | } |
6094 | 6074 | ||
6075 | static int gk20a_gr_post_bpt_events(struct gk20a *g, struct channel_gk20a *ch, | ||
6076 | u32 global_esr) | ||
6077 | { | ||
6078 | if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f()) { | ||
6079 | if (gk20a_is_channel_marked_as_tsg(ch)) { | ||
6080 | struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; | ||
6081 | |||
6082 | gk20a_tsg_event_id_post_event(tsg, | ||
6083 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT); | ||
6084 | } else { | ||
6085 | gk20a_channel_event_id_post_event(ch, | ||
6086 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT); | ||
6087 | } | ||
6088 | } | ||
6089 | if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f()) { | ||
6090 | if (gk20a_is_channel_marked_as_tsg(ch)) { | ||
6091 | struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; | ||
6092 | |||
6093 | gk20a_tsg_event_id_post_event(tsg, | ||
6094 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE); | ||
6095 | } else { | ||
6096 | gk20a_channel_event_id_post_event(ch, | ||
6097 | NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE); | ||
6098 | } | ||
6099 | } | ||
6100 | |||
6101 | return 0; | ||
6102 | } | ||
6103 | |||
6095 | int gk20a_gr_isr(struct gk20a *g) | 6104 | int gk20a_gr_isr(struct gk20a *g) |
6096 | { | 6105 | { |
6097 | struct device *dev = dev_from_gk20a(g); | 6106 | struct device *dev = dev_from_gk20a(g); |
@@ -6101,8 +6110,10 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6101 | int need_reset = 0; | 6110 | int need_reset = 0; |
6102 | u32 gr_intr = gk20a_readl(g, gr_intr_r()); | 6111 | u32 gr_intr = gk20a_readl(g, gr_intr_r()); |
6103 | struct channel_gk20a *ch = NULL; | 6112 | struct channel_gk20a *ch = NULL; |
6113 | struct channel_gk20a *fault_ch = NULL; | ||
6104 | int tsgid = NVGPU_INVALID_TSG_ID; | 6114 | int tsgid = NVGPU_INVALID_TSG_ID; |
6105 | u32 gr_engine_id; | 6115 | u32 gr_engine_id; |
6116 | u32 global_esr = 0; | ||
6106 | 6117 | ||
6107 | gk20a_dbg_fn(""); | 6118 | gk20a_dbg_fn(""); |
6108 | gk20a_dbg(gpu_dbg_intr, "pgraph intr %08x", gr_intr); | 6119 | gk20a_dbg(gpu_dbg_intr, "pgraph intr %08x", gr_intr); |
@@ -6235,7 +6246,6 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6235 | 6246 | ||
6236 | /* check if a gpc exception has occurred */ | 6247 | /* check if a gpc exception has occurred */ |
6237 | if (exception & gr_exception_gpc_m() && need_reset == 0) { | 6248 | if (exception & gr_exception_gpc_m() && need_reset == 0) { |
6238 | struct channel_gk20a *fault_ch; | ||
6239 | bool post_event = false; | 6249 | bool post_event = false; |
6240 | 6250 | ||
6241 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "GPC exception pending"); | 6251 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "GPC exception pending"); |
@@ -6246,7 +6256,7 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6246 | 6256 | ||
6247 | /* check if any gpc has an exception */ | 6257 | /* check if any gpc has an exception */ |
6248 | need_reset |= gk20a_gr_handle_gpc_exception(g, | 6258 | need_reset |= gk20a_gr_handle_gpc_exception(g, |
6249 | &post_event, fault_ch); | 6259 | &post_event, fault_ch, &global_esr); |
6250 | 6260 | ||
6251 | /* signal clients waiting on an event */ | 6261 | /* signal clients waiting on an event */ |
6252 | if (gk20a_gr_sm_debugger_attached(g) && post_event && fault_ch) { | 6262 | if (gk20a_gr_sm_debugger_attached(g) && post_event && fault_ch) { |
@@ -6310,6 +6320,10 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6310 | gk20a_err(dev_from_gk20a(g), | 6320 | gk20a_err(dev_from_gk20a(g), |
6311 | "unhandled gr interrupt 0x%08x", gr_intr); | 6321 | "unhandled gr interrupt 0x%08x", gr_intr); |
6312 | 6322 | ||
6323 | /* Posting of BPT events should be the last thing in this function */ | ||
6324 | if (global_esr && fault_ch) | ||
6325 | gk20a_gr_post_bpt_events(g, fault_ch, global_esr); | ||
6326 | |||
6313 | if (ch) | 6327 | if (ch) |
6314 | gk20a_channel_put(ch); | 6328 | gk20a_channel_put(ch); |
6315 | 6329 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index e1335b89..2a351bc3 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h | |||
@@ -584,7 +584,8 @@ void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); | |||
584 | int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, | 584 | int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, |
585 | u32 expect_delay); | 585 | u32 expect_delay); |
586 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | 586 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, |
587 | bool *post_event, struct channel_gk20a *fault_ch); | 587 | bool *post_event, struct channel_gk20a *fault_ch, |
588 | u32 *hww_global_esr); | ||
588 | int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, | 589 | int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, |
589 | bool *post_event); | 590 | bool *post_event); |
590 | int gr_gk20a_init_ctx_state(struct gk20a *g); | 591 | int gr_gk20a_init_ctx_state(struct gk20a *g); |