MES queue reset functionality for GFX queues. The changes include:

    1. Added detection of active VMIDs by reading CP_CNTX_STAT and CP_VMID
       registers to properly identify contexts that need resetting

    2. Implemented fallback to HPD status method when no active VMIDs are
       found, checking both pipe 0 and pipe 1 queues

    3. Extended the MES reset packet with:
       - active_vmids bitmap
       - connected_queue_index for pipe 0
       - connected_queue_index_p1 for pipe 1

Suggested-by: Chau Kyle-haiChau <kyle-hai.c...@amd.com>
Signed-off-by: Jesse Zhang <jesse.zh...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 50 ++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
index 6b222630f3fa..273c2f68050a 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -840,6 +840,12 @@ static int mes_v12_0_reset_hw_queue(struct amdgpu_mes *mes,
                                    struct mes_reset_queue_input *input)
 {
        union MESAPI__RESET mes_reset_queue_pkt;
+       struct amdgpu_device *adev = mes->adev;
+       uint32_t active_vmids = 0;
+       uint32_t connected_queue_index = 0;
+       uint32_t queue_status = 0;
+       uint32_t connected_queue_index_p1 = 0;
+       uint32_t queue_status_p1 = 0;
        int pipe;
 
        if (input->use_mmio)
@@ -855,6 +861,50 @@ static int mes_v12_0_reset_hw_queue(struct amdgpu_mes *mes,
 
        mes_reset_queue_pkt.queue_type =
                convert_to_mes_queue_type(input->queue_type);
+       /* Add VMID detection for GFX queues */
+       if (input->queue_type == AMDGPU_RING_TYPE_GFX) {
+               uint32_t cp_cntx_stat = RREG32_SOC15(GC, 0, regCP_CNTX_STAT);
+               uint32_t cp_vmid, grbm_gfx_cntl;
+
+               /* Check active contexts in CP_CNTX_STAT */
+               for (uint32_t i = 0; i < 8; i++) {
+                       if ((cp_cntx_stat >> (0x14 + i)) & 0x1) {
+                               grbm_gfx_cntl = (i << 11);
+                               WREG32_SOC15(GC, 0, regGRBM_GFX_CNTL, 
grbm_gfx_cntl);
+                               cp_vmid = RREG32_SOC15(GC, 0, regCP_CP_VMID);
+                               active_vmids |= (1 << cp_vmid);
+                       }
+               }
+
+               /* Fallback to HPD status if no active VMIDs found */
+               if (active_vmids == 0) {
+                       uint32_t hpd_status;
+
+                       /* Pipe 0 */
+                       WREG32_SOC15(GC, 0, regGRBM_GFX_CNTL, 0);
+                       hpd_status = RREG32_SOC15(GC, 0, regCP_GFX_HPD_STATUS0);
+                       queue_status = hpd_status & 0x1F;
+                       connected_queue_index = (hpd_status & 0xE0) >> 5;
+
+                       /* Pipe 1 */
+                       WREG32_SOC15(GC, 0, regGRBM_GFX_CNTL, (1 << 6));
+                       hpd_status = RREG32_SOC15(GC, 0, regCP_GFX_HPD_STATUS0);
+                       queue_status_p1 = hpd_status & 0x1F;
+                       connected_queue_index_p1 = (hpd_status & 0xE0) >> 5;
+               }
+
+               mes_reset_queue_pkt.active_vmids = active_vmids;
+               if (active_vmids == 0) {
+                       if (queue_status != 0) {
+                               mes_reset_queue_pkt.use_connected_queue_index = 
1;
+                               mes_reset_queue_pkt.connected_queue_index = 
connected_queue_index;
+                       }
+                       if (queue_status_p1 != 0) {
+                               
mes_reset_queue_pkt.use_connected_queue_index_p1 = 1;
+                               mes_reset_queue_pkt.connected_queue_index_p1 = 
connected_queue_index_p1;
+                       }
+               }
+       }
 
        if (input->legacy_gfx) {
                mes_reset_queue_pkt.reset_legacy_gfx = 1;
-- 
2.49.0

Reply via email to