[PATCH 029/109] drm/amdgpu: factor PSP v1.0 firmware bin descriptor parsing

Alex Deucher <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Candice Li <[email protected]>

Add parse_psp_v1_bin_descriptor to populate struct psp_bin_desc
from psp_firmware_header_v1_0, shared by ASD, TOC and CAP
standalone firmware loads.

Use psp-> fields directly instead of adev->psp.

v2: code rebase
v3: Rename v1 header helper to parse_psp_v1_bin_descriptor,
    have it return an error code with explicit NULL checks.
    Rename sos v2 helper to parse_psp_v2_bin_descriptor for symmetry.

Signed-off-by: Candice Li <[email protected]>
Reviewed-by: Hawking Zhang <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 93 ++++++++++++++-----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h |  4 +-
 3 files changed, 55 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index ad58d422204e8..f2f179421c4da 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -349,8 +349,8 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
 		fw_info->feature = adev->psp.toc.feature_version;
 		break;
 	case AMDGPU_INFO_FW_CAP:
-		fw_info->ver = adev->psp.cap_fw_version;
-		fw_info->feature = adev->psp.cap_feature_version;
+		fw_info->ver = adev->psp.cap.fw_version;
+		fw_info->feature = adev->psp.cap.feature_version;
 		break;
 	case AMDGPU_INFO_FW_MES_KIQ:
 		fw_info->ver = adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 04f6ebf31cca5..d7d6623b51da6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -3960,58 +3960,72 @@ int psp_ring_cmd_submit(struct psp_context *psp,
 	return 0;
 }
 
+/**
+ * parse_psp_v1_bin_descriptor - Populate struct psp_bin_desc from a
+ * v1.0 PSP firmware header (standalone images such as ASD or TOC).
+ */
+static int parse_psp_v1_bin_descriptor(struct psp_bin_desc *desc,
+					const struct psp_firmware_header_v1_0 *hdr)
+{
+	if (!desc || !hdr)
+		return -EINVAL;
+
+	desc->fw_version = le32_to_cpu(hdr->header.ucode_version);
+	desc->feature_version = le32_to_cpu(hdr->sos.fw_version);
+	desc->size_bytes = le32_to_cpu(hdr->header.ucode_size_bytes);
+	desc->start_addr = (uint8_t *)hdr +
+			   le32_to_cpu(hdr->header.ucode_array_offset_bytes);
+
+	return 0;
+}
+
 int psp_init_asd_microcode(struct psp_context *psp, const char *chip_name)
 {
-	struct amdgpu_device *adev = psp->adev;
-	const struct psp_firmware_header_v1_0 *asd_hdr;
-	int err = 0;
+	int err;
 
-	err = amdgpu_ucode_request(adev, &adev->psp.asd_fw, AMDGPU_UCODE_REQUIRED,
+	err = amdgpu_ucode_request(psp->adev, &psp->asd_fw, AMDGPU_UCODE_REQUIRED,
 				   "amdgpu/%s_asd.bin", chip_name);
 	if (err)
 		goto out;
 
-	asd_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
-	adev->psp.asd_context.bin_desc.fw_version = le32_to_cpu(asd_hdr->header.ucode_version);
-	adev->psp.asd_context.bin_desc.feature_version = le32_to_cpu(asd_hdr->sos.fw_version);
-	adev->psp.asd_context.bin_desc.size_bytes = le32_to_cpu(asd_hdr->header.ucode_size_bytes);
-	adev->psp.asd_context.bin_desc.start_addr = (uint8_t *)asd_hdr +
-				le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes);
+	err = parse_psp_v1_bin_descriptor(&psp->asd_context.bin_desc,
+		    (const struct psp_firmware_header_v1_0 *)psp->asd_fw->data);
+	if (err)
+		goto out;
+
 	return 0;
 out:
-	amdgpu_ucode_release(&adev->psp.asd_fw);
+	amdgpu_ucode_release(&psp->asd_fw);
 	return err;
 }
 
 int psp_init_toc_microcode(struct psp_context *psp, const char *chip_name)
 {
-	struct amdgpu_device *adev = psp->adev;
-	const struct psp_firmware_header_v1_0 *toc_hdr;
-	int err = 0;
+	int err;
 
-	if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 8) &&
-	    adev->rev_id == 0)
-		err = amdgpu_ucode_request(adev, &adev->psp.toc_fw, AMDGPU_UCODE_REQUIRED,
+	if (amdgpu_ip_version(psp->adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 8) &&
+	    psp->adev->rev_id == 0 &&
+	    !amdgpu_emu_mode)
+		err = amdgpu_ucode_request(psp->adev, &psp->toc_fw, AMDGPU_UCODE_REQUIRED,
 				   "amdgpu/%s_toc_1.bin", chip_name);
 	else
-		err = amdgpu_ucode_request(adev, &adev->psp.toc_fw, AMDGPU_UCODE_REQUIRED,
+		err = amdgpu_ucode_request(psp->adev, &psp->toc_fw, AMDGPU_UCODE_REQUIRED,
 				   "amdgpu/%s_toc.bin", chip_name);
 	if (err)
 		goto out;
 
-	toc_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.toc_fw->data;
-	adev->psp.toc.fw_version = le32_to_cpu(toc_hdr->header.ucode_version);
-	adev->psp.toc.feature_version = le32_to_cpu(toc_hdr->sos.fw_version);
-	adev->psp.toc.size_bytes = le32_to_cpu(toc_hdr->header.ucode_size_bytes);
-	adev->psp.toc.start_addr = (uint8_t *)toc_hdr +
-				le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes);
+	err = parse_psp_v1_bin_descriptor(&psp->toc,
+		    (const struct psp_firmware_header_v1_0 *)psp->toc_fw->data);
+	if (err)
+		goto out;
+
 	return 0;
 out:
-	amdgpu_ucode_release(&adev->psp.toc_fw);
+	amdgpu_ucode_release(&psp->toc_fw);
 	return err;
 }
 
