OSDN Git Service

drm/amdgpu: add CAP fw loading
authorZhigang Luo <zhigang.luo@amd.com>
Wed, 26 Feb 2020 15:30:13 +0000 (10:30 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 19 Mar 2020 04:03:05 +0000 (00:03 -0400)
The CAP fw is for enabling driver compatibility. Currently, it only
enabled for vega10 VF.

Signed-off-by: Zhigang Luo <zhigang.luo@amd.com>
Reviewed-by: Shaoyun Liu <Shaoyun.Liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
drivers/gpu/drm/amd/amdgpu/psp_v3_1.c

index be50867..dc42086 100644 (file)
@@ -159,6 +159,10 @@ static int psp_sw_fini(void *handle)
        adev->psp.sos_fw = NULL;
        release_firmware(adev->psp.asd_fw);
        adev->psp.asd_fw = NULL;
+       if (adev->psp.cap_fw) {
+               release_firmware(adev->psp.cap_fw);
+               adev->psp.cap_fw = NULL;
+       }
        if (adev->psp.ta_fw) {
                release_firmware(adev->psp.ta_fw);
                adev->psp.ta_fw = NULL;
@@ -246,7 +250,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
                DRM_WARN("psp command (0x%X) failed and response status is (0x%X)\n",
                         psp->cmd_buf_mem->cmd_id,
                         psp->cmd_buf_mem->resp.status);
-               if (!timeout) {
+               if ((ucode->ucode_id == AMDGPU_UCODE_ID_CAP) || !timeout) {
                        mutex_unlock(&psp->mutex);
                        return -EINVAL;
                }
@@ -1188,6 +1192,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
                           enum psp_gfx_fw_type *type)
 {
        switch (ucode->ucode_id) {
+       case AMDGPU_UCODE_ID_CAP:
+               *type = GFX_FW_TYPE_CAP;
+               break;
        case AMDGPU_UCODE_ID_SDMA0:
                *type = GFX_FW_TYPE_SDMA0;
                break;
index 297435c..4a4d8f2 100644 (file)
@@ -252,6 +252,9 @@ struct psp_context
        uint32_t                        asd_ucode_size;
        uint8_t                         *asd_start_addr;
 
+       /* cap firmware */
+       const struct firmware           *cap_fw;
+
        /* fence buffer */
        struct amdgpu_bo                *fence_buf_bo;
        uint64_t                        fence_buf_mc_addr;
index b0e6564..88f2260 100644 (file)
@@ -283,7 +283,8 @@ union amdgpu_firmware_header {
  * fw loading support
  */
 enum AMDGPU_UCODE_ID {
-       AMDGPU_UCODE_ID_SDMA0 = 0,
+       AMDGPU_UCODE_ID_CAP = 0, /* CAP must be the 1st fw to be loaded */
+       AMDGPU_UCODE_ID_SDMA0,
        AMDGPU_UCODE_ID_SDMA1,
        AMDGPU_UCODE_ID_SDMA2,
        AMDGPU_UCODE_ID_SDMA3,
index a44fd60..6ff9a95 100644 (file)
@@ -246,6 +246,7 @@ enum psp_gfx_fw_type {
        GFX_FW_TYPE_SDMA6                           = 56,   /* SDMA6                    MI      */
        GFX_FW_TYPE_SDMA7                           = 57,   /* SDMA7                    MI      */
        GFX_FW_TYPE_VCN1                            = 58,   /* VCN1                     MI      */
+       GFX_FW_TYPE_CAP                             = 62,   /* CAP_FW                   VG      */
        GFX_FW_TYPE_MAX
 };
 
index 735c43c..43896f4 100644 (file)
@@ -44,6 +44,7 @@
 
 MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
 MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
+MODULE_FIRMWARE("amdgpu/vega10_cap.bin");
 MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
 MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
 
@@ -63,6 +64,7 @@ static int psp_v3_1_init_microcode(struct psp_context *psp)
        char fw_name[30];
        int err = 0;
        const struct psp_firmware_header_v1_0 *hdr;
+       struct amdgpu_firmware_info *info = NULL;
 
        DRM_DEBUG("\n");
 
@@ -112,6 +114,26 @@ static int psp_v3_1_init_microcode(struct psp_context *psp)
        adev->psp.asd_start_addr = (uint8_t *)hdr +
                                le32_to_cpu(hdr->header.ucode_array_offset_bytes);
 
+       if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_VEGA10) {
+               snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_cap.bin",
+                        chip_name);
+               err = request_firmware(&adev->psp.cap_fw, fw_name, adev->dev);
+               if (err)
+                       goto out;
+
+               err = amdgpu_ucode_validate(adev->psp.cap_fw);
+               if (err)
+                       goto out;
+
+               info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CAP];
+               info->ucode_id = AMDGPU_UCODE_ID_CAP;
+               info->fw = adev->psp.cap_fw;
+               hdr = (const struct psp_firmware_header_v1_0 *)
+                             adev->psp.cap_fw->data;
+               adev->firmware.fw_size += ALIGN(
+                       le32_to_cpu(hdr->header.ucode_size_bytes), PAGE_SIZE);
+       }
+
        return 0;
 out:
        if (err) {
@@ -122,6 +144,8 @@ out:
                adev->psp.sos_fw = NULL;
                release_firmware(adev->psp.asd_fw);
                adev->psp.asd_fw = NULL;
+               release_firmware(adev->psp.cap_fw);
+               adev->psp.cap_fw = NULL;
        }
 
        return err;