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
