Skip to content

Commit

Permalink
drm/amdgpu: add CAP fw loading
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Zhigang Luo authored and Alex Deucher committed Mar 19, 2020
1 parent 8e02561 commit 29e2501
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 2 deletions.
9 changes: 8 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down
24 changes: 24 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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");

Expand Down Expand Up @@ -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) {
Expand All @@ -122,6 +144,8 @@ static int psp_v3_1_init_microcode(struct psp_context *psp)
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;
Expand Down

0 comments on commit 29e2501

Please sign in to comment.