Separated xgmi ta is required for specific APU, and driver needs
parse the ta binary properly with aux xgmi ta packed.

v2: make the check function more generic (Lijo)

Signed-off-by: Le Ma <le...@amd.com>
Reviewed-by: Lijo Lazar <lijo.la...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   | 33 +++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |  1 +
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index abd5e980c9c7..92cf412a4c2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -3563,6 +3563,35 @@ int psp_init_sos_microcode(struct psp_context *psp, 
const char *chip_name)
        return err;
 }
 
+static bool is_ta_fw_applicable(struct psp_context *psp,
+                            const struct psp_fw_bin_desc *desc)
+{
+       struct amdgpu_device *adev = psp->adev;
+       uint32_t fw_version;
+
+       switch (desc->fw_type) {
+       case TA_FW_TYPE_PSP_XGMI:
+       case TA_FW_TYPE_PSP_XGMI_AUX:
+               /* for now, AUX TA only exists on 13.0.6 ta bin,
+                * from v20.00.0x.14 */
+               if (amdgpu_ip_version(adev, MP0_HWIP, 0) ==
+                   IP_VERSION(13, 0, 6)) {
+                       fw_version = le32_to_cpu(desc->fw_version);
+
+                       if (adev->flags & AMD_IS_APU &&
+                           (fw_version & 0xff) >= 0x14)
+                               return desc->fw_type == TA_FW_TYPE_PSP_XGMI_AUX;
+                       else
+                               return desc->fw_type == TA_FW_TYPE_PSP_XGMI;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return true;
+}
+
 static int parse_ta_bin_descriptor(struct psp_context *psp,
                                   const struct psp_fw_bin_desc *desc,
                                   const struct ta_firmware_header_v2_0 *ta_hdr)
@@ -3572,6 +3601,9 @@ static int parse_ta_bin_descriptor(struct psp_context 
*psp,
        if (!psp || !desc || !ta_hdr)
                return -EINVAL;
 
+       if (!is_ta_fw_applicable(psp, desc))
+               return 0;
+
        ucode_start_addr  = (uint8_t *)ta_hdr +
                            le32_to_cpu(desc->offset_bytes) +
                            
le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
@@ -3584,6 +3616,7 @@ static int parse_ta_bin_descriptor(struct psp_context 
*psp,
                psp->asd_context.bin_desc.start_addr        = ucode_start_addr;
                break;
        case TA_FW_TYPE_PSP_XGMI:
+       case TA_FW_TYPE_PSP_XGMI_AUX:
                psp->xgmi_context.context.bin_desc.fw_version       = 
le32_to_cpu(desc->fw_version);
                psp->xgmi_context.context.bin_desc.size_bytes       = 
le32_to_cpu(desc->size_bytes);
                psp->xgmi_context.context.bin_desc.start_addr       = 
ucode_start_addr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
index 4e23419b92d4..4150ec0aa10d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
@@ -163,6 +163,7 @@ enum ta_fw_type {
        TA_FW_TYPE_PSP_DTM,
        TA_FW_TYPE_PSP_RAP,
        TA_FW_TYPE_PSP_SECUREDISPLAY,
+       TA_FW_TYPE_PSP_XGMI_AUX,
        TA_FW_TYPE_MAX_INDEX,
 };
 
-- 
2.43.2

Reply via email to