diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2019-05-22 08:15:54 +0200 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2019-06-07 07:13:58 +0200 |
commit | 475cf02b834599c8a7a21a1e2d11449b7217d856 (patch) | |
tree | 886daff7d3eb003d450374fdebf59770b9434bcb /drivers/gpu | |
parent | drm/nouveau/core: pass subdev into nvkm_firmware_get, rather than device (diff) | |
download | linux-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.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/core/firmware.c | 30 |
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); } /** |