Skip to contentSkip to conversation

gr: fallback to legacy paths during firmware lookup

PATCH In review Alexandre Courbot 3 participants 3 messages Nov 4, 2016 – Nov 6, 2016 1 message not in the archive

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 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 8539b37acef7 ("drm/nouveau/gr: use NVIDIA-provided external firmwares")

---
Changes since v1:
* Moved file name translation into the legacy function

 drm/nouveau/nvkm/engine/gr/gf100.c | 53 +++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 4 deletions(-)
drm/nouveau/nvkm/engine/gr/gf100.c +49 -4
index eccdee04107d..ed45f923442f 100644
@@ -1756,6 +1756,53 @@ gf100_gr_ = {
 };
 
 int
+gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname,
+			struct gf100_gr_fuc *fuc, int ret)
+{
+	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
+	struct nvkm_device *device = subdev->device;
+	const struct firmware *fw;
+	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
+		fwname = NULL;
+
+	/* nope, let's just return the error we got */
+	if (!fwname) {
+		nvkm_error(subdev, "failed to load %s\n", fwname);
+		return ret;
+	}
+
+	/* 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) {
+			nvkm_error(subdev, "failed to load %s\n", fwname);
+			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)
 {
@@ -1765,10 +1812,8 @@ gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
 	int ret;
 
 	ret = nvkm_firmware_get(device, fwname, &fw);
-	if (ret) {
-		nvkm_error(subdev, "failed to load %s\n", fwname);
-		return ret;
-	}
+	if (ret)
+		return gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);
 
 	fuc->size = fw->size;
 	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
Signature · 6 lines
2.10.0

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau

A message that is not in the archive (sent off-list or not yet received): 20161104093617.11370-1-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org

#2 lore raw
Quoted 38 lines · Alexandre Courbot

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 8539b37acef7 ("drm/nouveau/gr: use NVIDIA-provided external firmwares")

---
Changes since v1:
* Moved file name translation into the legacy function

 drm/nouveau/nvkm/engine/gr/gf100.c | 53 +++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 4 deletions(-)
drm/nouveau/nvkm/engine/gr/gf100.c +13 -0
index eccdee04107d..ed45f923442f 100644
@@ -1756,6 +1756,53 @@ gf100_gr_ = {
 };
 
 int
+gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname,
+			struct gf100_gr_fuc *fuc, int ret)
+{
+	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
+	struct nvkm_device *device = subdev->device;
+	const struct firmware *fw;
+	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";

drm/nouveau/nvkm/engine/gr/gf100.c gf100_gr_ = { · line 1781

Quoted 10 lines
drm/nouveau/nvkm/engine/gr/gf100.c +10 -0
+	else if (!strcmp(fwname, "gpccs_inst"))
+		fwname = "fuc41ac";
+	else if (!strcmp(fwname, "gpccs_data"))
+		fwname = "fuc41ad";
+	else
+		fwname = NULL;
+
+	/* nope, let's just return the error we got */
+	if (!fwname) {
+		nvkm_error(subdev, "failed to load %s\n", fwname);

Due to the rename from legacy_fwname -> fwname, this can be NULL. What about replacing the else branch above by this block?

Kind regards,
Peter

Quoted 42 lines
drm/nouveau/nvkm/engine/gr/gf100.c +26 -4
+		return ret;
+	}
+
+	/* 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) {
+			nvkm_error(subdev, "failed to load %s\n", fwname);
+			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)
 {
@@ -1765,10 +1812,8 @@ gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
 	int ret;
 
 	ret = nvkm_firmware_get(device, fwname, &fw);
-	if (ret) {
-		nvkm_error(subdev, "failed to load %s\n", fwname);
-		return ret;
-	}
+	if (ret)
+		return gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);
 
 	fuc->size = fw->size;
 	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
Signature · 1 line
2.10.0

_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau

#3 lore raw
Quoted 44 lines · Peter Wu
Quoted 43 lines · Alexandre Courbot

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 8539b37acef7 ("drm/nouveau/gr: use NVIDIA-provided external firmwares")

---
Changes since v1:
* Moved file name translation into the legacy function

 drm/nouveau/nvkm/engine/gr/gf100.c | 53 +++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 4 deletions(-)
drm/nouveau/nvkm/engine/gr/gf100.c +18 -0
index eccdee04107d..ed45f923442f 100644
@@ -1756,6 +1756,53 @@ gf100_gr_ = {
 };
 
 int
+gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname,
+                     struct gf100_gr_fuc *fuc, int ret)
+{
+     struct nvkm_subdev *subdev = &gr->base.engine.subdev;
+     struct nvkm_device *device = subdev->device;
+     const struct firmware *fw;
+     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
Quoted 8 lines

drm/nouveau/nvkm/engine/gr/gf100.c gf100_gr_ = { · line 1781

Quoted 5 lines
drm/nouveau/nvkm/engine/gr/gf100.c +5 -0
+             fwname = NULL;
+
+     /* nope, let's just return the error we got */
+     if (!fwname) {
+             nvkm_error(subdev, "failed to load %s\n", fwname);

Due to the rename from legacy_fwname -> fwname, this can be NULL. What about replacing the else branch above by this block?

Ah, stupid me - I wanted to save a variable and here is the result. Thanks for catching this, I will send a fixup patch to Ben.
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau