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

drm/amdgpu:properly fix some JumpTable issues

we found some MEC ucode leads to IB test fail or even
ring test fail if Jump Table of it is not start in
FW bo with page aligned address, fixed by always make
JT address page aligned.

we don't need to patch JT2 for MEC2, because for VI,
MEC2 is a copy of MEC1, thus when converting fw_type
for MEC_JT2 we just return MEC1,hw can use the same
JT for both MEC1 & MEC2.

above two change fixed some ring/ib test failure issue
for some version of MEC ucode.

Signed-off-by: Frank Min <Frank.Min@amd.com>
Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Monk Liu and committed by
Alex Deucher
4c2b2453 bed5712e

+52 -6
+15 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
··· 687 687 result = AMDGPU_UCODE_ID_CP_MEC1; 688 688 break; 689 689 case CGS_UCODE_ID_CP_MEC_JT2: 690 - if (adev->asic_type == CHIP_TONGA || adev->asic_type == CHIP_POLARIS11 691 - || adev->asic_type == CHIP_POLARIS10) 692 - result = AMDGPU_UCODE_ID_CP_MEC2; 693 - else 690 + /* for VI. JT2 should be the same as JT1, because: 691 + 1, MEC2 and MEC1 use exactly same FW. 692 + 2, JT2 is not pached but JT1 is. 693 + */ 694 + if (adev->asic_type >= CHIP_TOPAZ) 694 695 result = AMDGPU_UCODE_ID_CP_MEC1; 696 + else 697 + result = AMDGPU_UCODE_ID_CP_MEC2; 695 698 break; 696 699 case CGS_UCODE_ID_RLC_G: 697 700 result = AMDGPU_UCODE_ID_RLC_G; ··· 784 781 785 782 if ((type == CGS_UCODE_ID_CP_MEC_JT1) || 786 783 (type == CGS_UCODE_ID_CP_MEC_JT2)) { 787 - gpu_addr += le32_to_cpu(header->jt_offset) << 2; 784 + gpu_addr += ALIGN(le32_to_cpu(header->header.ucode_size_bytes), PAGE_SIZE); 788 785 data_size = le32_to_cpu(header->jt_size) << 2; 789 786 } 790 - info->mc_addr = gpu_addr; 787 + 788 + info->kptr = ucode->kaddr; 791 789 info->image_size = data_size; 790 + info->mc_addr = gpu_addr; 792 791 info->version = (uint16_t)le32_to_cpu(header->header.ucode_version); 792 + 793 + if (CGS_UCODE_ID_CP_MEC == type) 794 + info->image_size = (header->jt_offset) << 2; 795 + 793 796 info->fw_version = amdgpu_get_firmware_version(cgs_device, type); 794 797 info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version); 795 798 } else {
+32
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
··· 239 239 return 0; 240 240 } 241 241 242 + static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode, 243 + uint64_t mc_addr, void *kptr) 244 + { 245 + const struct gfx_firmware_header_v1_0 *header = NULL; 246 + const struct common_firmware_header *comm_hdr = NULL; 247 + uint8_t* src_addr = NULL; 248 + uint8_t* dst_addr = NULL; 249 + 250 + if (NULL == ucode->fw) 251 + return 0; 252 + 253 + comm_hdr = (const struct common_firmware_header *)ucode->fw->data; 254 + header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; 255 + dst_addr = ucode->kaddr + 256 + ALIGN(le32_to_cpu(comm_hdr->ucode_size_bytes), 257 + PAGE_SIZE); 258 + src_addr = (uint8_t *)ucode->fw->data + 259 + le32_to_cpu(comm_hdr->ucode_array_offset_bytes) + 260 + (le32_to_cpu(header->jt_offset) * 4); 261 + memcpy(dst_addr, src_addr, le32_to_cpu(header->jt_size) * 4); 262 + 263 + return 0; 264 + } 265 + 266 + 242 267 int amdgpu_ucode_init_bo(struct amdgpu_device *adev) 243 268 { 244 269 struct amdgpu_bo **bo = &adev->firmware.fw_buf; ··· 309 284 header = (const struct common_firmware_header *)ucode->fw->data; 310 285 amdgpu_ucode_init_single_fw(ucode, fw_mc_addr + fw_offset, 311 286 fw_buf_ptr + fw_offset); 287 + if (i == AMDGPU_UCODE_ID_CP_MEC1) { 288 + const struct gfx_firmware_header_v1_0 *cp_hdr; 289 + cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; 290 + amdgpu_ucode_patch_jt(ucode, fw_mc_addr + fw_offset, 291 + fw_buf_ptr + fw_offset); 292 + fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); 293 + } 312 294 fw_offset += ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); 313 295 } 314 296 }
+5
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
··· 1058 1058 adev->firmware.fw_size += 1059 1059 ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); 1060 1060 1061 + /* we need account JT in */ 1062 + cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; 1063 + adev->firmware.fw_size += 1064 + ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); 1065 + 1061 1066 if (amdgpu_sriov_vf(adev)) { 1062 1067 info = &adev->firmware.ucode[AMDGPU_UCODE_ID_STORAGE]; 1063 1068 info->ucode_id = AMDGPU_UCODE_ID_STORAGE;