Jiri Slaby a234e1
From: Ben Skeggs <bskeggs@redhat.com>
Jiri Slaby a234e1
Date: Mon, 20 Feb 2023 14:39:21 +1000
Jiri Slaby a234e1
Subject: [PATCH] drm/nouveau/fb/gp102-: cache scrubber binary on first load
Jiri Slaby a234e1
References: bsc#1012628
Jiri Slaby a234e1
Patch-mainline: 6.2.7
Jiri Slaby a234e1
Git-commit: 1b9b4f922f96108da3bb5d87b2d603f5dfbc5650
Jiri Slaby a234e1
Jiri Slaby a234e1
[ Upstream commit 1b9b4f922f96108da3bb5d87b2d603f5dfbc5650 ]
Jiri Slaby a234e1
Jiri Slaby a234e1
During system shutdown nouveau might not be able to request firmware from
Jiri Slaby a234e1
Userspace, which then leads to a regression preventing the system from
Jiri Slaby a234e1
shutting down.
Jiri Slaby a234e1
Jiri Slaby a234e1
Cache the scrubber binary for this case.
Jiri Slaby a234e1
Jiri Slaby a234e1
Fixes: 0e44c21708761 ("drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)")
Jiri Slaby a234e1
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Jiri Slaby a234e1
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Jiri Slaby a234e1
Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv7Uf5=K44y8YLsiy0aMnc1zvGEQdeDe7RQF=AV+fxxzuQ@mail.gmail.com
Jiri Slaby a234e1
Signed-off-by: Sasha Levin <sashal@kernel.org>
Jiri Slaby a234e1
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby a234e1
---
Jiri Slaby a234e1
 .../gpu/drm/nouveau/include/nvkm/subdev/fb.h  |  3 +-
Jiri Slaby a234e1
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c |  8 +++-
Jiri Slaby a234e1
 .../gpu/drm/nouveau/nvkm/subdev/fb/ga100.c    |  2 +-
Jiri Slaby a234e1
 .../gpu/drm/nouveau/nvkm/subdev/fb/ga102.c    | 21 ++++------
Jiri Slaby a234e1
 .../gpu/drm/nouveau/nvkm/subdev/fb/gp102.c    | 41 +++++++------------
Jiri Slaby a234e1
 .../gpu/drm/nouveau/nvkm/subdev/fb/gv100.c    |  4 +-
Jiri Slaby a234e1
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h |  3 +-
Jiri Slaby a234e1
 .../gpu/drm/nouveau/nvkm/subdev/fb/tu102.c    |  4 +-
Jiri Slaby a234e1
 8 files changed, 36 insertions(+), 50 deletions(-)
Jiri Slaby a234e1
Jiri Slaby a234e1
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
Jiri Slaby a234e1
index c5a4f49e..01a22a13 100644
Jiri Slaby a234e1
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
Jiri Slaby a234e1
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
Jiri Slaby a234e1
@@ -2,6 +2,7 @@
Jiri Slaby a234e1
 #ifndef __NVKM_FB_H__
Jiri Slaby a234e1
 #define __NVKM_FB_H__
Jiri Slaby a234e1
 #include <core/subdev.h>
