drm/amd/amdgpu: support MES command SET_HW_RESOURCE1 in sriov
authorchongli2 <chongli2@amd.com>
Tue, 26 Mar 2024 05:24:21 +0000 (13:24 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 10 Apr 2024 02:08:53 +0000 (22:08 -0400)
support MES command SET_HW_RESOURCE1 in sriov

Signed-off-by: chongli2 <chongli2@amd.com>
Reviewed-by: Jingwen Chen <Jingwen.Chen2@amd.com>
Acked-by: Jingwen Chen <Jingwen.Chen2@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
drivers/gpu/drm/amd/include/mes_v11_api_def.h

index 4c8fc3117ef8948627ef6a83cb7f603de2991662..6b3e1844eac58752f9cbdec812175a60c7abf713 100644 (file)
@@ -141,6 +141,12 @@ struct amdgpu_mes {
 
        /* ip specific functions */
        const struct amdgpu_mes_funcs   *funcs;
+
+       /* mes resource_1 bo*/
+       struct amdgpu_bo    *resource_1;
+       uint64_t            resource_1_gpu_addr;
+       void                *resource_1_addr;
+
 };
 
 struct amdgpu_mes_process {
index 6f01de220c44c96b640a115e3ba99954f2eaddb5..461753904dea55a6466beeee02be31bafb7e40cd 100644 (file)
@@ -576,6 +576,11 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev)
        vf2pf_info->decode_usage = 0;
 
        vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr;
+       vf2pf_info->mes_info_addr = (uint64_t)adev->mes.resource_1_gpu_addr;
+
+       if (adev->mes.resource_1) {
+               vf2pf_info->mes_info_size = adev->mes.resource_1->tbo.base.size;
+       }
        vf2pf_info->checksum =
                amd_sriov_msg_checksum(
                vf2pf_info, vf2pf_info->header.size, 0, 0);
index a858bc98cad4ff1b7b4860032797a3ebe209015c..a9f2f0c4f79917363188fb658b8f0063d49d08ba 100644 (file)
@@ -132,6 +132,8 @@ enum AMDGIM_FEATURE_FLAG {
        AMDGIM_FEATURE_AV1_SUPPORT = (1 << 6),
        /* VCN RB decouple */
        AMDGIM_FEATURE_VCN_RB_DECOUPLE = (1 << 7),
+       /* MES info */
+       AMDGIM_FEATURE_MES_INFO_ENABLE = (1 << 8),
 };
 
 enum AMDGIM_REG_ACCESS_FLAG {
@@ -335,6 +337,8 @@ static inline bool is_virtual_machine(void)
        ((adev)->virt.gim_feature & AMDGIM_FEATURE_AV1_SUPPORT)
 #define amdgpu_sriov_is_vcn_rb_decouple(adev) \
        ((adev)->virt.gim_feature & AMDGIM_FEATURE_VCN_RB_DECOUPLE)
+#define amdgpu_sriov_is_mes_info_enable(adev) \
+       ((adev)->virt.gim_feature & AMDGIM_FEATURE_MES_INFO_ENABLE)
 bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
 void amdgpu_virt_init_setting(struct amdgpu_device *adev);
 int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
index 51a14f6d93bd8af39c9094bfce0e7e100680fe82..0de78d6a83fe2c39698343a0fb7bb2cac38783c1 100644 (file)
@@ -94,7 +94,8 @@ union amd_sriov_msg_feature_flags {
                uint32_t reg_indirect_acc  : 1;
                uint32_t av1_support       : 1;
                uint32_t vcn_rb_decouple   : 1;
-               uint32_t reserved          : 24;
+               uint32_t mes_info_enable   : 1;
+               uint32_t reserved          : 23;
        } flags;
        uint32_t all;
 };
@@ -221,7 +222,7 @@ struct amd_sriov_msg_vf2pf_info_header {
        uint32_t reserved[2];
 };
 
-#define AMD_SRIOV_MSG_VF2PF_INFO_FILLED_SIZE (70)
+#define AMD_SRIOV_MSG_VF2PF_INFO_FILLED_SIZE (73)
 struct amd_sriov_msg_vf2pf_info {
        /* header contains size and version */
        struct amd_sriov_msg_vf2pf_info_header header;
@@ -265,7 +266,9 @@ struct amd_sriov_msg_vf2pf_info {
                uint32_t version;
        } ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE];
        uint64_t dummy_page_addr;
-
+       /* FB allocated for guest MES to record UQ info */
+       uint64_t mes_info_addr;
+       uint32_t mes_info_size;
        /* reserved */
        uint32_t reserved[256 - AMD_SRIOV_MSG_VF2PF_INFO_FILLED_SIZE];
 };
