gpu: nvgpu: gk20a_gr_isr code cleanup

Simplify the interrupt handling code in gk20a_gr_isr.
There is no need to individually clear the handled interrupt bit.
Clear all interrupt bits set at the end with one register write.

Add two new hals
read_pending_interrupts  - read the gr interrupt register
clear_pending_interrupts - write to gr interrupt register the pending ones.

JIRA NVGPU-3016

Change-Id: Iea682524d767d0f9b82d1137a8c0358e65eabade
Signed-off-by: Vinod G <vinodg@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2091086
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Vinod G
2019-04-05 16:36:57 -07:00
committed by mobile promotions
parent 9c465d5fd5
commit 744f0afcb2
9 changed files with 51 additions and 34 deletions

View File

@@ -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);

View File

@@ -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 =

View File

@@ -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 =

View File

@@ -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 =

View File

@@ -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 =

View File

@@ -31,6 +31,16 @@
#include <nvgpu/hw/gm20b/hw_gr_gm20b.h>
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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 =