Jiri Slaby a234e1
+#include <core/falcon.h>
Jiri Slaby a234e1
 #include <core/mm.h>
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 /* memory type/access flags, do not match hardware values */
Jiri Slaby a234e1
@@ -33,7 +34,7 @@ struct nvkm_fb {
Jiri Slaby a234e1
 	const struct nvkm_fb_func *func;
Jiri Slaby a234e1
 	struct nvkm_subdev subdev;
Jiri Slaby a234e1
 
Jiri Slaby a234e1
-	struct nvkm_blob vpr_scrubber;
Jiri Slaby a234e1
+	struct nvkm_falcon_fw vpr_scrubber;
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 	struct {
Jiri Slaby a234e1
 		struct page *flush_page;
Jiri Slaby a234e1
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
Jiri Slaby a234e1
index bac7dcc4..0955340c 100644
Jiri Slaby a234e1
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
Jiri Slaby a234e1
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
Jiri Slaby a234e1
@@ -143,6 +143,10 @@ nvkm_fb_mem_unlock(struct nvkm_fb *fb)
Jiri Slaby a234e1
 	if (!fb->func->vpr.scrub_required)
Jiri Slaby a234e1
 		return 0;
Jiri Slaby a234e1
 
Jiri Slaby a234e1
+	ret = nvkm_subdev_oneinit(subdev);
Jiri Slaby a234e1
+	if (ret)
Jiri Slaby a234e1
+		return ret;
Jiri Slaby a234e1
+
Jiri Slaby a234e1
 	if (!fb->func->vpr.scrub_required(fb)) {
Jiri Slaby a234e1
 		nvkm_debug(subdev, "VPR not locked\n");
Jiri Slaby a234e1
 		return 0;
Jiri Slaby a234e1
@@ -150,7 +154,7 @@ nvkm_fb_mem_unlock(struct nvkm_fb *fb)
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 	nvkm_debug(subdev, "VPR locked, running scrubber binary\n");
Jiri Slaby a234e1
 
Jiri Slaby a234e1
-	if (!fb->vpr_scrubber.size) {
Jiri Slaby a234e1
+	if (!fb->vpr_scrubber.fw.img) {
Jiri Slaby a234e1
 		nvkm_warn(subdev, "VPR locked, but no scrubber binary!\n");
Jiri Slaby a234e1
 		return 0;
Jiri Slaby a234e1
 	}
Jiri Slaby a234e1
@@ -229,7 +233,7 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev)
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 	nvkm_ram_del(&fb->ram);
Jiri Slaby a234e1
 
Jiri Slaby a234e1
-	nvkm_blob_dtor(&fb->vpr_scrubber);
Jiri Slaby a234e1
+	nvkm_falcon_fw_dtor(&fb->vpr_scrubber);
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 	if (fb->sysmem.flush_page) {
Jiri Slaby a234e1
 		dma_unmap_page(subdev->device->dev, fb->sysmem.flush_page_addr,
Jiri Slaby a234e1
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga100.c
Jiri Slaby a234e1
index 5098f219..a7456e78 100644
Jiri Slaby a234e1
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga100.c
Jiri Slaby a234e1
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga100.c
Jiri Slaby a234e1
@@ -37,5 +37,5 @@ ga100_fb = {
Jiri Slaby a234e1
 int
Jiri Slaby a234e1
 ga100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
Jiri Slaby a234e1
 {
Jiri Slaby a234e1
-	return gp102_fb_new_(&ga100_fb, device, type, inst, pfb);
Jiri Slaby a234e1
+	return gf100_fb_new_(&ga100_fb, device, type, inst, pfb);
Jiri Slaby a234e1
 }
Jiri Slaby a234e1
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
Jiri Slaby a234e1
index 5a21b0ae..dd476e07 100644
Jiri Slaby a234e1
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
Jiri Slaby a234e1
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
Jiri Slaby a234e1
@@ -25,25 +25,20 @@
Jiri Slaby a234e1
 #include <engine/nvdec.h>
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 static int
Jiri Slaby a234e1
-ga102_fb_vpr_scrub(struct nvkm_fb *fb)
Jiri Slaby a234e1
+ga102_fb_oneinit(struct nvkm_fb *fb)
Jiri Slaby a234e1
 {
Jiri Slaby a234e1
-	struct nvkm_falcon_fw fw = {};
Jiri Slaby a234e1
-	int ret;
Jiri Slaby a234e1
+	struct nvkm_subdev *subdev = &fb->subdev;
Jiri Slaby a234e1
 
Jiri Slaby a234e1
-	ret = nvkm_falcon_fw_ctor_hs_v2(&ga102_flcn_fw, "mem-unlock", &fb->subdev, "nvdec/scrubber",
Jiri Slaby a234e1
-					0, &fb->subdev.device->nvdec[0]->falcon, &fw;;
Jiri Slaby a234e1
-	if (ret)
Jiri Slaby a234e1
-		return ret;
Jiri Slaby a234e1
+	nvkm_falcon_fw_ctor_hs_v2(&ga102_flcn_fw, "mem-unlock", subdev, "nvdec/scrubber",
Jiri Slaby a234e1
+				  0, &subdev->device->nvdec[0]->falcon, &fb->vpr_scrubber);
Jiri Slaby a234e1
 
Jiri Slaby a234e1
-	ret = nvkm_falcon_fw_boot(&fw, &fb->subdev, true, NULL, NULL, 0, 0);
Jiri Slaby a234e1
-	nvkm_falcon_fw_dtor(&fw;;
Jiri Slaby a234e1
-	return ret;
Jiri Slaby a234e1
+	return gf100_fb_oneinit(fb);
Jiri Slaby a234e1
 }
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 static const struct nvkm_fb_func
Jiri Slaby a234e1
 ga102_fb = {
Jiri Slaby a234e1
 	.dtor = gf100_fb_dtor,
Jiri Slaby a234e1
-	.oneinit = gf100_fb_oneinit,
Jiri Slaby a234e1
+	.oneinit = ga102_fb_oneinit,
Jiri Slaby a234e1
 	.init = gm200_fb_init,
Jiri Slaby a234e1
 	.init_page = gv100_fb_init_page,
Jiri Slaby a234e1
 	.init_unkn = gp100_fb_init_unkn,
Jiri Slaby a234e1
@@ -51,13 +46,13 @@ ga102_fb = {
Jiri Slaby a234e1
 	.ram_new = ga102_ram_new,
Jiri Slaby a234e1
 	.default_bigpage = 16,
Jiri Slaby a234e1
 	.vpr.scrub_required = tu102_fb_vpr_scrub_required,
Jiri Slaby a234e1
-	.vpr.scrub = ga102_fb_vpr_scrub,
Jiri Slaby a234e1
+	.vpr.scrub = gp102_fb_vpr_scrub,
Jiri Slaby a234e1
 };
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 int
Jiri Slaby a234e1
 ga102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
Jiri Slaby a234e1
 {
Jiri Slaby a234e1
-	return gp102_fb_new_(&ga102_fb, device, type, inst, pfb);
Jiri Slaby a234e1
+	return gf100_fb_new_(&ga102_fb, device, type, inst, pfb);
Jiri Slaby a234e1
 }
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 MODULE_FIRMWARE("nvidia/ga102/nvdec/scrubber.bin");
Jiri Slaby a234e1
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c
Jiri Slaby a234e1
index 2658481d..14d942e8 100644
Jiri Slaby a234e1
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c
Jiri Slaby a234e1
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c
Jiri Slaby a234e1
@@ -29,18 +29,7 @@
Jiri Slaby a234e1
 int
Jiri Slaby a234e1
 gp102_fb_vpr_scrub(struct nvkm_fb *fb)
Jiri Slaby a234e1
 {
Jiri Slaby a234e1
-	struct nvkm_subdev *subdev = &fb->subdev;
Jiri Slaby a234e1
-	struct nvkm_falcon_fw fw = {};
Jiri Slaby a234e1
-	int ret;
Jiri Slaby a234e1
-
Jiri Slaby a234e1
-	ret = nvkm_falcon_fw_ctor_hs(&gm200_flcn_fw, "mem-unlock", subdev, NULL,
Jiri Slaby a234e1
-				     "nvdec/scrubber", 0, &subdev->device->nvdec[0]->falcon, &fw;;
Jiri Slaby a234e1
-	if (ret)
Jiri Slaby a234e1
-		return ret;
Jiri Slaby a234e1
-
Jiri Slaby a234e1
-	ret = nvkm_falcon_fw_boot(&fw, subdev, true, NULL, NULL, 0, 0x00000000);
Jiri Slaby a234e1
-	nvkm_falcon_fw_dtor(&fw;;
Jiri Slaby a234e1
-	return ret;
Jiri Slaby a234e1
+	return nvkm_falcon_fw_boot(&fb->vpr_scrubber, &fb->subdev, true, NULL, NULL, 0, 0x00000000);
Jiri Slaby a234e1
 }
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 bool
Jiri Slaby a234e1
@@ -51,10 +40,21 @@ gp102_fb_vpr_scrub_required(struct nvkm_fb *fb)
Jiri Slaby a234e1
 	return (nvkm_rd32(device, 0x100cd0) & 0x00000010) != 0;
Jiri Slaby a234e1
 }
Jiri Slaby a234e1
 
Jiri Slaby a234e1
+int
Jiri Slaby a234e1
+gp102_fb_oneinit(struct nvkm_fb *fb)
Jiri Slaby a234e1
+{
Jiri Slaby a234e1
+	struct nvkm_subdev *subdev = &fb->subdev;
Jiri Slaby a234e1
+
Jiri Slaby a234e1
+	nvkm_falcon_fw_ctor_hs(&gm200_flcn_fw, "mem-unlock", subdev, NULL, "nvdec/scrubber",
Jiri Slaby a234e1
+			       0, &subdev->device->nvdec[0]->falcon, &fb->vpr_scrubber);
Jiri Slaby a234e1
+
Jiri Slaby a234e1
+	return gf100_fb_oneinit(fb);
Jiri Slaby a234e1
+}
Jiri Slaby a234e1
+
Jiri Slaby a234e1
 static const struct nvkm_fb_func
Jiri Slaby a234e1
 gp102_fb = {
Jiri Slaby a234e1
 	.dtor = gf100_fb_dtor,
Jiri Slaby a234e1
-	.oneinit = gf100_fb_oneinit,
Jiri Slaby a234e1
+	.oneinit = gp102_fb_oneinit,
Jiri Slaby a234e1
 	.init = gm200_fb_init,
Jiri Slaby a234e1
 	.init_remapper = gp100_fb_init_remapper,
Jiri Slaby a234e1
 	.init_page = gm200_fb_init_page,
Jiri Slaby a234e1
@@ -64,23 +64,10 @@ gp102_fb = {
Jiri Slaby a234e1
 	.ram_new = gp100_ram_new,
Jiri Slaby a234e1
 };
Jiri Slaby a234e1
 
Jiri Slaby a234e1
-int
Jiri Slaby a234e1
-gp102_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device,
Jiri Slaby a234e1
-	      enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
Jiri Slaby a234e1
-{
Jiri Slaby a234e1
-	int ret = gf100_fb_new_(func, device, type, inst, pfb);
Jiri Slaby a234e1
-	if (ret)
Jiri Slaby a234e1
-		return ret;
Jiri Slaby a234e1
-
Jiri Slaby a234e1
-	nvkm_firmware_load_blob(&(*pfb)->subdev, "nvdec/scrubber", "", 0,
Jiri Slaby a234e1
-				&(*pfb)->vpr_scrubber);
Jiri Slaby a234e1
-	return 0;
Jiri Slaby a234e1
-}
Jiri Slaby a234e1
-
Jiri Slaby a234e1
 int
Jiri Slaby a234e1
 gp102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
Jiri Slaby a234e1
 {
Jiri Slaby a234e1
-	return gp102_fb_new_(&gp102_fb, device, type, inst, pfb);
Jiri Slaby a234e1
+	return gf100_fb_new_(&gp102_fb, device, type, inst, pfb);
Jiri Slaby a234e1
 }
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 MODULE_FIRMWARE("nvidia/gp102/nvdec/scrubber.bin");
Jiri Slaby a234e1
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c
Jiri Slaby a234e1
index 0e3c0a8f..4d8a286a 100644
Jiri Slaby a234e1
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c
Jiri Slaby a234e1
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c
Jiri Slaby a234e1
@@ -31,7 +31,7 @@ gv100_fb_init_page(struct nvkm_fb *fb)
Jiri Slaby a234e1
 static const struct nvkm_fb_func
Jiri Slaby a234e1
 gv100_fb = {
Jiri Slaby a234e1
 	.dtor = gf100_fb_dtor,
Jiri Slaby a234e1
-	.oneinit = gf100_fb_oneinit,
Jiri Slaby a234e1
+	.oneinit = gp102_fb_oneinit,
Jiri Slaby a234e1
 	.init = gm200_fb_init,
Jiri Slaby a234e1
 	.init_page = gv100_fb_init_page,
Jiri Slaby a234e1
 	.init_unkn = gp100_fb_init_unkn,
Jiri Slaby a234e1
@@ -45,7 +45,7 @@ gv100_fb = {
Jiri Slaby a234e1
 int
Jiri Slaby a234e1
 gv100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
Jiri Slaby a234e1
 {
Jiri Slaby a234e1
-	return gp102_fb_new_(&gv100_fb, device, type, inst, pfb);
Jiri Slaby a234e1
+	return gf100_fb_new_(&gv100_fb, device, type, inst, pfb);
Jiri Slaby a234e1
 }
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 MODULE_FIRMWARE("nvidia/gv100/nvdec/scrubber.bin");
Jiri Slaby a234e1
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
Jiri Slaby a234e1
index f517751f..726c30c8 100644
Jiri Slaby a234e1
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
Jiri Slaby a234e1
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
Jiri Slaby a234e1
@@ -83,8 +83,7 @@ int gm200_fb_init_page(struct nvkm_fb *);
Jiri Slaby a234e1
 void gp100_fb_init_remapper(struct nvkm_fb *);
Jiri Slaby a234e1
 void gp100_fb_init_unkn(struct nvkm_fb *);
Jiri Slaby a234e1
 
Jiri Slaby a234e1
-int gp102_fb_new_(const struct nvkm_fb_func *, struct nvkm_device *, enum nvkm_subdev_type, int,
Jiri Slaby a234e1
-		  struct nvkm_fb **);
Jiri Slaby a234e1
+int gp102_fb_oneinit(struct nvkm_fb *);
Jiri Slaby a234e1
 bool gp102_fb_vpr_scrub_required(struct nvkm_fb *);
Jiri Slaby a234e1
 int gp102_fb_vpr_scrub(struct nvkm_fb *);
Jiri Slaby a234e1
 
Jiri Slaby a234e1
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c
Jiri Slaby a234e1
index be82af03..b8803c12 100644
Jiri Slaby a234e1
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c
Jiri Slaby a234e1
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c
Jiri Slaby a234e1
@@ -31,7 +31,7 @@ tu102_fb_vpr_scrub_required(struct nvkm_fb *fb)
Jiri Slaby a234e1
 static const struct nvkm_fb_func
Jiri Slaby a234e1
 tu102_fb = {
Jiri Slaby a234e1
 	.dtor = gf100_fb_dtor,
Jiri Slaby a234e1
-	.oneinit = gf100_fb_oneinit,
Jiri Slaby a234e1
+	.oneinit = gp102_fb_oneinit,
Jiri Slaby a234e1
 	.init = gm200_fb_init,
Jiri Slaby a234e1
 	.init_page = gv100_fb_init_page,
Jiri Slaby a234e1
 	.init_unkn = gp100_fb_init_unkn,
Jiri Slaby a234e1
@@ -45,7 +45,7 @@ tu102_fb = {
Jiri Slaby a234e1
 int
Jiri Slaby a234e1
 tu102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
Jiri Slaby a234e1
 {
Jiri Slaby a234e1
-	return gp102_fb_new_(&tu102_fb, device, type, inst, pfb);
Jiri Slaby a234e1
+	return gf100_fb_new_(&tu102_fb, device, type, inst, pfb);
Jiri Slaby a234e1
 }
Jiri Slaby a234e1
 
Jiri Slaby a234e1
 MODULE_FIRMWARE("nvidia/tu102/nvdec/scrubber.bin");
Jiri Slaby a234e1
-- 
Jiri Slaby a234e1
2.35.3
Jiri Slaby a234e1