diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
index 1df09ed6fe6d8025d16de873532e1741fa7a2498..df666fb03f5f9f6ad3357fc277920e603becc838 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
@@ -243,6 +243,7 @@ acr_r352_ls_ucode_img_load(const struct acr_r352 *acr,
 			   enum nvkm_secboot_falcon falcon_id)
 {
 	const struct nvkm_subdev *subdev = acr->base.subdev;
+	const struct acr_r352_ls_func *func = acr->func->ls_func[falcon_id];
 	struct ls_ucode_img_r352 *img;
 	int ret;
 
@@ -252,9 +253,8 @@ acr_r352_ls_ucode_img_load(const struct acr_r352 *acr,
 
 	img->base.falcon_id = falcon_id;
 
-	ret = acr->func->ls_func[falcon_id]->load(sb, &img->base);
-
-	if (ret) {
+	ret = func->load(sb, func->version_max, &img->base);
+	if (ret < 0) {
 		kfree(img->base.ucode_data);
 		kfree(img->base.sig);
 		kfree(img);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
index 3d58ab87156325de7097c51d6820c01b77414ecb..f29c2268c026a83d3c19d1c18bd70707fc4ed3d1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
@@ -57,12 +57,14 @@ hsf_load_header_app_size(const struct hsf_load_header *hdr, u32 app)
  * @lhdr_flags: LS flags
  */
 struct acr_r352_ls_func {
-	int (*load)(const struct nvkm_secboot *, struct ls_ucode_img *);
+	int (*load)(const struct nvkm_secboot *, int maxver,
+		    struct ls_ucode_img *);
 	void (*generate_bl_desc)(const struct nvkm_acr *,
 				 const struct ls_ucode_img *, u64, void *);
 	u32 bl_desc_size;
 	int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *);
 	u32 lhdr_flags;
+	int version_max;
 };
 
 struct acr_r352;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c
index 978ad079036705cbb10b2b87fafa9507dc79317c..7c2424d730838be95ad0bac47f57c3b8fe8b6b3f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c
@@ -111,6 +111,7 @@ acr_r367_ls_ucode_img_load(const struct acr_r352 *acr,
 			   enum nvkm_secboot_falcon falcon_id)
 {
 	const struct nvkm_subdev *subdev = acr->base.subdev;
+	const struct acr_r352_ls_func *func = acr->func->ls_func[falcon_id];
 	struct ls_ucode_img_r367 *img;
 	int ret;
 
@@ -120,8 +121,8 @@ acr_r367_ls_ucode_img_load(const struct acr_r352 *acr,
 
 	img->base.falcon_id = falcon_id;
 
-	ret = acr->func->ls_func[falcon_id]->load(sb, &img->base);
-	if (ret) {
+	ret = func->load(sb, func->version_max, &img->base);
+	if (ret < 0) {
 		kfree(img->base.ucode_data);
 		kfree(img->base.sig);
 		kfree(img);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h
index 9b7c402594e80c16a9fe05e2f9a8147d5c2c1405..d43f906da3a7bbcb451a40f24aa27398e91134a4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h
@@ -147,11 +147,15 @@ struct fw_bl_desc {
 	u32 data_size;
 };
 
-int acr_ls_ucode_load_fecs(const struct nvkm_secboot *, struct ls_ucode_img *);
-int acr_ls_ucode_load_gpccs(const struct nvkm_secboot *, struct ls_ucode_img *);
-int acr_ls_ucode_load_pmu(const struct nvkm_secboot *, struct ls_ucode_img *);
+int acr_ls_ucode_load_fecs(const struct nvkm_secboot *, int,
+			   struct ls_ucode_img *);
+int acr_ls_ucode_load_gpccs(const struct nvkm_secboot *, int,
+			    struct ls_ucode_img *);
+int acr_ls_ucode_load_pmu(const struct nvkm_secboot *, int,
+			  struct ls_ucode_img *);
 int acr_ls_pmu_post_run(const struct nvkm_acr *, const struct nvkm_secboot *);
-int acr_ls_ucode_load_sec2(const struct nvkm_secboot *, struct ls_ucode_img *);
+int acr_ls_ucode_load_sec2(const struct nvkm_secboot *, int,
+			   struct ls_ucode_img *);
 int acr_ls_sec2_post_run(const struct nvkm_acr *, const struct nvkm_secboot *);
 
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c
index 0d71a9e40c3ea65f10df5d9a2cbe997cbf376259..821d3b2bdb1fa7503785d4b74d511b96dac8c1d4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c
@@ -90,8 +90,8 @@ ls_ucode_img_build(const struct firmware *bl, const struct firmware *code,
  * blob. Also generate the corresponding ucode descriptor.
  */
 static int
-ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img,
-		     const char *falcon_name)
+ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, int maxver,
+		     struct ls_ucode_img *img, const char *falcon_name)
 {
 	const struct firmware *bl, *code, *data, *sig;
 	char f[64];
@@ -146,13 +146,15 @@ ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img,
 }
 
 int
-acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
+acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, int maxver,
+		       struct ls_ucode_img *img)
 {
-	return ls_ucode_img_load_gr(&sb->subdev, img, "fecs");
+	return ls_ucode_img_load_gr(&sb->subdev, maxver, img, "fecs");
 }
 
 int
-acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
+acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, int maxver,
+			struct ls_ucode_img *img)
 {
-	return ls_ucode_img_load_gr(&sb->subdev, img, "gpccs");
+	return ls_ucode_img_load_gr(&sb->subdev, maxver, img, "gpccs");
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c
index 5b9874619e53aac30d4e78b86ddacc05ed62c7ab..5a7a55e831a46f4f7d2a9c90a49b109dcd1a9ca4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c
@@ -39,7 +39,7 @@
  */
 static int
 acr_ls_ucode_load_msgqueue(const struct nvkm_subdev *subdev, const char *name,
-			   struct ls_ucode_img *img)
+			   int maxver, struct ls_ucode_img *img)
 {
 	const struct firmware *image, *desc, *sig;
 	char f[64];
@@ -99,12 +99,13 @@ acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue,
 }
 
 int
-acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
+acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, int maxver,
+		      struct ls_ucode_img *img)
 {
 	struct nvkm_pmu *pmu = sb->subdev.device->pmu;
 	int ret;
 
-	ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", img);
+	ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", maxver, img);
 	if (ret)
 		return ret;
 
@@ -136,12 +137,13 @@ acr_ls_pmu_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb)
 }
 
 int
-acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
+acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, int maxver,
+		       struct ls_ucode_img *img)
 {
 	struct nvkm_sec2 *sec = sb->subdev.device->sec2;
 	int ret;
 
-	ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", img);
+	ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", maxver, img);
 	if (ret)
 		return ret;