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
