From 763b6076a9e1d815404cca855329879f81cb6b27 Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Tue, 7 Apr 2026 23:02:38 -0400 Subject: [PATCH] drm/amdgpu: LSDMA check PIO error status 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 Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- 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 d93a0e65ce7d..fa739b0e9ddf 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,