vce_v2_0 sets VCE_SYS_INT_TRAP_INTERRUPT_EN in VCE_SYS_INT_EN so that
the VCE_CMD_TRAP emitted after each fence raises an interrupt.  The
VCE1 code, used by SI and Trinity/Richland, never does, and amdgpu's
vce_v1_0 does (mmVCE_SYS_INT_EN, 0x8340, i.e. byte offset 0x20d00 on
SI).  VCE fences are therefore never processed from the interrupt
handler and are only noticed when a fence wait times out.

Enable the trap interrupt at the end of vce_v1_0_start().  CIK also
goes through vce_v1_0_start() (via vce_v1_0_init() and kv_dpm), but has
VCE_SYS_INT_EN at a different offset and already enables it in
vce_v2_0_resume(), so only do it for VCE1, i.e. before CHIP_BONAIRE.

Observed on a Radeon HD 8870M (Cape Verde, 1002:6821) with VCE firmware
50.0.1, Mesa 25.0.7 radeonsi and ffmpeg h264_vaapi on Debian 6.12.113:

 - Stock driver: the encode hangs after a few dozen frames ("ring 0
   stalled", "ring 3 stalled", "GPU lockup"), and the reset does not
   recover ("failed VCE resume (-22)", "ring 0 test failed").
 - With the hardware ring semaphores of the VCE ring disabled as a
   workaround, the hang is gone but encoding runs at 3.9 fps
   (~256 ms per frame), consistent with fences being noticed only by
   timeouts.
 - With this series: 640x360 for 1800 frames, 1280x720 for 900 frames
   and 1920x1080 for 600 frames, all in real time with no decode
   errors, and 191 fps at 720p / 91 fps at 1080p unthrottled.  Four
   runtime suspend/resume cycles with an encode in between also
   worked.  No lockup, reset, WARNING or error in the kernel log, with
   DPM and runtime PM enabled.

Trinity/Richland takes the same path and is covered by the previous
patch, but I have no such hardware to test.  CIK is not affected.

Fixes: a918efab631a ("drm/radeon: add VCE 1.0 support v4")
Cc: [email protected]
Signed-off-by: Matheus Tagliari <[email protected]>
---
 drivers/gpu/drm/radeon/sid.h      | 2 ++
 drivers/gpu/drm/radeon/vce_v1_0.c | 9 +++++++++
 2 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index f9267b026..ba322de84 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -1878,6 +1878,8 @@
 #define        DMA_PACKET_NOP                                    0xf
 
 #define VCE_STATUS                                     0x20004
+#define VCE_SYS_INT_EN                                 0x20d00
+#define                VCE_SYS_INT_TRAP_INTERRUPT_EN           (1 << 3)
 #define VCE_VCPU_CNTL                                  0x20014
 #define                VCE_CLK_EN                              (1 << 0)
 #define VCE_VCPU_CACHE_OFFSET0                         0x20024
diff --git a/drivers/gpu/drm/radeon/vce_v1_0.c 
b/drivers/gpu/drm/radeon/vce_v1_0.c
index bdfbcf14b..09fc1572a 100644
--- a/drivers/gpu/drm/radeon/vce_v1_0.c
+++ b/drivers/gpu/drm/radeon/vce_v1_0.c
@@ -350,6 +350,15 @@ int vce_v1_0_start(struct radeon_device *rdev)
                return r;
        }
 
+       /*
+        * Enable the trap interrupt so that VCE fences are processed.
+        * CIK also gets here but has VCE_SYS_INT_EN elsewhere and enables
+        * it in vce_v2_0_resume().
+        */
+       if (rdev->family < CHIP_BONAIRE)
+               WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN,
+                        ~VCE_SYS_INT_TRAP_INTERRUPT_EN);
+
        return 0;
 }
 
-- 
2.47.3

Reply via email to