drm/amdgpu/vcn1: read back register after written
authorDavid (Ming Qiang) Wu <David.Wu3@amd.com>
Wed, 14 May 2025 22:50:15 +0000 (18:50 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 29 May 2025 14:55:39 +0000 (10:55 -0400)
V3: drop changes where readbacks have implemented. This patch set
    is to add readbacks only.

V2: use common register UVD_STATUS for readback (standard PCI MMIO
    behavior, i.e. readback post all writes to let the writes hit
    the hardware)
    add readback in ..._stop() for more coverage.

Similar to the changes made for VCN v4.0.5 where readback to post the
writes to avoid race with the doorbell, the addition of register
readback support in other VCN versions is intended to prevent potential
race conditions, even though such issues have not been observed yet.
This change ensures consistency across different VCN variants and helps
avoid similar issues. The overhead introduced is negligible.

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Signed-off-by: David (Ming Qiang) Wu <David.Wu3@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c

index 21b57c2..c749477 100644 (file)
@@ -1009,6 +1009,11 @@ static int vcn_v1_0_start_spg_mode(struct amdgpu_vcn_inst *vinst)
 
        jpeg_v1_0_start(adev, 0);
 
+       /* Keeping one read-back to ensure all register writes are done,
+        * otherwise it may introduce race conditions.
+        */
+       RREG32_SOC15(UVD, 0, mmUVD_STATUS);
+
        return 0;
 }
 
@@ -1154,6 +1159,11 @@ static int vcn_v1_0_start_dpg_mode(struct amdgpu_vcn_inst *vinst)
 
        jpeg_v1_0_start(adev, 1);
 
+       /* Keeping one read-back to ensure all register writes are done,
+        * otherwise it may introduce race conditions.
+        */
+       RREG32_SOC15(UVD, 0, mmUVD_STATUS);
+
        return 0;
 }
 
@@ -1216,6 +1226,12 @@ static int vcn_v1_0_stop_spg_mode(struct amdgpu_vcn_inst *vinst)
 
        vcn_v1_0_enable_clock_gating(vinst);
        vcn_1_0_enable_static_power_gating(vinst);
+
+       /* Keeping one read-back to ensure all register writes are done,
+        * otherwise it may introduce race conditions.
+        */
+       RREG32_SOC15(UVD, 0, mmUVD_STATUS);
+
        return 0;
 }
 
@@ -1250,6 +1266,11 @@ static int vcn_v1_0_stop_dpg_mode(struct amdgpu_vcn_inst *vinst)
        WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0,
                        ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
 
+       /* Keeping one read-back to ensure all register writes are done,
+        * otherwise it may introduce race conditions.
+        */
+       RREG32_SOC15(UVD, 0, mmUVD_STATUS);
+
        return 0;
 }