gpu: nvgpu: Update read_pending_interrupts hal

Modify read_pending_interrupts hal to report the pending gr interrupt
bit back to isr to process.

semaphore_timeout interrupt bit is removed after gk20a chip.
Remove that bit checking from the isr function.
Remove some static functions for handling interrupt, which only calls
gk20a_gr_set_error_notifier. Call that function directly from isr

JIRA NVGPU-3016

Change-Id: Ic7084f038114fbce6d6b5c10a806dee6280e5c0a
Signed-off-by: Vinod G <vinodg@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2092876
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-08 15:55:16 -07:00
committed by mobile promotions
parent 9f486ba21e
commit 1095f0eea3
5 changed files with 104 additions and 100 deletions

View File

@@ -293,11 +293,6 @@ u32 gr_gk20a_get_patch_slots(struct gk20a *g)
return PATCH_CTX_SLOTS_PER_PAGE;
}
#define NVA297_SET_ALPHA_CIRCULAR_BUFFER_SIZE 0x02dcU
#define NVA297_SET_CIRCULAR_BUFFER_SIZE 0x1280U
#define NVA297_SET_SHADER_EXCEPTIONS 0x1528U
#define NVA0C0_SET_SHADER_EXCEPTIONS 0x1528U
#define NVA297_SET_SHADER_EXCEPTIONS_ENABLE_FALSE U32(0)
void gk20a_gr_set_shader_exceptions(struct gk20a *g, u32 data)
@@ -365,29 +360,6 @@ static void gk20a_gr_set_error_notifier(struct gk20a *g,
}
}
static int gk20a_gr_handle_semaphore_timeout_pending(struct gk20a *g,
struct nvgpu_gr_isr_data *isr_data)
{
nvgpu_log_fn(g, " ");
gk20a_gr_set_error_notifier(g, isr_data,
NVGPU_ERR_NOTIFIER_GR_SEMAPHORE_TIMEOUT);
nvgpu_err(g,
"gr semaphore timeout");
return -EINVAL;
}
static int gk20a_gr_intr_illegal_notify_pending(struct gk20a *g,
struct nvgpu_gr_isr_data *isr_data)
{
nvgpu_log_fn(g, " ");
gk20a_gr_set_error_notifier(g, isr_data,
NVGPU_ERR_NOTIFIER_GR_ILLEGAL_NOTIFY);
/* This is an unrecoverable error, reset is needed */
nvgpu_err(g,
"gr semaphore timeout");
return -EINVAL;
}
static int gk20a_gr_handle_illegal_method(struct gk20a *g,
struct nvgpu_gr_isr_data *isr_data)
{
@@ -404,18 +376,6 @@ static int gk20a_gr_handle_illegal_method(struct gk20a *g,
return ret;
}
static int gk20a_gr_handle_illegal_class(struct gk20a *g,
struct nvgpu_gr_isr_data *isr_data)
{
nvgpu_log_fn(g, " ");
gk20a_gr_set_error_notifier(g, isr_data,
NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY);
nvgpu_err(g,
"invalid class 0x%08x, offset 0x%08x",
isr_data->class_num, isr_data->offset);
return -EINVAL;
}
int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch,
struct nvgpu_gr_isr_data *isr_data)
{
@@ -536,23 +496,6 @@ static int gk20a_gr_handle_class_error(struct gk20a *g,
return -EINVAL;
}
static int gk20a_gr_handle_firmware_method(struct gk20a *g,
struct nvgpu_gr_isr_data *isr_data)
{
u32 chid = isr_data->ch != NULL ?
isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID;
nvgpu_log_fn(g, " ");
gk20a_gr_set_error_notifier(g, isr_data,
NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY);
nvgpu_err(g,
"firmware method 0x%08x, offset 0x%08x for channel %u",
isr_data->class_num, isr_data->offset,
chid);
return -EINVAL;
}
/* Used by sw interrupt thread to translate current ctx to chid.
* Also used by regops to translate current ctx to chid and tsgid.
* For performance, we don't want to go through 128 channels every time.
@@ -804,8 +747,8 @@ static int gk20a_gr_post_bpt_events(struct gk20a *g, struct tsg_gk20a *tsg,
int gk20a_gr_isr(struct gk20a *g)
{
struct nvgpu_gr_isr_data isr_data;
struct nvgpu_gr_intr_info intr_info;
bool need_reset = false;
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;
@@ -814,6 +757,7 @@ int gk20a_gr_isr(struct gk20a *g)
u32 global_esr = 0;
u32 chid;
struct nvgpu_gr_config *gr_config = g->gr.config;
u32 gr_intr = g->ops.gr.intr.read_pending_interrupts(g, &intr_info);
u32 clear_intr = gr_intr;
nvgpu_log_fn(g, " ");
@@ -857,72 +801,73 @@ int gk20a_gr_isr(struct gk20a *g)
isr_data.curr_ctx, isr_data.offset,
isr_data.sub_chan, isr_data.class_num);
if ((gr_intr & gr_intr_notify_pending_f()) != 0U) {
if (intr_info.notify != 0U) {
g->ops.gr.intr.handle_notify_pending(g, &isr_data);
clear_intr &= ~gr_intr_notify_pending_f();
clear_intr &= ~intr_info.notify;
}
if ((gr_intr & gr_intr_semaphore_pending_f()) != 0U) {
if (intr_info.semaphore != 0U) {
g->ops.gr.intr.handle_semaphore_pending(g, &isr_data);
clear_intr &= ~gr_intr_semaphore_pending_f();
clear_intr &= ~intr_info.semaphore;
}
if ((gr_intr & gr_intr_semaphore_timeout_pending_f()) != 0U) {
if (gk20a_gr_handle_semaphore_timeout_pending(g,
&isr_data) != 0) {
need_reset = true;
}
clear_intr &= ~gr_intr_semaphore_pending_f();
if (intr_info.illegal_notify != 0U) {
nvgpu_err(g, "illegal notify pending");
gk20a_gr_set_error_notifier(g, &isr_data,
NVGPU_ERR_NOTIFIER_GR_ILLEGAL_NOTIFY);
need_reset = true;
clear_intr &= ~intr_info.illegal_notify;
}
if ((gr_intr & gr_intr_illegal_notify_pending_f()) != 0U) {
if (gk20a_gr_intr_illegal_notify_pending(g,
&isr_data) != 0) {
need_reset = true;
}
clear_intr &= ~gr_intr_illegal_notify_pending_f();
}
if ((gr_intr & gr_intr_illegal_method_pending_f()) != 0U) {
if (intr_info.illegal_method != 0U) {
if (gk20a_gr_handle_illegal_method(g, &isr_data) != 0) {
need_reset = true;
}
clear_intr &= ~gr_intr_illegal_method_pending_f();
clear_intr &= ~intr_info.illegal_method;
}
if ((gr_intr & gr_intr_illegal_class_pending_f()) != 0U) {
if (gk20a_gr_handle_illegal_class(g, &isr_data) != 0) {
need_reset = true;
}
clear_intr &= ~gr_intr_illegal_class_pending_f();
if (intr_info.illegal_class != 0U) {
nvgpu_err(g, "invalid class 0x%08x, offset 0x%08x",
isr_data.class_num, isr_data.offset);
gk20a_gr_set_error_notifier(g, &isr_data,
NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY);
need_reset = true;
clear_intr &= ~intr_info.illegal_class;
}
if ((gr_intr & gr_intr_fecs_error_pending_f()) != 0U) {
if (intr_info.fecs_error != 0U) {
if (g->ops.gr.handle_fecs_error(g, ch, &isr_data) != 0) {
need_reset = true;
}
clear_intr &= ~gr_intr_fecs_error_pending_f();
clear_intr &= ~intr_info.fecs_error;
}
if ((gr_intr & gr_intr_class_error_pending_f()) != 0U) {
if (intr_info.class_error != 0U) {
if (gk20a_gr_handle_class_error(g, &isr_data) != 0) {
need_reset = true;
}
clear_intr &= ~gr_intr_class_error_pending_f();
clear_intr &= ~intr_info.class_error;
}
/* this one happens if someone tries to hit a non-whitelisted
* register using set_falcon[4] */
if ((gr_intr & gr_intr_firmware_method_pending_f()) != 0U) {
if (gk20a_gr_handle_firmware_method(g, &isr_data) != 0) {
need_reset = true;
}
nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg,
"firmware method intr pending\n");
clear_intr &= ~gr_intr_firmware_method_pending_f();
if (intr_info.fw_method != 0U) {
u32 ch_id = isr_data.ch != NULL ?
isr_data.ch->chid : FIFO_INVAL_CHANNEL_ID;
nvgpu_err(g,
"firmware method 0x%08x, offset 0x%08x for channel %u",
isr_data.class_num, isr_data.offset,
ch_id);
gk20a_gr_set_error_notifier(g, &isr_data,
NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY);
need_reset = true;
clear_intr &= ~intr_info.fw_method;
}
if ((gr_intr & gr_intr_exception_pending_f()) != 0U) {
if (intr_info.exception != 0U) {
bool is_gpc_exception = false;
need_reset = g->ops.gr.intr.handle_exceptions(g,
@@ -954,7 +899,7 @@ int gk20a_gr_isr(struct gk20a *g)
}
#endif
}
clear_intr &= ~gr_intr_exception_pending_f();
clear_intr &= ~intr_info.exception;
if (need_reset) {
nvgpu_err(g, "set gr exception notifier");

View File

@@ -36,9 +36,52 @@ 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)
u32 gm20b_gr_intr_read_pending_interrupts(struct gk20a *g,
struct nvgpu_gr_intr_info *intr_info)
{
return nvgpu_readl(g, gr_intr_r());
u32 gr_intr = nvgpu_readl(g, gr_intr_r());
(void) memset(intr_info, 0, sizeof(struct nvgpu_gr_intr_info));
if ((gr_intr & gr_intr_notify_pending_f()) != 0U) {
intr_info->notify = gr_intr_notify_pending_f();
}
if ((gr_intr & gr_intr_semaphore_pending_f()) != 0U) {
intr_info->semaphore = gr_intr_semaphore_pending_f();
}
if ((gr_intr & gr_intr_illegal_notify_pending_f()) != 0U) {
intr_info->illegal_notify = gr_intr_illegal_notify_pending_f();
}
if ((gr_intr & gr_intr_illegal_method_pending_f()) != 0U) {
intr_info->illegal_method = gr_intr_illegal_method_pending_f();
}
if ((gr_intr & gr_intr_illegal_class_pending_f()) != 0U) {
intr_info->illegal_class = gr_intr_illegal_class_pending_f();
}
if ((gr_intr & gr_intr_fecs_error_pending_f()) != 0U) {
intr_info->fecs_error = gr_intr_fecs_error_pending_f();
}
if ((gr_intr & gr_intr_class_error_pending_f()) != 0U) {
intr_info->class_error = gr_intr_class_error_pending_f();
}
/* this one happens if someone tries to hit a non-whitelisted
* register using set_falcon[4] */
if ((gr_intr & gr_intr_firmware_method_pending_f()) != 0U) {
intr_info->fw_method = gr_intr_firmware_method_pending_f();
}
if ((gr_intr & gr_intr_exception_pending_f()) != 0U) {
intr_info->exception = gr_intr_exception_pending_f();
}
return gr_intr;
}
bool gm20b_gr_intr_handle_exceptions(struct gk20a *g, bool *is_gpc_exception)

View File

@@ -29,9 +29,11 @@ struct gk20a;
struct nvgpu_gr_config;
struct nvgpu_gr_tpc_exception;
struct nvgpu_gr_isr_data;
struct nvgpu_gr_intr_info;
void gm20b_gr_intr_clear_pending_interrupts(struct gk20a *g, u32 gr_intr);
u32 gm20b_gr_intr_read_pending_interrupts(struct gk20a *g);
u32 gm20b_gr_intr_read_pending_interrupts(struct gk20a *g,
struct nvgpu_gr_intr_info *intr_info);
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

@@ -66,6 +66,7 @@ struct nvgpu_gr_zbc_query_params;
struct nvgpu_gr_zcull;
struct nvgpu_gr_zcull_info;
struct nvgpu_gr_tpc_exception;
struct nvgpu_gr_intr_info;
struct nvgpu_channel_hw_state;
struct nvgpu_engine_status_info;
struct nvgpu_pbdma_status_info;
@@ -784,7 +785,8 @@ struct gpu_ops {
struct {
void (*clear_pending_interrupts)(struct gk20a *g,
u32 gr_intr);
u32 (*read_pending_interrupts)(struct gk20a *g);
u32 (*read_pending_interrupts)(struct gk20a *g,
struct nvgpu_gr_intr_info *intr_info);
bool (*handle_exceptions)(struct gk20a *g,
bool *is_gpc_exception);
u32 (*read_gpc_tpc_exception)(u32 gpc_exception);

View File

@@ -27,6 +27,18 @@
struct channel_gk20a;
struct nvgpu_gr_intr_info {
u32 notify;
u32 semaphore;
u32 illegal_notify;
u32 illegal_method;
u32 illegal_class;
u32 fecs_error;
u32 class_error;
u32 fw_method;
u32 exception;
};
struct nvgpu_gr_tpc_exception {
bool tex_exception;
bool sm_exception;