Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e137040e authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Ben Skeggs
Browse files

drm/nouveau/gr: fallback to legacy paths during firmware lookup



Look for firmware files using the legacy ("nouveau/nvxx_fucxxxx") path
if they cannot be found in the new, "official" path. User setups were
broken by the switch, which is bad.

There are only 4 firmware files we may want to look up that way, so
hardcode them into the lookup function. All new firmware files should
use the standard "nvidia/<chip>/gr/" path.

Fixes: 8539b37a ("drm/nouveau/gr: use NVIDIA-provided external firmwares")
Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Cc: stable@vger.kernel.org
parent f479c0ba
Loading
Loading
Loading
Loading
+46 −4
Original line number Original line Diff line number Diff line
@@ -1756,19 +1756,61 @@ gf100_gr_ = {
};
};


int
int
gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname,
		 struct gf100_gr_fuc *fuc)
			struct gf100_gr_fuc *fuc, int ret)
{
{
	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	struct nvkm_device *device = subdev->device;
	const struct firmware *fw;
	const struct firmware *fw;
	int ret;
	char f[32];

	/* see if this firmware has a legacy path */
	if (!strcmp(fwname, "fecs_inst"))
		fwname = "fuc409c";
	else if (!strcmp(fwname, "fecs_data"))
		fwname = "fuc409d";
	else if (!strcmp(fwname, "gpccs_inst"))
		fwname = "fuc41ac";
	else if (!strcmp(fwname, "gpccs_data"))
		fwname = "fuc41ad";
	else {
		/* nope, let's just return the error we got */
		nvkm_error(subdev, "failed to load %s\n", fwname);
		return ret;
	}


	ret = nvkm_firmware_get(device, fwname, &fw);
	/* yes, try to load from the legacy path */
	nvkm_debug(subdev, "%s: falling back to legacy path\n", fwname);

	snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname);
	ret = request_firmware(&fw, f, device->dev);
	if (ret) {
		snprintf(f, sizeof(f), "nouveau/%s", fwname);
		ret = request_firmware(&fw, f, device->dev);
		if (ret) {
		if (ret) {
			nvkm_error(subdev, "failed to load %s\n", fwname);
			nvkm_error(subdev, "failed to load %s\n", fwname);
			return ret;
			return ret;
		}
		}
	}

	fuc->size = fw->size;
	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
	release_firmware(fw);
	return (fuc->data != NULL) ? 0 : -ENOMEM;
}

int
gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
		 struct gf100_gr_fuc *fuc)
{
	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	const struct firmware *fw;
	int ret;

	ret = nvkm_firmware_get(device, fwname, &fw);
	if (ret)
		return gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);


	fuc->size = fw->size;
	fuc->size = fw->size;
	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);