summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2015-11-30 18:07:08 -0500
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-12-05 10:42:44 -0500
commitcbda0b2b7172bc9f0a3310ed9fe08e9f384b69c0 (patch)
treef92bc055b414e5002d4430d4a3326f15f05a0435 /drivers/gpu/nvgpu/gk20a/gr_gk20a.c
parent397c6d44ed3ee6cc0c24fce7711bda4f0d6cd9bf (diff)
gpu: nvgpu: Handle interrupt even if no channel
If we could not find the channel for GR interrupt we skipped resetting it. Change the logic to do the reset, and find the channel via FIFO engine status. Bug 1706962 Change-Id: I8a0d283b36d88ea1cec541dbf90db7929104ad7c Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/839465
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index ef24e078..9eea0a0c 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -4832,17 +4832,16 @@ static int gk20a_gr_handle_illegal_class(struct gk20a *g,
4832 return -EINVAL; 4832 return -EINVAL;
4833} 4833}
4834 4834
4835static int gk20a_gr_handle_fecs_error(struct gk20a *g, 4835static int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch,
4836 struct gr_isr_data *isr_data) 4836 struct gr_isr_data *isr_data)
4837{ 4837{
4838 struct fifo_gk20a *f = &g->fifo;
4839 struct channel_gk20a *ch = &f->channel[isr_data->chid];
4840 u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r()); 4838 u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r());
4839
4841 gk20a_dbg_fn(""); 4840 gk20a_dbg_fn("");
4842 4841
4843 gk20a_err(dev_from_gk20a(g), 4842 gk20a_err(dev_from_gk20a(g),
4844 "unhandled fecs error interrupt 0x%08x for channel %u", 4843 "unhandled fecs error interrupt 0x%08x for channel %u",
4845 gr_fecs_intr, ch->hw_chid); 4844 gr_fecs_intr, isr_data->chid);
4846 4845
4847 if (gr_fecs_intr & gr_fecs_host_int_status_umimp_firmware_method_f(1)) { 4846 if (gr_fecs_intr & gr_fecs_host_int_status_umimp_firmware_method_f(1)) {
4848 gk20a_err(dev_from_gk20a(g), 4847 gk20a_err(dev_from_gk20a(g),
@@ -5360,12 +5359,10 @@ int gk20a_gr_isr(struct gk20a *g)
5360 isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table); 5359 isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table);
5361 5360
5362 ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); 5361 ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid);
5363 if (!ch) { 5362 if (ch)
5364 gk20a_err(dev_from_gk20a(g), "invalid channel ctx 0x%08x", 5363 isr_data.chid = ch->hw_chid;
5365 isr_data.curr_ctx); 5364 else
5366 goto clean_up; 5365 isr_data.chid = 0xffffffff;
5367 }
5368 isr_data.chid = ch->hw_chid;
5369 5366
5370 gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, 5367 gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg,
5371 "channel %d: addr 0x%08x, " 5368 "channel %d: addr 0x%08x, "
@@ -5422,7 +5419,7 @@ int gk20a_gr_isr(struct gk20a *g)
5422 } 5419 }
5423 5420
5424 if (gr_intr & gr_intr_fecs_error_pending_f()) { 5421 if (gr_intr & gr_intr_fecs_error_pending_f()) {
5425 need_reset |= gk20a_gr_handle_fecs_error(g, &isr_data); 5422 need_reset |= gk20a_gr_handle_fecs_error(g, ch, &isr_data);
5426 gk20a_writel(g, gr_intr_r(), 5423 gk20a_writel(g, gr_intr_r(),
5427 gr_intr_fecs_error_reset_f()); 5424 gr_intr_fecs_error_reset_f());
5428 gr_intr &= ~gr_intr_fecs_error_pending_f(); 5425 gr_intr &= ~gr_intr_fecs_error_pending_f();
@@ -5509,12 +5506,14 @@ int gk20a_gr_isr(struct gk20a *g)
5509 if (tsgid != NVGPU_INVALID_TSG_ID) 5506 if (tsgid != NVGPU_INVALID_TSG_ID)
5510 gk20a_fifo_recover(g, BIT(ENGINE_GR_GK20A), 5507 gk20a_fifo_recover(g, BIT(ENGINE_GR_GK20A),
5511 tsgid, true, true, true); 5508 tsgid, true, true, true);
5512 else 5509 else if (ch)
5513 gk20a_fifo_recover(g, BIT(ENGINE_GR_GK20A), 5510 gk20a_fifo_recover(g, BIT(ENGINE_GR_GK20A),
5514 ch->hw_chid, false, true, true); 5511 ch->hw_chid, false, true, true);
5512 else
5513 gk20a_fifo_recover(g, BIT(ENGINE_GR_GK20A),
5514 0, false, false, true);
5515 } 5515 }
5516 5516
5517clean_up:
5518 if (gr_intr && !ch) { 5517 if (gr_intr && !ch) {
5519 /* Clear interrupts for unused channel. This is 5518 /* Clear interrupts for unused channel. This is
5520 probably an interrupt during gk20a_free_channel() */ 5519 probably an interrupt during gk20a_free_channel() */