-static int parse_sos_bin_descriptor(struct psp_context *psp,
+static int parse_psp_v2_bin_descriptor(struct psp_context *psp,
 				   const struct psp_fw_bin_desc *desc,
 				   const struct psp_firmware_header_v2_0 *sos_hdr)
 {
@@ -4241,7 +4255,7 @@ int psp_init_sos_microcode(struct psp_context *psp, const char *chip_name)
 		}
 
 		for (fw_index = start_index; fw_index < fw_bin_count; fw_index++) {
-			err = parse_sos_bin_descriptor(psp, fw_bin + fw_index,
+			err = parse_psp_v2_bin_descriptor(psp, fw_bin + fw_index,
 						       sos_hdr_v2_0);
 			if (err)
 				goto out;
@@ -4476,16 +4490,15 @@ int psp_init_ta_microcode(struct psp_context *psp, const char *chip_name)
 int psp_init_cap_microcode(struct psp_context *psp, const char *chip_name)
 {
 	struct amdgpu_device *adev = psp->adev;
-	const struct psp_firmware_header_v1_0 *cap_hdr_v1_0;
-	struct amdgpu_firmware_info *info = NULL;
-	int err = 0;
+	struct amdgpu_firmware_info *info;
+	int err;
 
 	if (!amdgpu_sriov_vf(adev)) {
 		dev_err(adev->dev, "cap microcode should only be loaded under SRIOV\n");
 		return -EINVAL;
 	}
 
-	err = amdgpu_ucode_request(adev, &adev->psp.cap_fw, AMDGPU_UCODE_OPTIONAL,
+	err = amdgpu_ucode_request(adev, &psp->cap_fw, AMDGPU_UCODE_OPTIONAL,
 				   "amdgpu/%s_cap.bin", chip_name);
 	if (err) {
 		if (err == -ENODEV) {
@@ -4497,21 +4510,19 @@ int psp_init_cap_microcode(struct psp_context *psp, const char *chip_name)
 		goto out;
 	}
 
+	err = parse_psp_v1_bin_descriptor(&psp->cap,
+		(const struct psp_firmware_header_v1_0 *)psp->cap_fw->data);
+	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;
-	cap_hdr_v1_0 = (const struct psp_firmware_header_v1_0 *)
-		adev->psp.cap_fw->data;
-	adev->firmware.fw_size += ALIGN(
-			le32_to_cpu(cap_hdr_v1_0->header.ucode_size_bytes), PAGE_SIZE);
-	adev->psp.cap_fw_version = le32_to_cpu(cap_hdr_v1_0->header.ucode_version);
-	adev->psp.cap_feature_version = le32_to_cpu(cap_hdr_v1_0->sos.fw_version);
-	adev->psp.cap_ucode_size = le32_to_cpu(cap_hdr_v1_0->header.ucode_size_bytes);
-
+	info->fw = psp->cap_fw;
+	adev->firmware.fw_size += ALIGN(psp->cap.size_bytes, PAGE_SIZE);
 	return 0;
 
 out:
-	amdgpu_ucode_release(&adev->psp.cap_fw);
+	amdgpu_ucode_release(&psp->cap_fw);
 	return err;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index d80c85793e3b9..4047706c1ce22 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -448,9 +448,7 @@ struct psp_context {
 	const struct firmware		*ta_fw;
 	uint32_t			ta_fw_version;
 
-	uint32_t			cap_fw_version;
-	uint32_t			cap_feature_version;
-	uint32_t			cap_ucode_size;
+	struct psp_bin_desc		cap;
 
 	struct ta_context		asd_context;
 	struct psp_xgmi_context		xgmi_context;
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.