Blob Blame History Raw
From 123c78cf7f2223337ba368c49eea6132bd698f8b Mon Sep 17 00:00:00 2001
From: Zhigang Luo <zhigang.luo@amd.com>
Date: Wed, 26 Feb 2020 10:30:13 -0500
Subject: drm/amdgpu: add CAP fw loading
Git-commit: 29e2501f8a64fa2fa8f6fe4be53cce5a5a4fe79f
Patch-mainline: v5.7-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322

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>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 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     | 24 +++++++++++++++++++++++
 5 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index be50867ea644..dc42086a672b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -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;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 297435c0c7c1..4a4d8f2ccca2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -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;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
index b0e656409c03..88f226070229 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
@@ -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,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
index a44fd6060d5b..6ff9a9544110 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
+++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
@@ -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
 };
 
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
index 735c43c7daab..43896f4779b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
@@ -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 @@ 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;
-- 
2.28.0