drm/amd: Add a new helper for loading/validating microcode

commit 2210af50ae upstream.

All microcode runs a basic validation after it's been loaded. Each
IP block as part of init will run both.

Introduce a wrapper for request_firmware and amdgpu_ucode_validate.
This wrapper will also remap any error codes from request_firmware
to -ENODEV.  This is so that early_init will fail if firmware couldn't
be loaded instead of the IP block being disabled.

Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Mario Limonciello 2023-01-03 13:18:19 -06:00 committed by Greg Kroah-Hartman
parent 709217fdcf
commit 9b36abb956
2 changed files with 39 additions and 0 deletions

View File

@ -1091,3 +1091,39 @@ void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type,
snprintf(ucode_prefix, len, "%s_%d_%d_%d", ip_name, maj, min, rev);
}
/*
* amdgpu_ucode_request - Fetch and validate amdgpu microcode
*
* @adev: amdgpu device
* @fw: pointer to load firmware to
* @fw_name: firmware to load
*
* This is a helper that will use request_firmware and amdgpu_ucode_validate
* to load and run basic validation on firmware. If the load fails, remap
* the error code to -ENODEV, so that early_init functions will fail to load.
*/
int amdgpu_ucode_request(struct amdgpu_device *adev, const struct firmware **fw,
const char *fw_name)
{
int err = request_firmware(fw, fw_name, adev->dev);
if (err)
return -ENODEV;
err = amdgpu_ucode_validate(*fw);
if (err)
dev_dbg(adev->dev, "\"%s\" failed to validate\n", fw_name);
return err;
}
/*
* amdgpu_ucode_release - Release firmware microcode
*
* @fw: pointer to firmware to release
*/
void amdgpu_ucode_release(const struct firmware **fw)
{
release_firmware(*fw);
*fw = NULL;
}

View File

@ -544,6 +544,9 @@ void amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header *hdr);
void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr);
void amdgpu_ucode_print_gpu_info_hdr(const struct common_firmware_header *hdr);
int amdgpu_ucode_validate(const struct firmware *fw);
int amdgpu_ucode_request(struct amdgpu_device *adev, const struct firmware **fw,
const char *fw_name);
void amdgpu_ucode_release(const struct firmware **fw);
bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr,
uint16_t hdr_major, uint16_t hdr_minor);