diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 3890077fb..69ad1c92d 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -989,7 +989,7 @@ int gk20a_gr_isr(struct gk20a *g) { struct nvgpu_gr_isr_data isr_data; bool need_reset = false; - u32 gr_intr = gk20a_readl(g, gr_intr_r()); + u32 gr_intr = g->ops.gr.intr.read_pending_interrupts(g); struct channel_gk20a *ch = NULL; struct channel_gk20a *fault_ch = NULL; u32 tsgid = NVGPU_INVALID_TSG_ID; @@ -998,6 +998,7 @@ int gk20a_gr_isr(struct gk20a *g) u32 global_esr = 0; u32 chid; struct nvgpu_gr_config *gr_config = g->gr.config; + u32 clear_intr = gr_intr; nvgpu_log_fn(g, " "); nvgpu_log(g, gpu_dbg_intr, "pgraph intr 0x%08x", gr_intr); @@ -1042,16 +1043,12 @@ int gk20a_gr_isr(struct gk20a *g) if ((gr_intr & gr_intr_notify_pending_f()) != 0U) { g->ops.gr.intr.handle_notify_pending(g, &isr_data); - gk20a_writel(g, gr_intr_r(), - gr_intr_notify_reset_f()); - gr_intr &= ~gr_intr_notify_pending_f(); + clear_intr &= ~gr_intr_notify_pending_f(); } if ((gr_intr & gr_intr_semaphore_pending_f()) != 0U) { g->ops.gr.intr.handle_semaphore_pending(g, &isr_data); - gk20a_writel(g, gr_intr_r(), - gr_intr_semaphore_reset_f()); - gr_intr &= ~gr_intr_semaphore_pending_f(); + clear_intr &= ~gr_intr_semaphore_pending_f(); } if ((gr_intr & gr_intr_semaphore_timeout_pending_f()) != 0U) { @@ -1059,9 +1056,7 @@ int gk20a_gr_isr(struct gk20a *g) &isr_data) != 0) { need_reset = true; } - gk20a_writel(g, gr_intr_r(), - gr_intr_semaphore_reset_f()); - gr_intr &= ~gr_intr_semaphore_pending_f(); + clear_intr &= ~gr_intr_semaphore_pending_f(); } if ((gr_intr & gr_intr_illegal_notify_pending_f()) != 0U) { @@ -1069,45 +1064,35 @@ int gk20a_gr_isr(struct gk20a *g) &isr_data) != 0) { need_reset = true; } - gk20a_writel(g, gr_intr_r(), - gr_intr_illegal_notify_reset_f()); - gr_intr &= ~gr_intr_illegal_notify_pending_f(); + clear_intr &= ~gr_intr_illegal_notify_pending_f(); } if ((gr_intr & gr_intr_illegal_method_pending_f()) != 0U) { if (gk20a_gr_handle_illegal_method(g, &isr_data) != 0) { need_reset = true; } - gk20a_writel(g, gr_intr_r(), - gr_intr_illegal_method_reset_f()); - gr_intr &= ~gr_intr_illegal_method_pending_f(); + clear_intr &= ~gr_intr_illegal_method_pending_f(); } if ((gr_intr & gr_intr_illegal_class_pending_f()) != 0U) { if (gk20a_gr_handle_illegal_class(g, &isr_data) != 0) { need_reset = true; } - gk20a_writel(g, gr_intr_r(), - gr_intr_illegal_class_reset_f()); - gr_intr &= ~gr_intr_illegal_class_pending_f(); + clear_intr &= ~gr_intr_illegal_class_pending_f(); } if ((gr_intr & gr_intr_fecs_error_pending_f()) != 0U) { if (g->ops.gr.handle_fecs_error(g, ch, &isr_data) != 0) { need_reset = true; } - gk20a_writel(g, gr_intr_r(), - gr_intr_fecs_error_reset_f()); - gr_intr &= ~gr_intr_fecs_error_pending_f(); + clear_intr &= ~gr_intr_fecs_error_pending_f(); } if ((gr_intr & gr_intr_class_error_pending_f()) != 0U) { if (gk20a_gr_handle_class_error(g, &isr_data) != 0) { need_reset = true; } - gk20a_writel(g, gr_intr_r(), - gr_intr_class_error_reset_f()); - gr_intr &= ~gr_intr_class_error_pending_f(); + clear_intr &= ~gr_intr_class_error_pending_f(); } /* this one happens if someone tries to hit a non-whitelisted @@ -1118,9 +1103,7 @@ int gk20a_gr_isr(struct gk20a *g) } nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, "firmware method intr pending\n"); - gk20a_writel(g, gr_intr_r(), - gr_intr_firmware_method_reset_f()); - gr_intr &= ~gr_intr_firmware_method_pending_f(); + clear_intr &= ~gr_intr_firmware_method_pending_f(); } if ((gr_intr & gr_intr_exception_pending_f()) != 0U) { @@ -1155,9 +1138,7 @@ int gk20a_gr_isr(struct gk20a *g) } #endif } - - gk20a_writel(g, gr_intr_r(), gr_intr_exception_reset_f()); - gr_intr &= ~gr_intr_exception_pending_f(); + clear_intr &= ~gr_intr_exception_pending_f(); if (need_reset) { nvgpu_err(g, "set gr exception notifier"); @@ -1182,8 +1163,7 @@ int gk20a_gr_isr(struct gk20a *g) } } - if (gr_intr != 0U) { - /* clear unhandled interrupts */ + if (clear_intr != 0U) { if (ch == NULL) { /* * This is probably an interrupt during @@ -1196,9 +1176,11 @@ int gk20a_gr_isr(struct gk20a *g) nvgpu_err(g, "unhandled gr intr 0x%08x for chid: %d", gr_intr, chid); } - gk20a_writel(g, gr_intr_r(), gr_intr); } + /* clear handled and unhandled interrupts */ + g->ops.gr.intr.clear_pending_interrupts(g, gr_intr); + /* Enable fifo access */ g->ops.gr.init.fifo_access(g, true); diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index ffe5c9347..f36f0e7ed 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c @@ -473,6 +473,10 @@ static const struct gpu_ops gm20b_ops = { .get_gfxp_rtv_cb_size = NULL, }, .intr = { + .clear_pending_interrupts = + gm20b_gr_intr_clear_pending_interrupts, + .read_pending_interrupts = + gm20b_gr_intr_read_pending_interrupts, .handle_exceptions = gm20b_gr_intr_handle_exceptions, .read_gpc_tpc_exception = diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c index b565e23f0..94d428627 100644 --- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c @@ -559,6 +559,10 @@ static const struct gpu_ops gp10b_ops = { gp10b_gr_init_commit_cbes_reserve, }, .intr = { + .clear_pending_interrupts = + gm20b_gr_intr_clear_pending_interrupts, + .read_pending_interrupts = + gm20b_gr_intr_read_pending_interrupts, .handle_exceptions = gm20b_gr_intr_handle_exceptions, .read_gpc_tpc_exception = diff --git a/drivers/gpu/nvgpu/gv100/hal_gv100.c b/drivers/gpu/nvgpu/gv100/hal_gv100.c index 2a297f1ce..aabdda9a5 100644 --- a/drivers/gpu/nvgpu/gv100/hal_gv100.c +++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c @@ -699,6 +699,10 @@ static const struct gpu_ops gv100_ops = { gv11b_gr_init_commit_gfxp_wfi_timeout, }, .intr = { + .clear_pending_interrupts = + gm20b_gr_intr_clear_pending_interrupts, + .read_pending_interrupts = + gm20b_gr_intr_read_pending_interrupts, .handle_exceptions = gm20b_gr_intr_handle_exceptions, .read_gpc_tpc_exception = diff --git a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c index 01965f85b..649491901 100644 --- a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c @@ -659,6 +659,10 @@ static const struct gpu_ops gv11b_ops = { gv11b_gr_init_commit_gfxp_wfi_timeout, }, .intr = { + .clear_pending_interrupts = + gm20b_gr_intr_clear_pending_interrupts, + .read_pending_interrupts = + gm20b_gr_intr_read_pending_interrupts, .handle_exceptions = gm20b_gr_intr_handle_exceptions, .read_gpc_tpc_exception = diff --git a/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c b/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c index 3d545df7f..63e9b461d 100644 --- a/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c +++ b/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.c @@ -31,6 +31,16 @@ #include +void gm20b_gr_intr_clear_pending_interrupts(struct gk20a *g, u32 gr_intr) +{ + nvgpu_writel(g, gr_intr_r(), gr_intr); +} + +u32 gm20b_gr_intr_read_pending_interrupts(struct gk20a *g) +{ + return nvgpu_readl(g, gr_intr_r()); +} + bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception) { bool gpc_reset = false; diff --git a/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.h b/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.h index 4af07b670..49f59b6b5 100644 --- a/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.h +++ b/drivers/gpu/nvgpu/hal/gr/intr/gr_intr_gm20b.h @@ -30,6 +30,8 @@ struct nvgpu_gr_config; struct nvgpu_gr_tpc_exception; struct nvgpu_gr_isr_data; +void gm20b_gr_intr_clear_pending_interrupts(struct gk20a *g, u32 gr_intr); +u32 gm20b_gr_intr_read_pending_interrupts(struct gk20a *g); bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception); u32 gm20b_gr_intr_read_gpc_tpc_exception(u32 gpc_exception); u32 gm20b_gr_intr_read_gpc_exception(struct gk20a *g, u32 gpc); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 3f17fb6a6..4414769ab 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -778,6 +778,9 @@ struct gpu_ops { } init; struct { + void (*clear_pending_interrupts)(struct gk20a *g, + u32 gr_intr); + u32 (*read_pending_interrupts)(struct gk20a *g); bool (*handle_exceptions)(struct gk20a *g, bool *is_gpc_exception); u32 (*read_gpc_tpc_exception)(u32 gpc_exception); diff --git a/drivers/gpu/nvgpu/tu104/hal_tu104.c b/drivers/gpu/nvgpu/tu104/hal_tu104.c index b6fdb0942..f13dfcd59 100644 --- a/drivers/gpu/nvgpu/tu104/hal_tu104.c +++ b/drivers/gpu/nvgpu/tu104/hal_tu104.c @@ -731,6 +731,10 @@ static const struct gpu_ops tu104_ops = { gv11b_gr_init_commit_gfxp_wfi_timeout, }, .intr = { + .clear_pending_interrupts = + gm20b_gr_intr_clear_pending_interrupts, + .read_pending_interrupts = + gm20b_gr_intr_read_pending_interrupts, .handle_exceptions = gm20b_gr_intr_handle_exceptions, .read_gpc_tpc_exception =