[PATCH 2/2] drm/amdgpu: LSDMA check PIO error status

Alex Deucher <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Philip Yang <[email protected]>

Check LSDMA PIO error status bits after each transfer completes to
detect silent copy failures caused by issues such as IFoE (Infinity
Fabric over Ethernet) errors.

The following error conditions are checked:
- Write return NACK / general error
- Read return NACK / general error
- Invalid address
- Zero count
- DRAM ECC error

Log the error via dev_warn() and clear only the set error bits
(write-1-to-clear) so that subsequent transfers can proceed once the
underlying issue is resolved.

Signed-off-by: Philip Yang <[email protected]>
Reviewed-by: Felix Kuehling <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/lsdma_v7_1.c | 27 ++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/lsdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/lsdma_v7_1.c
index d93a0e65ce7de..fa739b0e9ddfb 100644
--- a/drivers/gpu/drm/amd/amdgpu/lsdma_v7_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/lsdma_v7_1.c
@@ -31,9 +31,34 @@
 
 static int lsdma_v7_1_wait_pio_status(struct amdgpu_device *adev)
 {
-	return amdgpu_lsdma_wait_for(adev, SOC15_REG_OFFSET(LSDMA, 0, regLSDMA_PIO_STATUS),
+	u32 error_mask;
+	u32 reg;
+	int r;
+
+	r = amdgpu_lsdma_wait_for(adev, SOC15_REG_OFFSET(LSDMA, 0, regLSDMA_PIO_STATUS),
 			LSDMA_PIO_STATUS__PIO_IDLE_MASK | LSDMA_PIO_STATUS__PIO_FIFO_EMPTY_MASK,
 			LSDMA_PIO_STATUS__PIO_IDLE_MASK | LSDMA_PIO_STATUS__PIO_FIFO_EMPTY_MASK);
+	if (r)
+		return r;
+
+	error_mask = LSDMA_PIO_STATUS__ERROR_WRRET_NACK_GEN_ERR_MASK |
+		     LSDMA_PIO_STATUS__ERROR_RDRET_NACK_GEN_ERR_MASK |
+		     LSDMA_PIO_STATUS__ERROR_INVALID_ADDR_MASK |
+		     LSDMA_PIO_STATUS__ERROR_ZERO_COUNT_MASK |
+		     LSDMA_PIO_STATUS__ERROR_DRAM_ECC_MASK;
+
+	reg = RREG32(SOC15_REG_OFFSET(LSDMA, 0, regLSDMA_PIO_STATUS));
+	if (reg & error_mask) {
+		dev_warn(adev->dev, "LSDMA PIO error status bits 0x%x\n", reg & error_mask);
+
+		/*
+		 * write 1 to clear only the set lsdma error status bits
+		 */
+		WREG32(SOC15_REG_OFFSET(LSDMA, 0, regLSDMA_PIO_STATUS), reg & error_mask);
+		return -EIO;
+	}
+
+	return 0;
 }
 
 static int lsdma_v7_1_copy_mem(struct amdgpu_device *adev,
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.