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