]> git.dujemihanovic.xyz Git - linux.git/commitdiff
drm/amdgpu: load sos binary properly on the basis of pmfw version
authorLe Ma <le.ma@amd.com>
Tue, 10 Sep 2024 12:10:45 +0000 (20:10 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 18 Sep 2024 20:15:06 +0000 (16:15 -0400)
To be compatible with legacy IFWI, driver needs to carry legacy tOS and
query pmfw version to load them accordingly.

Add psp_firmware_header_v2_1 to handle the combined sos binary.

Double the sos count limit for the case of aux sos fw packed.

v2: pass the correct fw_bin_desc to parse_sos_bin_descriptor

Signed-off-by: Le Ma <le.ma@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h

index e9e599ff3bd48877a9c6b73d5df6e9c9077f4603..0b28b2cf1517d130da01989df70b9dff6433edc4 100644 (file)
@@ -3425,9 +3425,11 @@ int psp_init_sos_microcode(struct psp_context *psp, const char *chip_name)
        const struct psp_firmware_header_v1_2 *sos_hdr_v1_2;
        const struct psp_firmware_header_v1_3 *sos_hdr_v1_3;
        const struct psp_firmware_header_v2_0 *sos_hdr_v2_0;
-       int err = 0;
+       const struct psp_firmware_header_v2_1 *sos_hdr_v2_1;
+       int fw_index, fw_bin_count, start_index = 0;
+       const struct psp_fw_bin_desc *fw_bin;
        uint8_t *ucode_array_start_addr;
-       int fw_index = 0;
+       int err = 0;
 
        err = amdgpu_ucode_request(adev, &adev->psp.sos_fw, "amdgpu/%s_sos.bin", chip_name);
        if (err)
@@ -3478,15 +3480,30 @@ int psp_init_sos_microcode(struct psp_context *psp, const char *chip_name)
        case 2:
                sos_hdr_v2_0 = (const struct psp_firmware_header_v2_0 *)adev->psp.sos_fw->data;
 
-               if (le32_to_cpu(sos_hdr_v2_0->psp_fw_bin_count) >= UCODE_MAX_PSP_PACKAGING) {
+               fw_bin_count = le32_to_cpu(sos_hdr_v2_0->psp_fw_bin_count);
+
+               if (fw_bin_count >= UCODE_MAX_PSP_PACKAGING) {
                        dev_err(adev->dev, "packed SOS count exceeds maximum limit\n");
                        err = -EINVAL;
                        goto out;
                }
 
-               for (fw_index = 0; fw_index < le32_to_cpu(sos_hdr_v2_0->psp_fw_bin_count); fw_index++) {
-                       err = parse_sos_bin_descriptor(psp,
-                                                      &sos_hdr_v2_0->psp_fw_bin[fw_index],
+               if (sos_hdr_v2_0->header.header_version_minor == 1) {
+                       sos_hdr_v2_1 = (const struct psp_firmware_header_v2_1 *)adev->psp.sos_fw->data;
+
+                       fw_bin = sos_hdr_v2_1->psp_fw_bin;
+
+                       if (psp_is_aux_sos_load_required(psp))
+                               start_index = le32_to_cpu(sos_hdr_v2_1->psp_aux_fw_bin_index);
+                       else
+                               fw_bin_count -= le32_to_cpu(sos_hdr_v2_1->psp_aux_fw_bin_index);
+
+               } else {
+                       fw_bin = sos_hdr_v2_0->psp_fw_bin;
+               }
+
+               for (fw_index = start_index; fw_index < fw_bin_count; fw_index++) {
+                       err = parse_sos_bin_descriptor(psp, fw_bin + fw_index,
                                                       sos_hdr_v2_0);
                        if (err)
                                goto out;
index 5bc37acd3981952e795584480c2e59fa1db410e3..4e23419b92d4eba2f8f087ddd9ba51026724eaaf 100644 (file)
@@ -136,6 +136,14 @@ struct psp_firmware_header_v2_0 {
        struct psp_fw_bin_desc psp_fw_bin[];
 };
 
+/* version_major=2, version_minor=1 */
+struct psp_firmware_header_v2_1 {
+       struct common_firmware_header header;
+       uint32_t psp_fw_bin_count;
+       uint32_t psp_aux_fw_bin_index;
+       struct psp_fw_bin_desc psp_fw_bin[];
+};
+
 /* version_major=1, version_minor=0 */
 struct ta_firmware_header_v1_0 {
        struct common_firmware_header header;
@@ -426,6 +434,7 @@ union amdgpu_firmware_header {
        struct psp_firmware_header_v1_1 psp_v1_1;
        struct psp_firmware_header_v1_3 psp_v1_3;
        struct psp_firmware_header_v2_0 psp_v2_0;
+       struct psp_firmware_header_v2_0 psp_v2_1;
        struct ta_firmware_header_v1_0 ta;
        struct ta_firmware_header_v2_0 ta_v2_0;
        struct gfx_firmware_header_v1_0 gfx;
@@ -447,7 +456,7 @@ union amdgpu_firmware_header {
        uint8_t raw[0x100];
 };
 
-#define UCODE_MAX_PSP_PACKAGING ((sizeof(union amdgpu_firmware_header) - sizeof(struct common_firmware_header) - 4) / sizeof(struct psp_fw_bin_desc))
+#define UCODE_MAX_PSP_PACKAGING (((sizeof(union amdgpu_firmware_header) - sizeof(struct common_firmware_header) - 4) / sizeof(struct psp_fw_bin_desc)) * 2)
 
 /*
  * fw loading support