diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-11-30 18:07:08 -0500 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-12-05 10:42:44 -0500 |
commit | cbda0b2b7172bc9f0a3310ed9fe08e9f384b69c0 (patch) | |
tree | f92bc055b414e5002d4430d4a3326f15f05a0435 /drivers | |
parent | 397c6d44ed3ee6cc0c24fce7711bda4f0d6cd9bf (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')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 25 |
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 | ||
4835 | static int gk20a_gr_handle_fecs_error(struct gk20a *g, | 4835 | static 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 | ||
5517 | clean_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() */ |