From 066383830893c0fc43ec28f833185eab91e9dfc9 Mon Sep 17 00:00:00 2001 From: Debarshi Dutta Date: Tue, 3 Sep 2019 14:05:20 +0530 Subject: gpu: nvgpu: correct handling of pbdma rc The current code reads the pbdma_status info after clearing the interrupt. Other interrupts/sleep can cause enough delay between clearing the interrupt and pbdma switching the channel leading to invalid channel/tsg ID. Correct that by reading the pbdma_status info register before clearing of the pbdma interrupt to correctly read the context information before the pbdma can switch out the context. Bug 200533450 Change-Id: Ic2f0682526e00d14ad58f0411472f34388183f2b Signed-off-by: Debarshi Dutta Reviewed-on: https://git-master.nvidia.com/r/2165047 (cherry-picked from 0ef96e4b1a7979d2bae0e52924e976515cb87400 in dev-main) Reviewed-on: https://git-master.nvidia.com/r/2188861 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 5aca7d62..1b18a8f9 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -2769,14 +2769,12 @@ unsigned int gk20a_fifo_handle_pbdma_intr_1(struct gk20a *g, static void gk20a_fifo_pbdma_fault_rc(struct gk20a *g, struct fifo_gk20a *f, u32 pbdma_id, - u32 error_notifier) + u32 error_notifier, u32 status) { - u32 status; u32 id; nvgpu_log(g, gpu_dbg_info, "pbdma id %d error notifier %d", pbdma_id, error_notifier); - status = gk20a_readl(g, fifo_pbdma_status_r(pbdma_id)); /* Remove channel from runlist */ id = fifo_pbdma_status_id_v(status); if (fifo_pbdma_status_id_type_v(status) @@ -2816,6 +2814,7 @@ u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, struct fifo_gk20a *f, u32 handled = 0; u32 error_notifier = NVGPU_ERR_NOTIFIER_PBDMA_ERROR; unsigned int rc_type = RC_TYPE_NO_RC; + u32 pbdma_status_info = 0; if (pbdma_intr_0) { nvgpu_log(g, gpu_dbg_info | gpu_dbg_intr, @@ -2825,6 +2824,9 @@ u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, struct fifo_gk20a *f, if (g->ops.fifo.handle_pbdma_intr_0(g, pbdma_id, pbdma_intr_0, &handled, &error_notifier) != RC_TYPE_NO_RC) { rc_type = RC_TYPE_PBDMA_FAULT; + + pbdma_status_info = gk20a_readl(g, + fifo_pbdma_status_r(pbdma_id)); } gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0); } @@ -2837,12 +2839,16 @@ u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, struct fifo_gk20a *f, if (g->ops.fifo.handle_pbdma_intr_1(g, pbdma_id, pbdma_intr_1, &handled, &error_notifier) != RC_TYPE_NO_RC) { rc_type = RC_TYPE_PBDMA_FAULT; + + pbdma_status_info = gk20a_readl(g, + fifo_pbdma_status_r(pbdma_id)); } gk20a_writel(g, pbdma_intr_1_r(pbdma_id), pbdma_intr_1); } if (rc == RC_YES && rc_type == RC_TYPE_PBDMA_FAULT) { - gk20a_fifo_pbdma_fault_rc(g, f, pbdma_id, error_notifier); + gk20a_fifo_pbdma_fault_rc(g, f, pbdma_id, error_notifier, + pbdma_status_info); } return handled; -- cgit v1.2.2