Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: load sos binary properly on the basis of pmfw version

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>

authored by

Le Ma and committed by
Alex Deucher
2778701b 2ae6cd58

+33 -7
+23 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 3425 3425 const struct psp_firmware_header_v1_2 *sos_hdr_v1_2; 3426 3426 const struct psp_firmware_header_v1_3 *sos_hdr_v1_3; 3427 3427 const struct psp_firmware_header_v2_0 *sos_hdr_v2_0; 3428 - int err = 0; 3428 + const struct psp_firmware_header_v2_1 *sos_hdr_v2_1; 3429 + int fw_index, fw_bin_count, start_index = 0; 3430 + const struct psp_fw_bin_desc *fw_bin; 3429 3431 uint8_t *ucode_array_start_addr; 3430 - int fw_index = 0; 3432 + int err = 0; 3431 3433 3432 3434 err = amdgpu_ucode_request(adev, &adev->psp.sos_fw, "amdgpu/%s_sos.bin", chip_name); 3433 3435 if (err) ··· 3480 3478 case 2: 3481 3479 sos_hdr_v2_0 = (const struct psp_firmware_header_v2_0 *)adev->psp.sos_fw->data; 3482 3480 3483 - if (le32_to_cpu(sos_hdr_v2_0->psp_fw_bin_count) >= UCODE_MAX_PSP_PACKAGING) { 3481 + fw_bin_count = le32_to_cpu(sos_hdr_v2_0->psp_fw_bin_count); 3482 + 3483 + if (fw_bin_count >= UCODE_MAX_PSP_PACKAGING) { 3484 3484 dev_err(adev->dev, "packed SOS count exceeds maximum limit\n"); 3485 3485 err = -EINVAL; 3486 3486 goto out; 3487 3487 } 3488 3488 3489 - for (fw_index = 0; fw_index < le32_to_cpu(sos_hdr_v2_0->psp_fw_bin_count); fw_index++) { 3490 - err = parse_sos_bin_descriptor(psp, 3491 - &sos_hdr_v2_0->psp_fw_bin[fw_index], 3489 + if (sos_hdr_v2_0->header.header_version_minor == 1) { 3490 + sos_hdr_v2_1 = (const struct psp_firmware_header_v2_1 *)adev->psp.sos_fw->data; 3491 + 3492 + fw_bin = sos_hdr_v2_1->psp_fw_bin; 3493 + 3494 + if (psp_is_aux_sos_load_required(psp)) 3495 + start_index = le32_to_cpu(sos_hdr_v2_1->psp_aux_fw_bin_index); 3496 + else 3497 + fw_bin_count -= le32_to_cpu(sos_hdr_v2_1->psp_aux_fw_bin_index); 3498 + 3499 + } else { 3500 + fw_bin = sos_hdr_v2_0->psp_fw_bin; 3501 + } 3502 + 3503 + for (fw_index = start_index; fw_index < fw_bin_count; fw_index++) { 3504 + err = parse_sos_bin_descriptor(psp, fw_bin + fw_index, 3492 3505 sos_hdr_v2_0); 3493 3506 if (err) 3494 3507 goto out;
+10 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
··· 136 136 struct psp_fw_bin_desc psp_fw_bin[]; 137 137 }; 138 138 139 + /* version_major=2, version_minor=1 */ 140 + struct psp_firmware_header_v2_1 { 141 + struct common_firmware_header header; 142 + uint32_t psp_fw_bin_count; 143 + uint32_t psp_aux_fw_bin_index; 144 + struct psp_fw_bin_desc psp_fw_bin[]; 145 + }; 146 + 139 147 /* version_major=1, version_minor=0 */ 140 148 struct ta_firmware_header_v1_0 { 141 149 struct common_firmware_header header; ··· 434 426 struct psp_firmware_header_v1_1 psp_v1_1; 435 427 struct psp_firmware_header_v1_3 psp_v1_3; 436 428 struct psp_firmware_header_v2_0 psp_v2_0; 429 + struct psp_firmware_header_v2_0 psp_v2_1; 437 430 struct ta_firmware_header_v1_0 ta; 438 431 struct ta_firmware_header_v2_0 ta_v2_0; 439 432 struct gfx_firmware_header_v1_0 gfx; ··· 456 447 uint8_t raw[0x100]; 457 448 }; 458 449 459 - #define UCODE_MAX_PSP_PACKAGING ((sizeof(union amdgpu_firmware_header) - sizeof(struct common_firmware_header) - 4) / sizeof(struct psp_fw_bin_desc)) 450 + #define UCODE_MAX_PSP_PACKAGING (((sizeof(union amdgpu_firmware_header) - sizeof(struct common_firmware_header) - 4) / sizeof(struct psp_fw_bin_desc)) * 2) 460 451 461 452 /* 462 453 * fw loading support