From: Saleemkhan Jamadar <[email protected]>

For suspend context UMSCH expects the ack from host(vcn).
Queue is suspended then interrupt is sent to driver which
acks back with register update.

note there isn't any resume context interrupt.

Signed-off-by: Saleemkhan Jamadar <[email protected]>
Acked-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c       | 50 ++++++++++++++++---
 .../amd/include/ivsrcid/vcn/irqsrcs_vcn_4_0.h | 10 ++++
 2 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c 
b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
index c246a932a4e6..541d8c694a65 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
@@ -197,6 +197,18 @@ static int vcn_v4_0_5_sw_init(struct amdgpu_ip_block 
*ip_block)
                if (r)
                        return r;
 
+               /* UMSCH SUSPEND  */
+               r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
+                               VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT0, 
&adev->vcn.inst[i].irq);
+               if (r)
+                       return r;
+
+               /* UMSCH RESUME */
+               r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
+                               VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT1, 
&adev->vcn.inst[i].irq);
+               if (r)
+                       return r;
+
                ring = &adev->vcn.inst[i].ring_enc[0];
                ring->use_doorbell = true;
                if (amdgpu_sriov_vf(adev))
@@ -1668,6 +1680,7 @@ static int vcn_v4_0_5_process_interrupt(struct 
amdgpu_device *adev, struct amdgp
                struct amdgpu_iv_entry *entry)
 {
        u32 doorbell_offset = entry->src_data[0];
+       uint32_t reg_data = 0;
        uint32_t ip_instance;
 
        switch (entry->client_id) {
@@ -1685,16 +1698,37 @@ static int vcn_v4_0_5_process_interrupt(struct 
amdgpu_device *adev, struct amdgp
        DRM_DEBUG("IH: VCN TRAP\n");
 
        if (doorbell_offset) {
-               struct xarray *xa = &adev->userq_xa;
-               struct amdgpu_userq_fence_driver *fence_drv;
-               unsigned long flags;
+               switch (entry->src_id) {
+               case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
+                       struct xarray *xa = &adev->userq_xa;
+                       u32 doorbell_offset = entry->src_data[0];
+                       struct amdgpu_userq_fence_driver *fence_drv;
+                       unsigned long flags;
 
-               xa_lock_irqsave(xa, flags);
-               fence_drv = xa_load(xa, doorbell_offset);
-               if (fence_drv)
-                       amdgpu_userq_fence_driver_process(fence_drv);
+                       xa_lock_irqsave(xa, flags);
+                       fence_drv = xa_load(xa, doorbell_offset);
+                       if (fence_drv)
+                               amdgpu_userq_fence_driver_process(fence_drv);
 
-               xa_unlock_irqrestore(xa, flags);
+                       xa_unlock_irqrestore(xa, flags);
+                       break;
+               case VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT0:
+                       reg_data = RREG32_SOC15(VCN, ip_instance, 
regVCN_UMSCH_SYS_INT_ACK);
+                       reg_data |= (VCN_UMSCH_SYS_INT_ACK__INT0_MASK <<
+                                                
VCN_UMSCH_SYS_INT_ACK__INT0__SHIFT); //INT0
+                       WREG32_SOC15(VCN, ip_instance, 
regVCN_UMSCH_SYS_INT_ACK, reg_data);
+                       break;
+               case VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT1:
+                       reg_data = RREG32_SOC15(VCN, ip_instance, 
regVCN_UMSCH_SYS_INT_ACK);
+                       reg_data |= (VCN_UMSCH_SYS_INT_ACK__INT1_MASK <<
+                                                
VCN_UMSCH_SYS_INT_ACK__INT1__SHIFT); //INT1
+                       WREG32_SOC15(VCN, ip_instance, 
regVCN_UMSCH_SYS_INT_ACK, reg_data);
+                       break;
+               default:
+                       DRM_ERROR("Unhandled interrupt: %d %d\n", entry->src_id,
+                                     entry->src_data[0]);
+                       break;
+               }
        } else {
                switch (entry->src_id) {
                case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
diff --git a/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_4_0.h 
b/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_4_0.h
index 03cfa0517df2..994bc39e8810 100644
--- a/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_4_0.h
+++ b/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_4_0.h
@@ -41,4 +41,14 @@
 #define VCN_4_0__SRCID_UVD_POISON                                      160
 #define VCN_4_0__SRCID_DJPEG0_POISON                                   161
 #define VCN_4_0__SRCID_EJPEG0_POISON                                   162
+
+/* 0xa3  UMSCH FW to Host interrupt also Debug interrupt for MES register read 
illegal response*/
+#define VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT0           163
+#define VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT1           164  // 0xa4 UMSCH FW 
to Host interrupt
+#define VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT2           165  // 0xa5 UMSCH FW 
to Host interrupt
+#define VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT3           166  // 0xa6 UMSCH FW 
to Host interrupt
+#define VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT4           167  // 0xa7 UMSCH FW 
to Host interrupt
+#define VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT5           168  // 0xa8 UMSCH FW 
to Host interrupt
+#define VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT6           169  // 0xa9 UMSCH FW 
to Host interrupt
+#define VCN_4_0_0__SRCID__UVD_MESFW2DRV_INT7           170  // 0xaa UMSCH FW 
to Host interrupt
 #endif
-- 
2.43.0

Reply via email to