[PATCH] drm/amdgpu: add CAP fw loading
Zhigang Luo
zhigang.luo at amd.com
Wed Feb 26 19:35:13 UTC 2020
The CAP fw is for enabling driver compatibility. Currently, it only
enabled for vega10 VF.
Signed-off-by: Zhigang Luo <zhigang.luo at amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 9 +++++++-
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 3 +++
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 3 ++-
drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h | 1 +
drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | 26 +++++++++++++++++++++++
5 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 0c88837bb890..6ebc04c95927 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -93,6 +93,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;
@@ -162,7 +166,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
ucode->ucode_id);
DRM_WARN("psp command failed and response status is (%d)\n",
psp->cmd_buf_mem->resp.status);
- if (!timeout)
+ if ((ucode->ucode_id == AMDGPU_UCODE_ID_CAP) || !timeout)
return -EINVAL;
}
@@ -841,6 +845,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;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 80bbfecc815d..b51901626798 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -184,6 +184,9 @@ struct psp_context
uint64_t asd_shared_mc_addr;
void *asd_shared_buf;
+ /* cap firmware */
+ const struct firmware *cap_fw;
+
/* fence buffer */
struct amdgpu_bo *fence_buf_bo;
uint64_t fence_buf_mc_addr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
index c1fb6dc86440..82e13fa43e28 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
@@ -260,7 +260,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_CP_CE,
AMDGPU_UCODE_ID_CP_PFP,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
index 5080a73a95a5..2651d9164007 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
+++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
@@ -235,6 +235,7 @@ enum psp_gfx_fw_type {
GFX_FW_TYPE_RLX6_DRAM_BOOT = 48, /* RLX6 DRAM BOOT NV */
GFX_FW_TYPE_VCN0_RAM = 49, /* VCN_RAM NV */
GFX_FW_TYPE_VCN1_RAM = 50, /* VCN_RAM NV */
+ GFX_FW_TYPE_CAP = 62, /* CAP_FW VG */
GFX_FW_TYPE_MAX
};
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
index ec3a05602f11..6ffcc89e9e28 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
@@ -42,6 +42,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");
@@ -61,6 +62,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");
@@ -110,6 +112,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) {
@@ -120,6 +142,10 @@ 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;
+ if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_VEGA10) {
+ release_firmware(adev->psp.cap_fw);
+ adev->psp.cap_fw = NULL;
+ }
}
return err;
--
2.17.1
More information about the amd-gfx
mailing list