mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
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:
committed by
mobile promotions
parent
9c465d5fd5
commit
744f0afcb2
@@ -989,7 +989,7 @@ int gk20a_gr_isr(struct gk20a *g)
|
|||||||
{
|
{
|
||||||
struct nvgpu_gr_isr_data isr_data;
|
struct nvgpu_gr_isr_data isr_data;
|
||||||
bool need_reset = false;
|
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 *ch = NULL;
|
||||||
struct channel_gk20a *fault_ch = NULL;
|
struct channel_gk20a *fault_ch = NULL;
|
||||||
u32 tsgid = NVGPU_INVALID_TSG_ID;
|
u32 tsgid = NVGPU_INVALID_TSG_ID;
|
||||||
@@ -998,6 +998,7 @@ int gk20a_gr_isr(struct gk20a *g)
|
|||||||
u32 global_esr = 0;
|
u32 global_esr = 0;
|
||||||
u32 chid;
|
u32 chid;
|
||||||
struct nvgpu_gr_config *gr_config = g->gr.config;
|
struct nvgpu_gr_config *gr_config = g->gr.config;
|
||||||
|
u32 clear_intr = gr_intr;
|
||||||
|
|
||||||
nvgpu_log_fn(g, " ");
|
nvgpu_log_fn(g, " ");
|
||||||
nvgpu_log(g, gpu_dbg_intr, "pgraph intr 0x%08x", gr_intr);
|
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) {
|
if ((gr_intr & gr_intr_notify_pending_f()) != 0U) {
|
||||||
g->ops.gr.intr.handle_notify_pending(g, &isr_data);
|
g->ops.gr.intr.handle_notify_pending(g, &isr_data);
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_notify_pending_f();
|
||||||
gr_intr_notify_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_notify_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gr_intr & gr_intr_semaphore_pending_f()) != 0U) {
|
if ((gr_intr & gr_intr_semaphore_pending_f()) != 0U) {
|
||||||
g->ops.gr.intr.handle_semaphore_pending(g, &isr_data);
|
g->ops.gr.intr.handle_semaphore_pending(g, &isr_data);
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_semaphore_pending_f();
|
||||||
gr_intr_semaphore_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_semaphore_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gr_intr & gr_intr_semaphore_timeout_pending_f()) != 0U) {
|
if ((gr_intr & gr_intr_semaphore_timeout_pending_f()) != 0U) {
|
||||||
@@ -1059,9 +1056,7 @@ int gk20a_gr_isr(struct gk20a *g)
|
|||||||
&isr_data) != 0) {
|
&isr_data) != 0) {
|
||||||
need_reset = true;
|
need_reset = true;
|
||||||
}
|
}
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_semaphore_pending_f();
|
||||||
gr_intr_semaphore_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_semaphore_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gr_intr & gr_intr_illegal_notify_pending_f()) != 0U) {
|
if ((gr_intr & gr_intr_illegal_notify_pending_f()) != 0U) {
|
||||||
@@ -1069,45 +1064,35 @@ int gk20a_gr_isr(struct gk20a *g)
|
|||||||
&isr_data) != 0) {
|
&isr_data) != 0) {
|
||||||
need_reset = true;
|
need_reset = true;
|
||||||
}
|
}
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_illegal_notify_pending_f();
|
||||||
gr_intr_illegal_notify_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_illegal_notify_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gr_intr & gr_intr_illegal_method_pending_f()) != 0U) {
|
if ((gr_intr & gr_intr_illegal_method_pending_f()) != 0U) {
|
||||||
if (gk20a_gr_handle_illegal_method(g, &isr_data) != 0) {
|
if (gk20a_gr_handle_illegal_method(g, &isr_data) != 0) {
|
||||||
need_reset = true;
|
need_reset = true;
|
||||||
}
|
}
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_illegal_method_pending_f();
|
||||||
gr_intr_illegal_method_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_illegal_method_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gr_intr & gr_intr_illegal_class_pending_f()) != 0U) {
|
if ((gr_intr & gr_intr_illegal_class_pending_f()) != 0U) {
|
||||||
if (gk20a_gr_handle_illegal_class(g, &isr_data) != 0) {
|
if (gk20a_gr_handle_illegal_class(g, &isr_data) != 0) {
|
||||||
need_reset = true;
|
need_reset = true;
|
||||||
}
|
}
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_illegal_class_pending_f();
|
||||||
gr_intr_illegal_class_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_illegal_class_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gr_intr & gr_intr_fecs_error_pending_f()) != 0U) {
|
if ((gr_intr & gr_intr_fecs_error_pending_f()) != 0U) {
|
||||||
if (g->ops.gr.handle_fecs_error(g, ch, &isr_data) != 0) {
|
if (g->ops.gr.handle_fecs_error(g, ch, &isr_data) != 0) {
|
||||||
need_reset = true;
|
need_reset = true;
|
||||||
}
|
}
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_fecs_error_pending_f();
|
||||||
gr_intr_fecs_error_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_fecs_error_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gr_intr & gr_intr_class_error_pending_f()) != 0U) {
|
if ((gr_intr & gr_intr_class_error_pending_f()) != 0U) {
|
||||||
if (gk20a_gr_handle_class_error(g, &isr_data) != 0) {
|
if (gk20a_gr_handle_class_error(g, &isr_data) != 0) {
|
||||||
need_reset = true;
|
need_reset = true;
|
||||||
}
|
}
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_class_error_pending_f();
|
||||||
gr_intr_class_error_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_class_error_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this one happens if someone tries to hit a non-whitelisted
|
/* 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,
|
nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg,
|
||||||
"firmware method intr pending\n");
|
"firmware method intr pending\n");
|
||||||
gk20a_writel(g, gr_intr_r(),
|
clear_intr &= ~gr_intr_firmware_method_pending_f();
|
||||||
gr_intr_firmware_method_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_firmware_method_pending_f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gr_intr & gr_intr_exception_pending_f()) != 0U) {
|
if ((gr_intr & gr_intr_exception_pending_f()) != 0U) {
|
||||||
@@ -1155,9 +1138,7 @@ int gk20a_gr_isr(struct gk20a *g)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
clear_intr &= ~gr_intr_exception_pending_f();
|
||||||
gk20a_writel(g, gr_intr_r(), gr_intr_exception_reset_f());
|
|
||||||
gr_intr &= ~gr_intr_exception_pending_f();
|
|
||||||
|
|
||||||
if (need_reset) {
|
if (need_reset) {
|
||||||
nvgpu_err(g, "set gr exception notifier");
|
nvgpu_err(g, "set gr exception notifier");
|
||||||
@@ -1182,8 +1163,7 @@ int gk20a_gr_isr(struct gk20a *g)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gr_intr != 0U) {
|
if (clear_intr != 0U) {
|
||||||
/* clear unhandled interrupts */
|
|
||||||
if (ch == NULL) {
|
if (ch == NULL) {
|
||||||
/*
|
/*
|
||||||
* This is probably an interrupt during
|
* 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",
|
nvgpu_err(g, "unhandled gr intr 0x%08x for chid: %d",
|
||||||
gr_intr, chid);
|
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 */
|
/* Enable fifo access */
|
||||||
g->ops.gr.init.fifo_access(g, true);
|
g->ops.gr.init.fifo_access(g, true);
|
||||||
|
|
||||||
|
|||||||
@@ -473,6 +473,10 @@ static const struct gpu_ops gm20b_ops = {
|
|||||||
.get_gfxp_rtv_cb_size = NULL,
|
.get_gfxp_rtv_cb_size = NULL,
|
||||||
},
|
},
|
||||||
.intr = {
|
.intr = {
|
||||||
|
.clear_pending_interrupts =
|
||||||
|
gm20b_gr_intr_clear_pending_interrupts,
|
||||||
|
.read_pending_interrupts =
|
||||||
|
gm20b_gr_intr_read_pending_interrupts,
|
||||||
.handle_exceptions =
|
.handle_exceptions =
|
||||||
gm20b_gr_intr_handle_exceptions,
|
gm20b_gr_intr_handle_exceptions,
|
||||||
.read_gpc_tpc_exception =
|
.read_gpc_tpc_exception =
|
||||||
|
|||||||
@@ -559,6 +559,10 @@ static const struct gpu_ops gp10b_ops = {
|
|||||||
gp10b_gr_init_commit_cbes_reserve,
|
gp10b_gr_init_commit_cbes_reserve,
|
||||||
},
|
},
|
||||||
.intr = {
|
.intr = {
|
||||||
|
.clear_pending_interrupts =
|
||||||
|
gm20b_gr_intr_clear_pending_interrupts,
|
||||||
|
.read_pending_interrupts =
|
||||||
|
gm20b_gr_intr_read_pending_interrupts,
|
||||||
.handle_exceptions =
|
.handle_exceptions =
|
||||||
gm20b_gr_intr_handle_exceptions,
|
gm20b_gr_intr_handle_exceptions,
|
||||||
.read_gpc_tpc_exception =
|
.read_gpc_tpc_exception =
|
||||||
|
|||||||
@@ -699,6 +699,10 @@ static const struct gpu_ops gv100_ops = {
|
|||||||
gv11b_gr_init_commit_gfxp_wfi_timeout,
|
gv11b_gr_init_commit_gfxp_wfi_timeout,
|
||||||
},
|
},
|
||||||
.intr = {
|
.intr = {
|
||||||
|
.clear_pending_interrupts =
|
||||||
|
gm20b_gr_intr_clear_pending_interrupts,
|
||||||
|
.read_pending_interrupts =
|
||||||
|
gm20b_gr_intr_read_pending_interrupts,
|
||||||
.handle_exceptions =
|
.handle_exceptions =
|
||||||
gm20b_gr_intr_handle_exceptions,
|
gm20b_gr_intr_handle_exceptions,
|
||||||
.read_gpc_tpc_exception =
|
.read_gpc_tpc_exception =
|
||||||
|
|||||||
@@ -659,6 +659,10 @@ static const struct gpu_ops gv11b_ops = {
|
|||||||
gv11b_gr_init_commit_gfxp_wfi_timeout,
|
gv11b_gr_init_commit_gfxp_wfi_timeout,
|
||||||
},
|
},
|
||||||
.intr = {
|
.intr = {
|
||||||
|
.clear_pending_interrupts =
|
||||||
|
gm20b_gr_intr_clear_pending_interrupts,
|
||||||
|
.read_pending_interrupts =
|
||||||
|
gm20b_gr_intr_read_pending_interrupts,
|
||||||
.handle_exceptions =
|
.handle_exceptions =
|
||||||
gm20b_gr_intr_handle_exceptions,
|
gm20b_gr_intr_handle_exceptions,
|
||||||
.read_gpc_tpc_exception =
|
.read_gpc_tpc_exception =
|
||||||
|
|||||||
@@ -31,6 +31,16 @@
|
|||||||
|
|
||||||
#include <nvgpu/hw/gm20b/hw_gr_gm20b.h>
|
#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 gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception)
|
||||||
{
|
{
|
||||||
bool gpc_reset = false;
|
bool gpc_reset = false;
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ struct nvgpu_gr_config;
|
|||||||
struct nvgpu_gr_tpc_exception;
|
struct nvgpu_gr_tpc_exception;
|
||||||
struct nvgpu_gr_isr_data;
|
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);
|
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_tpc_exception(u32 gpc_exception);
|
||||||
u32 gm20b_gr_intr_read_gpc_exception(struct gk20a *g, u32 gpc);
|
u32 gm20b_gr_intr_read_gpc_exception(struct gk20a *g, u32 gpc);
|
||||||
|
|||||||
@@ -778,6 +778,9 @@ struct gpu_ops {
|
|||||||
} init;
|
} init;
|
||||||
|
|
||||||
struct {
|
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 (*handle_exceptions)(struct gk20a *g,
|
||||||
bool *is_gpc_exception);
|
bool *is_gpc_exception);
|
||||||
u32 (*read_gpc_tpc_exception)(u32 gpc_exception);
|
u32 (*read_gpc_tpc_exception)(u32 gpc_exception);
|
||||||
|
|||||||
@@ -731,6 +731,10 @@ static const struct gpu_ops tu104_ops = {
|
|||||||
gv11b_gr_init_commit_gfxp_wfi_timeout,
|
gv11b_gr_init_commit_gfxp_wfi_timeout,
|
||||||
},
|
},
|
||||||
.intr = {
|
.intr = {
|
||||||
|
.clear_pending_interrupts =
|
||||||
|
gm20b_gr_intr_clear_pending_interrupts,
|
||||||
|
.read_pending_interrupts =
|
||||||
|
gm20b_gr_intr_read_pending_interrupts,
|
||||||
.handle_exceptions =
|
.handle_exceptions =
|
||||||
gm20b_gr_intr_handle_exceptions,
|
gm20b_gr_intr_handle_exceptions,
|
||||||
.read_gpc_tpc_exception =
|
.read_gpc_tpc_exception =
|
||||||
|
|||||||
Reference in New Issue
Block a user