summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2019-05-22 08:15:54 +0200
committerBen Skeggs <bskeggs@redhat.com>2019-06-07 07:13:58 +0200
commit475cf02b834599c8a7a21a1e2d11449b7217d856 (patch)
tree886daff7d3eb003d450374fdebf59770b9434bcb /drivers/gpu
parentdrm/nouveau/core: pass subdev into nvkm_firmware_get, rather than device (diff)
downloadlinux-475cf02b834599c8a7a21a1e2d11449b7217d856.tar.xz
linux-475cf02b834599c8a7a21a1e2d11449b7217d856.zip
drm/nouveau/core: support versioned firmware loading
We have a need for this now with updated SEC2 LS FW images that have an incompatible interface from the previous version. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/firmware.c30
2 files changed, 31 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h b/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h
index d0fe98bd50fd..54da9c6bc8d5 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h
@@ -3,7 +3,10 @@
#define __NVKM_FIRMWARE_H__
#include <core/subdev.h>
+int nvkm_firmware_get_version(const struct nvkm_subdev *, const char *fwname,
+ int min_version, int max_version,
+ const struct firmware **);
int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname,
- const struct firmware **fw);
-void nvkm_firmware_put(const struct firmware *fw);
+ const struct firmware **);
+void nvkm_firmware_put(const struct firmware *);
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c
index 87728133ff93..092acdec2c39 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c
@@ -32,8 +32,9 @@
* Firmware files released by NVIDIA will always follow this format.
*/
int
-nvkm_firmware_get(const struct nvkm_subdev *subdev, const char *fwname,
- const struct firmware **fw)
+nvkm_firmware_get_version(const struct nvkm_subdev *subdev, const char *fwname,
+ int min_version, int max_version,
+ const struct firmware **fw)
{
struct nvkm_device *device = subdev->device;
char f[64];
@@ -49,8 +50,29 @@ nvkm_firmware_get(const struct nvkm_subdev *subdev, const char *fwname,
cname[i] = tolower(cname[i]);
}
- snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
- return request_firmware(fw, f, device->dev);
+ for (i = max_version; i >= min_version; i--) {
+ if (i != 0)
+ snprintf(f, sizeof(f), "nvidia/%s/%s-%d.bin", cname, fwname, i);
+ else
+ snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
+
+ if (!firmware_request_nowarn(fw, f, device->dev)) {
+ nvkm_debug(subdev, "firmware \"%s\" loaded\n", f);
+ return i;
+ }
+
+ nvkm_debug(subdev, "firmware \"%s\" unavailable\n", f);
+ }
+
+ nvkm_error(subdev, "failed to load firmware \"%s\"", fwname);
+ return -ENOENT;
+}
+
+int
+nvkm_firmware_get(const struct nvkm_subdev *subdev, const char *fwname,
+ const struct firmware **fw)
+{
+ return nvkm_firmware_get_version(subdev, fwname, 0, 0, fw);
}
/**