Commit ea5d4934 authored by Mario Limonciello's avatar Mario Limonciello Committed by Alex Deucher
Browse files

drm/amd: Add the capability to mark certain firmware as "required"



Some of the firmware that is loaded by amdgpu is not actually required.
For example the ISP firmware on some SoCs is optional, and if it's not
present the ISP IP block just won't be initialized.

The firmware loader core however will show a warning when this happens
like this:
```
Direct firmware load for amdgpu/isp_4_1_0.bin failed with error -2
```

To avoid confusion for non-required firmware, adjust the amd-ucode helper
to take an extra argument indicating if the firmware is required or
optional.

On optional firmware use firmware_request_nowarn() instead of
request_firmware() to avoid the warnings.

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/amd-gfx/df71d375-7abd-4b32-97ce-15e57846eed8@amd.com/T/#t


Signed-off-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5a7c8c57
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -414,7 +414,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
				return -EINVAL;
			}

			err = amdgpu_ucode_request(adev, &adev->pm.fw, "%s", fw_name);
			err = amdgpu_ucode_request(adev, &adev->pm.fw,
						   AMDGPU_UCODE_REQUIRED,
						   "%s", fw_name);
			if (err) {
				DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
				amdgpu_ucode_release(&adev->pm.fw);
+1 −0
Original line number Diff line number Diff line
@@ -2485,6 +2485,7 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
	}

	err = amdgpu_ucode_request(adev, &adev->firmware.gpu_info_fw,
				   AMDGPU_UCODE_OPTIONAL,
				   "amdgpu/%s_gpu_info.bin", chip_name);
	if (err) {
		dev_err(adev->dev,
+2 −1
Original line number Diff line number Diff line
@@ -77,7 +77,8 @@ static int isp_load_fw_by_psp(struct amdgpu_device *adev)
				       sizeof(ucode_prefix));

	/* read isp fw */
	r = amdgpu_ucode_request(adev, &adev->isp.fw, "amdgpu/%s.bin", ucode_prefix);
	r = amdgpu_ucode_request(adev, &adev->isp.fw, AMDGPU_UCODE_OPTIONAL,
				"amdgpu/%s.bin", ucode_prefix);
	if (r) {
		amdgpu_ucode_release(&adev->isp.fw);
		return r;
+3 −1
Original line number Diff line number Diff line
@@ -1610,10 +1610,12 @@ int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe)
			 pipe == AMDGPU_MES_SCHED_PIPE ? "" : "1");
	}

	r = amdgpu_ucode_request(adev, &adev->mes.fw[pipe], "%s", fw_name);
	r = amdgpu_ucode_request(adev, &adev->mes.fw[pipe], AMDGPU_UCODE_REQUIRED,
				 "%s", fw_name);
	if (r && need_retry && pipe == AMDGPU_MES_SCHED_PIPE) {
		dev_info(adev->dev, "try to fall back to %s_mes.bin\n", ucode_prefix);
		r = amdgpu_ucode_request(adev, &adev->mes.fw[pipe],
					 AMDGPU_UCODE_REQUIRED,
					 "amdgpu/%s_mes.bin", ucode_prefix);
	}

+12 −6
Original line number Diff line number Diff line
@@ -3290,7 +3290,8 @@ int psp_init_asd_microcode(struct psp_context *psp, const char *chip_name)
	const struct psp_firmware_header_v1_0 *asd_hdr;
	int err = 0;

	err = amdgpu_ucode_request(adev, &adev->psp.asd_fw, "amdgpu/%s_asd.bin", chip_name);
	err = amdgpu_ucode_request(adev, &adev->psp.asd_fw, AMDGPU_UCODE_REQUIRED,
				   "amdgpu/%s_asd.bin", chip_name);
	if (err)
		goto out;

@@ -3312,7 +3313,8 @@ int psp_init_toc_microcode(struct psp_context *psp, const char *chip_name)
	const struct psp_firmware_header_v1_0 *toc_hdr;
	int err = 0;

	err = amdgpu_ucode_request(adev, &adev->psp.toc_fw, "amdgpu/%s_toc.bin", chip_name);
	err = amdgpu_ucode_request(adev, &adev->psp.toc_fw, AMDGPU_UCODE_REQUIRED,
				   "amdgpu/%s_toc.bin", chip_name);
	if (err)
		goto out;

@@ -3475,7 +3477,8 @@ int psp_init_sos_microcode(struct psp_context *psp, const char *chip_name)
	uint8_t *ucode_array_start_addr;
	int err = 0;

	err = amdgpu_ucode_request(adev, &adev->psp.sos_fw, "amdgpu/%s_sos.bin", chip_name);
	err = amdgpu_ucode_request(adev, &adev->psp.sos_fw, AMDGPU_UCODE_REQUIRED,
				   "amdgpu/%s_sos.bin", chip_name);
	if (err)
		goto out;

@@ -3751,7 +3754,8 @@ int psp_init_ta_microcode(struct psp_context *psp, const char *chip_name)
	struct amdgpu_device *adev = psp->adev;
	int err;

	err = amdgpu_ucode_request(adev, &adev->psp.ta_fw, "amdgpu/%s_ta.bin", chip_name);
	err = amdgpu_ucode_request(adev, &adev->psp.ta_fw, AMDGPU_UCODE_REQUIRED,
				   "amdgpu/%s_ta.bin", chip_name);
	if (err)
		return err;

@@ -3786,7 +3790,8 @@ int psp_init_cap_microcode(struct psp_context *psp, const char *chip_name)
		return -EINVAL;
	}

	err = amdgpu_ucode_request(adev, &adev->psp.cap_fw, "amdgpu/%s_cap.bin", chip_name);
	err = amdgpu_ucode_request(adev, &adev->psp.cap_fw, AMDGPU_UCODE_OPTIONAL,
				   "amdgpu/%s_cap.bin", chip_name);
	if (err) {
		if (err == -ENODEV) {
			dev_warn(adev->dev, "cap microcode does not exist, skip\n");
@@ -3909,7 +3914,8 @@ static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev,
	if (!drm_dev_enter(ddev, &idx))
		return -ENODEV;

	ret = amdgpu_ucode_request(adev, &usbc_pd_fw, "amdgpu/%s", buf);
	ret = amdgpu_ucode_request(adev, &usbc_pd_fw, AMDGPU_UCODE_REQUIRED,
				   "amdgpu/%s", buf);
	if (ret)
		goto fail;

Loading