gpu: nvgpu: Add ELPG protected call for GR and CE intr

- Accessing any PGRAPH registers in GR intr retrigger
  ISR routine when ELPG is engaged causes idle snap.
- This idle snap is caught when nvgpu_submit_illegal_class
  test is run.
- To avoid access to PGRAPH registers when ELPG is engaged
  add elpg protected call for GR intr retrigger and CE ISR
  and retrigger HALs

Bug 200777033

Change-Id: Ieef4a423faf79f09476d696c3078b113750548bb
Signed-off-by: Divya Singhatwaria <dsinghatwari@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2586449
Reviewed-by: Mahantesh Kumbar <mkumbar@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Divya Singhatwaria
2021-08-14 22:39:12 +05:30
committed by mobile promotions
parent e3dd17a287
commit 9984b59a00
4 changed files with 30 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -64,7 +64,7 @@ void ga10b_gr_intr_handle_tpc_sm_ecc_exception(struct gk20a *g, u32 gpc,
bool ga10b_gr_intr_sm_ecc_status_errors(struct gk20a *g, bool ga10b_gr_intr_sm_ecc_status_errors(struct gk20a *g,
u32 ecc_status_reg, enum nvgpu_gr_sm_ecc_error_types err_type, u32 ecc_status_reg, enum nvgpu_gr_sm_ecc_error_types err_type,
struct nvgpu_gr_sm_ecc_status *ecc_status); struct nvgpu_gr_sm_ecc_status *ecc_status);
void ga10b_gr_intr_retrigger(struct gk20a *g); int ga10b_gr_intr_retrigger(struct gk20a *g);
void ga10b_gr_intr_enable_gpc_crop_hww(struct gk20a *g); void ga10b_gr_intr_enable_gpc_crop_hww(struct gk20a *g);
void ga10b_gr_intr_enable_gpc_zrop_hww(struct gk20a *g); void ga10b_gr_intr_enable_gpc_zrop_hww(struct gk20a *g);
void ga10b_gr_intr_handle_gpc_crop_hww(struct gk20a *g, u32 gpc, u32 exception); void ga10b_gr_intr_handle_gpc_crop_hww(struct gk20a *g, u32 gpc, u32 exception);

View File

@@ -1028,10 +1028,12 @@ void ga10b_gr_intr_enable_interrupts(struct gk20a *g, bool enable)
} }
} }
void ga10b_gr_intr_retrigger(struct gk20a *g) int ga10b_gr_intr_retrigger(struct gk20a *g)
{ {
nvgpu_writel(g, gr_intr_retrigger_r(), nvgpu_writel(g, gr_intr_retrigger_r(),
gr_intr_retrigger_trigger_true_f()); gr_intr_retrigger_trigger_true_f());
return 0;
} }
u32 ga10b_gr_intr_read_pending_interrupts(struct gk20a *g, u32 ga10b_gr_intr_read_pending_interrupts(struct gk20a *g,

View File

@@ -714,7 +714,16 @@ static int ga10b_intr_gr_stall_isr(struct gk20a *g)
int err; int err;
err = nvgpu_pg_elpg_protected_call(g, g->ops.gr.intr.stall_isr(g)); err = nvgpu_pg_elpg_protected_call(g, g->ops.gr.intr.stall_isr(g));
g->ops.gr.intr.retrigger(g); if (err != 0) {
nvgpu_err(g, "GR intr stall_isr failed");
return err;
}
err = nvgpu_pg_elpg_protected_call(g, g->ops.gr.intr.retrigger(g));
if (err != 0) {
nvgpu_err(g, "GR intr retrigger failed");
return err;
}
return err; return err;
} }
@@ -807,6 +816,7 @@ static void ga10b_intr_isr_stall_host2soc_3(struct gk20a *g)
u64 engine_intr_mask; u64 engine_intr_mask;
u32 vectorid; u32 vectorid;
const struct nvgpu_device *dev; const struct nvgpu_device *dev;
int err;
vectorid = vectorid =
g->mc.intr_unit_info[NVGPU_CIC_INTR_UNIT_CE_STALL].vectorid[0]; g->mc.intr_unit_info[NVGPU_CIC_INTR_UNIT_CE_STALL].vectorid[0];
@@ -814,6 +824,15 @@ static void ga10b_intr_isr_stall_host2soc_3(struct gk20a *g)
handled_subtree_mask |= unit_subtree_mask; handled_subtree_mask |= unit_subtree_mask;
ga10b_intr_subtree_clear(g, subtree, unit_subtree_mask); ga10b_intr_subtree_clear(g, subtree, unit_subtree_mask);
/* disable elpg before accessing CE registers */
err = nvgpu_pg_elpg_disable(g);
if (err != 0) {
nvgpu_err(g, "ELPG disable failed");
/* enable ELPG again so that PG SM is in known state*/
(void) nvgpu_pg_elpg_enable(g);
goto exit;
}
for (i = 0U; i < g->fifo.num_engines; i++) { for (i = 0U; i < g->fifo.num_engines; i++) {
dev = g->fifo.active_engines[i]; dev = g->fifo.active_engines[i];
@@ -832,7 +851,11 @@ static void ga10b_intr_isr_stall_host2soc_3(struct gk20a *g)
g->ops.ce.intr_retrigger(g, dev->inst_id); g->ops.ce.intr_retrigger(g, dev->inst_id);
} }
/* enable elpg again */
(void) nvgpu_pg_elpg_enable(g);
} }
exit:
ga10b_intr_subtree_clear_unhandled(g, subtree, intr_leaf0, intr_leaf1, ga10b_intr_subtree_clear_unhandled(g, subtree, intr_leaf0, intr_leaf1,
handled_subtree_mask); handled_subtree_mask);
} }

View File

@@ -475,7 +475,7 @@ struct gops_gr_intr {
/** @cond DOXYGEN_SHOULD_SKIP_THIS */ /** @cond DOXYGEN_SHOULD_SKIP_THIS */
#if defined(CONFIG_NVGPU_HAL_NON_FUSA) #if defined(CONFIG_NVGPU_HAL_NON_FUSA)
void (*retrigger)(struct gk20a *g); int (*retrigger)(struct gk20a *g);
u32 (*enable_mask)(struct gk20a *g); u32 (*enable_mask)(struct gk20a *g);
#endif #endif
int (*handle_fecs_error)(struct gk20a *g, int (*handle_fecs_error)(struct gk20a *g,