Implement the MES gang contex alloc and free heplers.

Signed-off-by: Prike Liang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c       | 41 +++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h       |  7 ++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h     |  1 +
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c    |  7 +++-
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        |  2 +
 drivers/gpu/drm/amd/include/mes_v11_api_def.h |  1 +
 6 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index db9c46ece2a0..56671f98b052 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -1081,6 +1081,47 @@ void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes 
*mes,
        amdgpu_mes_unlock(mes);
 }
 
+/**
+ * amdgpu_mes_alloc_gang_ctx_index - allocate a gang context slot
+ */
+int amdgpu_mes_alloc_gang_ctx_index(struct amdgpu_mes *mes,
+                                   struct amdgpu_usermode_queue *queue)
+{
+       unsigned long bit;
+
+       if (!mes->use_rs64mem || !mes->gang_ctx_bitmap)
+               return -EOPNOTSUPP;
+
+       amdgpu_mes_lock(mes);
+       bit = find_first_zero_bit(mes->gang_ctx_bitmap,
+                                 mes->gang_ctx_array_size);
+       if (bit >= mes->gang_ctx_array_size) {
+               amdgpu_mes_unlock(mes);
+               return -ENOSPC;
+       }
+       set_bit(bit, mes->gang_ctx_bitmap);
+       queue->gang_ctx_array_index = bit;
+       amdgpu_mes_unlock(mes);
+
+       return 0;
+}
+
+/**
+ * amdgpu_mes_free_gang_ctx_index - free a gang context slot
+ */
+void amdgpu_mes_free_gang_ctx_index(struct amdgpu_mes *mes,
+                                   struct amdgpu_usermode_queue *queue)
+{
+       if (!mes->use_rs64mem || !mes->gang_ctx_bitmap)
+               return;
+       if (queue->gang_ctx_array_index >= mes->gang_ctx_array_size)
+               return;
+
+       amdgpu_mes_lock(mes);
+       clear_bit(queue->gang_ctx_array_index, mes->gang_ctx_bitmap);
+       amdgpu_mes_unlock(mes);
+}
+
 #if defined(CONFIG_DEBUG_FS)
 
 static int amdgpu_debugfs_mes_event_log_show(struct seq_file *m, void *unused)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index 33a426f58e72..c67db2d6e122 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -181,6 +181,7 @@ struct amdgpu_mes {
        uint32_t                        proc_ctx_array_size;
        unsigned long                   *proc_ctx_bitmap;
        uint32_t                        gang_ctx_array_size;
+       uint32_t                        gang_ctx_array_index;
        unsigned long                   *gang_ctx_bitmap;
 };
 
@@ -280,6 +281,7 @@ struct mes_add_queue_input {
        uint32_t        sh_mem_config_data;
        uint32_t        vm_cntx_cntl;
        uint32_t        process_context_array_index;
+       uint32_t        gang_context_array_index;
 };
 
 struct mes_remove_queue_input {
@@ -288,6 +290,7 @@ struct mes_remove_queue_input {
        uint64_t        gang_context_addr;
        uint32_t        queue_type;
        bool            remove_queue_after_reset;
+       uint32_t        gang_context_array_index;
 };
 
 struct mes_map_legacy_queue_input {
@@ -636,4 +639,8 @@ int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes *mes,
                                    struct amdgpu_usermode_queue *queue);
 void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes *mes,
                                    struct amdgpu_usermode_queue *queue);
+int amdgpu_mes_alloc_gang_ctx_index(struct amdgpu_mes *mes,
+                                   struct amdgpu_usermode_queue *queue);
+void amdgpu_mes_free_gang_ctx_index(struct amdgpu_mes *mes,
+                                   struct amdgpu_usermode_queue *queue);
 #endif /* __AMDGPU_MES_H__ */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
index 8bb0d3213abf..8333bab537d4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
@@ -102,6 +102,7 @@ struct amdgpu_usermode_queue {
        } userq_vas;
 
        uint32_t        proc_ctx_array_index;
+       uint32_t        gang_ctx_array_index;
 };
 
 struct amdgpu_userq_funcs {
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index e1ff0f22a6e1..0dc10553dcef 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -150,6 +150,8 @@ static int mes_userq_map(struct amdgpu_usermode_queue 
*queue)
        if (mes->use_rs64mem) {
                amdgpu_mes_alloc_proc_ctx_index(mes, queue);
                queue_input.process_context_array_index = 
queue->proc_ctx_array_index;
+               amdgpu_mes_alloc_gang_ctx_index(mes, queue);
+               queue_input.gang_context_array_index = 
queue->gang_ctx_array_index;
        }
        amdgpu_mes_lock(&adev->mes);
        r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
@@ -173,6 +175,7 @@ static int mes_userq_unmap(struct amdgpu_usermode_queue 
*queue)
        int r;
 
        memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
+       queue_input.gang_context_array_index = queue->gang_ctx_array_index;
        queue_input.doorbell_offset = queue->doorbell_index;
        queue_input.gang_context_addr = ctx->gpu_addr;
        queue_input.queue_type = queue->queue_type;
@@ -180,8 +183,10 @@ static int mes_userq_unmap(struct amdgpu_usermode_queue 
*queue)
        amdgpu_mes_lock(&adev->mes);
        r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
        amdgpu_mes_unlock(&adev->mes);
-       if (mes->use_rs64mem)
+       if (mes->use_rs64mem) {
                amdgpu_mes_free_proc_ctx_index(mes, queue);
+               amdgpu_mes_free_gang_ctx_index(mes, queue);
+       }
        if (r)
                DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
        return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
index db09f63ec1ad..c2129ea6614b 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
@@ -338,6 +338,7 @@ static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes,
        mes_add_queue_pkt.process_context_array_index = 
input->process_context_array_index;
        mes_add_queue_pkt.gang_quantum = input->gang_quantum;
        mes_add_queue_pkt.gang_context_addr = input->gang_context_addr;
+       mes_add_queue_pkt.gang_context_array_index = 
input->gang_context_array_index;
        mes_add_queue_pkt.inprocess_gang_priority =
                convert_to_mes_priority_level(input->inprocess_gang_priority);
        mes_add_queue_pkt.gang_global_priority_level =
@@ -388,6 +389,7 @@ static int mes_v11_0_remove_hw_queue(struct amdgpu_mes *mes,
 
        mes_remove_queue_pkt.doorbell_offset = input->doorbell_offset;
        mes_remove_queue_pkt.gang_context_addr = input->gang_context_addr;
+       mes_remove_queue_pkt.gang_context_array_index = 
input->gang_context_array_index;
        mes_remove_queue_pkt.queue_type =
                convert_to_mes_queue_type(input->queue_type);
 
diff --git a/drivers/gpu/drm/amd/include/mes_v11_api_def.h 
b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
index dfc27be4454d..04005a03987a 100644
--- a/drivers/gpu/drm/amd/include/mes_v11_api_def.h
+++ b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
@@ -360,6 +360,7 @@ union MESAPI__REMOVE_QUEUE {
 
                enum MES_QUEUE_TYPE         queue_type;
                uint64_t                    timestamp;
+               uint32_t                    gang_context_array_index;
        };
 
        uint32_t        max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
-- 
2.34.1

Reply via email to