drm/amdgpu: add init microcode function for psp v10
authorJunwei Zhang <Jerry.Zhang@amd.com>
Fri, 14 Jul 2017 10:31:18 +0000 (18:31 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 25 Jul 2017 20:25:57 +0000 (16:25 -0400)
Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
drivers/gpu/drm/amd/amdgpu/psp_v10_0.h

index 5346f29..43327b8 100644 (file)
@@ -63,6 +63,7 @@ static int psp_sw_init(void *handle)
                psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk;
                break;
        case CHIP_RAVEN:
+               psp->init_microcode = psp_v10_0_init_microcode;
                psp->prep_cmd_buf = psp_v10_0_prep_cmd_buf;
                psp->ring_init = psp_v10_0_ring_init;
                psp->cmd_submit = psp_v10_0_cmd_submit;
index 9a7b94d..133b030 100644 (file)
@@ -86,6 +86,52 @@ psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *
        return 0;
 }
 
+int psp_v10_0_init_microcode(struct psp_context *psp)
+{
+       struct amdgpu_device *adev = psp->adev;
+       const char *chip_name;
+       char fw_name[30];
+       int err = 0;
+       const struct psp_firmware_header_v1_0 *hdr;
+
+       DRM_DEBUG("\n");
+
+       switch (adev->asic_type) {
+       case CHIP_RAVEN:
+               chip_name = "raven";
+               break;
+       default: BUG();
+       }
+
+       snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
+       err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
+       if (err)
+               goto out;
+
+       err = amdgpu_ucode_validate(adev->psp.asd_fw);
+       if (err)
+               goto out;
+
+       hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
+       adev->psp.asd_fw_version = le32_to_cpu(hdr->header.ucode_version);
+       adev->psp.asd_feature_version = le32_to_cpu(hdr->ucode_feature_version);
+       adev->psp.asd_ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
+       adev->psp.asd_start_addr = (uint8_t *)hdr +
+                               le32_to_cpu(hdr->header.ucode_array_offset_bytes);
+
+       return 0;
+out:
+       if (err) {
+               dev_err(adev->dev,
+                       "psp v10.0: Failed to load firmware \"%s\"\n",
+                       fw_name);
+               release_firmware(adev->psp.asd_fw);
+               adev->psp.asd_fw = NULL;
+       }
+
+       return err;
+}
+
 int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cmd_resp *cmd)
 {
        int ret;
index 2022b7b..2f5a314 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "amdgpu_psp.h"
 
+extern int psp_v10_0_init_microcode(struct psp_context *psp);
 extern int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode,
                                 struct psp_gfx_cmd_resp *cmd);
 extern int psp_v10_0_ring_init(struct psp_context *psp,