index 63f281a9984d986961d70511c83b6e65272979b7..e5230078a4cdd3cdbad4c6f98f100ee1e94cff60 100644 (file)
@@ -422,6 +422,36 @@ static int mes_v11_0_set_hw_resources(struct amdgpu_mes *mes)
                        offsetof(union MESAPI_SET_HW_RESOURCES, api_status));
 }
 
+static int mes_v11_0_set_hw_resources_1(struct amdgpu_mes *mes)
+{
+       int size = 128 * PAGE_SIZE;
+       int ret = 0;
+       struct amdgpu_device *adev = mes->adev;
+       union MESAPI_SET_HW_RESOURCES_1 mes_set_hw_res_pkt;
+       memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt));
+
+       mes_set_hw_res_pkt.header.type = MES_API_TYPE_SCHEDULER;
+       mes_set_hw_res_pkt.header.opcode = MES_SCH_API_SET_HW_RSRC_1;
+       mes_set_hw_res_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
+       mes_set_hw_res_pkt.enable_mes_info_ctx = 1;
+
+       ret = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
+                               AMDGPU_GEM_DOMAIN_VRAM,
+                               &mes->resource_1,
+                               &mes->resource_1_gpu_addr,
+                               &mes->resource_1_addr);
+       if (ret) {
+               dev_err(adev->dev, "(%d) failed to create mes resource_1 bo\n", ret);
+               return ret;
+       }
+
+       mes_set_hw_res_pkt.mes_info_ctx_mc_addr = mes->resource_1_gpu_addr;
+       mes_set_hw_res_pkt.mes_info_ctx_size = mes->resource_1->tbo.base.size;
+       return mes_v11_0_submit_pkt_and_poll_completion(mes,
+                       &mes_set_hw_res_pkt, sizeof(mes_set_hw_res_pkt),
+                       offsetof(union MESAPI_SET_HW_RESOURCES_1, api_status));
+}
+
 static const struct amdgpu_mes_funcs mes_v11_0_funcs = {
        .add_hw_queue = mes_v11_0_add_hw_queue,
        .remove_hw_queue = mes_v11_0_remove_hw_queue,
@@ -1203,6 +1233,14 @@ static int mes_v11_0_hw_init(void *handle)
        if (r)
                goto failure;
 
+       if (amdgpu_sriov_is_mes_info_enable(adev)) {
+               r = mes_v11_0_set_hw_resources_1(&adev->mes);
+               if (r) {
+                       DRM_ERROR("failed mes_v11_0_set_hw_resources_1, r=%d\n", r);
+                       goto failure;
+               }
+       }
+
        r = mes_v11_0_query_sched_status(&adev->mes);
        if (r) {
                DRM_ERROR("MES is busy\n");
@@ -1226,6 +1264,11 @@ failure:
 
 static int mes_v11_0_hw_fini(void *handle)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       if (amdgpu_sriov_is_mes_info_enable(adev)) {
+               amdgpu_bo_free_kernel(&adev->mes.resource_1, &adev->mes.resource_1_gpu_addr,
+                                       &adev->mes.resource_1_addr);
+       }
        return 0;
 }
 
index ec5b9ab67c5e446ed4fe6cff474d206930bfb276..410c8d6643368d3b412dc49a9bf5a705f002c24c 100644 (file)
@@ -61,6 +61,7 @@ enum MES_SCH_API_OPCODE {
        MES_SCH_API_MISC                        = 14,
        MES_SCH_API_UPDATE_ROOT_PAGE_TABLE      = 15,
        MES_SCH_API_AMD_LOG                     = 16,
+       MES_SCH_API_SET_HW_RSRC_1               = 19,
        MES_SCH_API_MAX                         = 0xFF
 };
 
@@ -238,6 +239,26 @@ union MESAPI_SET_HW_RESOURCES {
        uint32_t        max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
 };
 
+union MESAPI_SET_HW_RESOURCES_1 {
+       struct {
+               union MES_API_HEADER                            header;
+               struct MES_API_STATUS                      api_status;
+               uint64_t                                                        timestamp;
+               union {
+                       struct {
+                               uint32_t enable_mes_info_ctx : 1;
+                               uint32_t reserved : 31;
+                       };
+                       uint32_t uint32_all;
+               };
+               uint64_t                                                        mes_info_ctx_mc_addr;
+               uint32_t                                                        mes_info_ctx_size;
+               uint32_t                                                        mes_kiq_unmap_timeout; // unit is 100ms
+       };
+
+       uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
+};
+
 union MESAPI__ADD_QUEUE {
        struct {
                union MES_API_HEADER            header;