Setup the MES_API_QUERY_MES__GET_CTX_ARRAY_SIZE MES firmware
command request, and get the MES11 process/gang contex size.

Signed-off-by: Prike Liang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        | 79 +++++++++++++++++++
 drivers/gpu/drm/amd/include/mes_v11_api_def.h | 61 ++++++++++++--
 2 files changed, 132 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
index c721a90051e9..195dc3b4058d 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
@@ -832,6 +832,58 @@ static int mes_v11_0_query_sched_status(struct amdgpu_mes 
*mes)
                        offsetof(union MESAPI__QUERY_MES_STATUS, api_status));
 }
 
+/**
+ * QUERY_SCHEDULER_STATUS: get proc/gang context array sizes
+ */
+static int mes_v11_0_query_ctx_array_sizes(struct amdgpu_mes *mes)
+{
+       struct amdgpu_device *adev = mes->adev;;
+       union MESAPI__QUERY_MES_STATUS mes_query_pkt;
+       int r;
+
+       if (!mes->ctx_array_size_cpu_ptr)
+               return -EINVAL;
+
+       /* Clear the output buffer */
+       mes->ctx_array_size_cpu_ptr[0] = 0;  /* proc_ctx_array_size */
+       mes->ctx_array_size_cpu_ptr[1] = 0;  /* gang_ctx_array_size */
+
+       memset(&mes_query_pkt, 0, sizeof(mes_query_pkt));
+
+       mes_query_pkt.header.type = MES_API_TYPE_SCHEDULER;
+       mes_query_pkt.header.opcode = MES_SCH_API_QUERY_SCHEDULER_STATUS;
+       mes_query_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
+
+       mes_query_pkt.subopcode = MES_API_QUERY_MES__GET_CTX_ARRAY_SIZE;
+
+       /*
+        * MES FW will write the array sizes to these GPU addresses:
+        *   proc_ctx_array_size_addr -> uint32_t N (e.g., 50)
+        *   gang_ctx_array_size_addr -> uint32_t M (e.g., 300)
+        */
+       mes_query_pkt.ctx_array_size.proc_ctx_array_size_addr =
+               mes->ctx_array_size_gpu_addr;
+       mes_query_pkt.ctx_array_size.gang_ctx_array_size_addr =
+               mes->ctx_array_size_gpu_addr + sizeof(uint32_t);
+
+       mes_query_pkt.api_status.api_completion_fence_addr =
+               mes->ring[0].fence_drv.gpu_addr;
+       mes_query_pkt.api_status.api_completion_fence_value =
+               ++mes->ring[0].fence_drv.sync_seq;
+
+       r = mes_v11_0_submit_pkt_and_poll_completion(mes,
+                       &mes_query_pkt, sizeof(mes_query_pkt),
+                       offsetof(union MESAPI__QUERY_MES_STATUS, api_status));
+       if (r) {
+               dev_err(adev->dev,
+                       "MES QUERY_SCHEDULER_STATUS (GET_CTX_ARRAY_SIZE) 
failed, r=%d\n", r);
+               return r;
+       }
+
+       /* MES has written the sizes - now set up bitmaps */
+       return amdgpu_mes_rs64mem_setup_bitmaps(mes);
+}
+
 static int mes_v11_0_misc_op(struct amdgpu_mes *mes,
                             struct mes_misc_op_input *input)
 {
@@ -1907,10 +1959,33 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block 
*ip_block)
        if (r)
                goto failure;
 
+       /* Allocate GPU buffer for array size query results */
+       r = amdgpu_mes_rs64mem_init(&adev->mes);
+       if (r)
+               dev_warn(adev->dev,
+                        "RS64 local memory init failed (%d), "
+                        "falling back to system memory path\n", r);
+
        r = mes_v11_0_set_hw_resources(&adev->mes);
+
        if (r)
                goto failure;
 
+       /*
+        * QUERY_SCHEDULER_STATUS to get array sizes (N, M).
+        * MES writes the sizes to the GPU buffer, then we allocate bitmaps.
+        */
+       if (adev->mes.use_rs64mem) {
+               r = mes_v11_0_query_ctx_array_sizes(&adev->mes);
+               if (r) {
+                       dev_warn(adev->dev,
+                                "Failed to query ctx array sizes (%d), "
+                                "disabling RS64 local memory\n", r);
+                       /* Continue without optimization - not fatal */
+               }
+       }
+
+
        if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x52) {
                r = mes_v11_0_set_hw_resources_1(&adev->mes);
                if (r) {
@@ -1948,6 +2023,10 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block 
*ip_block)
 
 static int mes_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
 {
+       struct amdgpu_device *adev = ip_block->adev;
+
+       if (adev->mes.use_rs64mem)
+               amdgpu_mes_rs64mem_fini(&adev->mes);
        return 0;
 }
 
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 b06412ac8583..dfc27be4454d 100644
--- a/drivers/gpu/drm/amd/include/mes_v11_api_def.h
+++ b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
@@ -329,6 +329,7 @@ union MESAPI__ADD_QUEUE {
                uint32_t                    pipe_id;
                uint32_t                    queue_id;
                uint32_t                    alignment_mode_setting;
+               uint32_t                    full_sh_mem_config_data;
                uint64_t                    unmap_flag_addr;
        };
 
@@ -358,6 +359,7 @@ union MESAPI__REMOVE_QUEUE {
                uint32_t                    tf_data;
 
                enum MES_QUEUE_TYPE         queue_type;
+               uint64_t                    timestamp;
        };
 
        uint32_t        max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
@@ -516,14 +518,57 @@ union MESAPI__SET_LOGGING_BUFFER {
        uint32_t        max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
 };
 
-union MESAPI__QUERY_MES_STATUS {
-       struct {
-               union MES_API_HEADER    header;
-               bool                    mes_healthy; /* 0 - not healthy, 1 - 
healthy */
-               struct MES_API_STATUS   api_status;
-       };
-
-       uint32_t        max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
+enum MES_API_QUERY_MES_OPCODE
+{
+    MES_API_QUERY_MES__GET_CTX_ARRAY_SIZE,
+    MES_API_QUERY_MES__GET_CAPS = MES_API_QUERY_MES__GET_CTX_ARRAY_SIZE,
+    MES_API_QUERY_MES__CHECK_HEALTHY,
+    MES_API_QUERY_MES__MAX,
+};
+
+enum { QUERY_MES_MAX_SIZE_IN_DWORDS = 20 };
+
+/**
+ * Obsolete
+ * to be removed once KMD stopped refering to it.
+ * use MES_API_QUERY_MES__CAPS instead
+*/
+struct MES_API_QUERY_MES__CTX_ARRAY_SIZE
+{
+    uint64_t    proc_ctx_array_size_addr;
+    uint64_t    gang_ctx_array_size_addr;
+};
+
+struct MES_API_QUERY_MES__HEALTHY_CHECK
+{
+    uint64_t    healthy_addr;
+};
+
+struct MES_API_QUERY_MES__CAPS
+{
+    uint64_t    proc_ctx_array_size_addr;
+    uint64_t    gang_ctx_array_size_addr;
+    uint64_t    features_enablement_addr;
+};
+
+union MESAPI__QUERY_MES_STATUS
+{
+    struct
+    {
+        union MES_API_HEADER            header;
+        enum MES_API_QUERY_MES_OPCODE   subopcode;
+        struct MES_API_STATUS           api_status;
+        uint64_t                        timestamp;
+        union
+        {
+            struct MES_API_QUERY_MES__CTX_ARRAY_SIZE    ctx_array_size;
+            struct MES_API_QUERY_MES__CAPS              caps;
+            struct MES_API_QUERY_MES__HEALTHY_CHECK     healthy_check;
+            uint32_t data[QUERY_MES_MAX_SIZE_IN_DWORDS];
+        };
+    };
+
+    uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
 };
 
 union MESAPI__PROGRAM_GDS {
-- 
2.34.1

Reply via email to