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

drm/amdgpu: correct psp ucode arrary start address

For ASICs that need to load sys_drv_aux and sos_aux,
the sys_start_addr is not the start address of psp
ucode array because the sys_drv_aux and sos_aux actaully
located at the end of the ucode array, instead, the
psp ucode arrary start address should be sos_hdr +
sos_hdr_offset.

Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: John Clements <John.Clements@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Hawking Zhang and committed by
Alex Deucher
ed4454c3 5a75ea56

+14 -9
+14 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 2954 2954 { 2955 2955 const struct psp_firmware_header_v1_0 *sos_hdr; 2956 2956 const struct psp_firmware_header_v1_3 *sos_hdr_v1_3; 2957 + uint8_t *ucode_array_start_addr; 2957 2958 2958 2959 sos_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data; 2960 + ucode_array_start_addr = (uint8_t *)sos_hdr + 2961 + le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes); 2959 2962 2960 2963 if (adev->gmc.xgmi.connected_to_cpu || (adev->asic_type != CHIP_ALDEBARAN)) { 2961 2964 adev->psp.sos_fw_version = le32_to_cpu(sos_hdr->header.ucode_version); 2962 2965 adev->psp.sos_feature_version = le32_to_cpu(sos_hdr->sos.fw_version); 2963 2966 2964 2967 adev->psp.sys_bin_size = le32_to_cpu(sos_hdr->sos.offset_bytes); 2965 - adev->psp.sys_start_addr = (uint8_t *)sos_hdr + 2966 - le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes); 2968 + adev->psp.sys_start_addr = ucode_array_start_addr; 2967 2969 2968 2970 adev->psp.sos_bin_size = le32_to_cpu(sos_hdr->sos.size_bytes); 2969 - adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + 2971 + adev->psp.sos_start_addr = ucode_array_start_addr + 2970 2972 le32_to_cpu(sos_hdr->sos.offset_bytes); 2971 2973 } else { 2972 2974 /* Load alternate PSP SOS FW */ ··· 2978 2976 adev->psp.sos_feature_version = le32_to_cpu(sos_hdr_v1_3->sos_aux.fw_version); 2979 2977 2980 2978 adev->psp.sys_bin_size = le32_to_cpu(sos_hdr_v1_3->sys_drv_aux.size_bytes); 2981 - adev->psp.sys_start_addr = (uint8_t *)adev->psp.sys_start_addr + 2979 + adev->psp.sys_start_addr = ucode_array_start_addr + 2982 2980 le32_to_cpu(sos_hdr_v1_3->sys_drv_aux.offset_bytes); 2983 2981 2984 2982 adev->psp.sos_bin_size = le32_to_cpu(sos_hdr_v1_3->sos_aux.size_bytes); 2985 - adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + 2983 + adev->psp.sos_start_addr = ucode_array_start_addr + 2986 2984 le32_to_cpu(sos_hdr_v1_3->sos_aux.offset_bytes); 2987 2985 } 2988 2986 ··· 3004 3002 const struct psp_firmware_header_v1_2 *sos_hdr_v1_2; 3005 3003 const struct psp_firmware_header_v1_3 *sos_hdr_v1_3; 3006 3004 int err = 0; 3005 + uint8_t *ucode_array_start_addr; 3007 3006 3008 3007 if (!chip_name) { 3009 3008 dev_err(adev->dev, "invalid chip name for sos microcode\n"); ··· 3021 3018 goto out; 3022 3019 3023 3020 sos_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data; 3021 + ucode_array_start_addr = (uint8_t *)sos_hdr + 3022 + le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes); 3024 3023 amdgpu_ucode_print_psp_hdr(&sos_hdr->header); 3025 3024 3026 3025 switch (sos_hdr->header.header_version_major) { ··· 3049 3044 if (sos_hdr->header.header_version_minor == 3) { 3050 3045 sos_hdr_v1_3 = (const struct psp_firmware_header_v1_3 *)adev->psp.sos_fw->data; 3051 3046 adev->psp.toc_bin_size = le32_to_cpu(sos_hdr_v1_3->v1_1.toc.size_bytes); 3052 - adev->psp.toc_start_addr = (uint8_t *)adev->psp.sys_start_addr + 3047 + adev->psp.toc_start_addr = ucode_array_start_addr + 3053 3048 le32_to_cpu(sos_hdr_v1_3->v1_1.toc.offset_bytes); 3054 3049 adev->psp.kdb_bin_size = le32_to_cpu(sos_hdr_v1_3->v1_1.kdb.size_bytes); 3055 - adev->psp.kdb_start_addr = (uint8_t *)adev->psp.sys_start_addr + 3050 + adev->psp.kdb_start_addr = ucode_array_start_addr + 3056 3051 le32_to_cpu(sos_hdr_v1_3->v1_1.kdb.offset_bytes); 3057 3052 adev->psp.spl_bin_size = le32_to_cpu(sos_hdr_v1_3->spl.size_bytes); 3058 - adev->psp.spl_start_addr = (uint8_t *)adev->psp.sys_start_addr + 3053 + adev->psp.spl_start_addr = ucode_array_start_addr + 3059 3054 le32_to_cpu(sos_hdr_v1_3->spl.offset_bytes); 3060 3055 adev->psp.rl_bin_size = le32_to_cpu(sos_hdr_v1_3->rl.size_bytes); 3061 - adev->psp.rl_start_addr = (uint8_t *)adev->psp.sys_start_addr + 3056 + adev->psp.rl_start_addr = ucode_array_start_addr + 3062 3057 le32_to_cpu(sos_hdr_v1_3->rl.offset_bytes); 3063 3058 } 3064 3059 break;