--- a/sys/dev/drm/amd/amdgpu/psp_v11_0.c +++ b/sys/dev/drm/amd/amdgpu/psp_v11_0.c @@ -34,6 +34,7 @@ #include "nbio/nbio_7_4_offset.h" MODULE_FIRMWARE("amdgpufw_vega20_sos"); +MODULE_FIRMWARE("amdgpufw_vega20_asd"); /* address block */ #define smnMP1_FIRMWARE_FLAGS 0x3010024 @@ -129,6 +130,30 @@ le32_to_cpu(hdr->header.ucode_array_offset_bytes); adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + le32_to_cpu(hdr->sos_offset_bytes); + + /* psp_hw_start() -> psp_asd_load() consumes asd_start_addr and + * asd_ucode_size unconditionally; without this block they stay + * NULL/0 for Vega20 and the generic code memcpy()s from NULL and + * submits a zero-length LOAD_ASD whose PSP rejection is then + * swallowed (psp_cmd_submit_buf ignores resp.status for + * ucode == NULL). Mirror psp_v3_1_init_microcode(). + */ + snprintf(fw_name, sizeof(fw_name), "amdgpufw_%s_asd", chip_name); + err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev); + if (err) + goto out; + + err = amdgpu_ucode_validate(adev->psp.asd_fw); + if (err) + goto out; + + hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data; + adev->psp.asd_fw_version = le32_to_cpu(hdr->header.ucode_version); + adev->psp.asd_feature_version = le32_to_cpu(hdr->ucode_feature_version); + adev->psp.asd_ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); + adev->psp.asd_start_addr = (uint8_t *)hdr + + le32_to_cpu(hdr->header.ucode_array_offset_bytes); + return 0; out: if (err) { @@ -137,6 +162,8 @@ fw_name); release_firmware(adev->psp.sos_fw); adev->psp.sos_fw = NULL; + release_firmware(adev->psp.asd_fw); + adev->psp.asd_fw = NULL; } return err;