|
@@ -1755,6 +1755,50 @@ gf100_gr_ = {
|
|
|
.object_get = gf100_gr_object_get,
|
|
|
};
|
|
|
|
|
|
+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 {
|
|
|
+ /* nope, let's just return the error we got */
|
|
|
+ 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 +1809,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);
|