Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/nouveau/fb/gp102-: cache scrubber binary on first load

During system shutdown nouveau might not be able to request firmware from
Userspace, which then leads to a regression preventing the system from
shutting down.

Cache the scrubber binary for this case.

Fixes: 0e44c21708761 ("drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)")
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv7Uf5=K44y8YLsiy0aMnc1zvGEQdeDe7RQF=AV+fxxzuQ@mail.gmail.com

authored by

Ben Skeggs and committed by
Karol Herbst
1b9b4f92 3638a820

+36 -50
+2 -1
drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
··· 2 2 #ifndef __NVKM_FB_H__ 3 3 #define __NVKM_FB_H__ 4 4 #include <core/subdev.h> 5 + #include <core/falcon.h> 5 6 #include <core/mm.h> 6 7 7 8 /* memory type/access flags, do not match hardware values */ ··· 34 33 const struct nvkm_fb_func *func; 35 34 struct nvkm_subdev subdev; 36 35 37 - struct nvkm_blob vpr_scrubber; 36 + struct nvkm_falcon_fw vpr_scrubber; 38 37 39 38 struct { 40 39 struct page *flush_page;
+6 -2
drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
··· 143 143 if (!fb->func->vpr.scrub_required) 144 144 return 0; 145 145 146 + ret = nvkm_subdev_oneinit(subdev); 147 + if (ret) 148 + return ret; 149 + 146 150 if (!fb->func->vpr.scrub_required(fb)) { 147 151 nvkm_debug(subdev, "VPR not locked\n"); 148 152 return 0; ··· 154 150 155 151 nvkm_debug(subdev, "VPR locked, running scrubber binary\n"); 156 152 157 - if (!fb->vpr_scrubber.size) { 153 + if (!fb->vpr_scrubber.fw.img) { 158 154 nvkm_warn(subdev, "VPR locked, but no scrubber binary!\n"); 159 155 return 0; 160 156 } ··· 233 229 234 230 nvkm_ram_del(&fb->ram); 235 231 236 - nvkm_blob_dtor(&fb->vpr_scrubber); 232 + nvkm_falcon_fw_dtor(&fb->vpr_scrubber); 237 233 238 234 if (fb->sysmem.flush_page) { 239 235 dma_unmap_page(subdev->device->dev, fb->sysmem.flush_page_addr,
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga100.c
··· 37 37 int 38 38 ga100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) 39 39 { 40 - return gp102_fb_new_(&ga100_fb, device, type, inst, pfb); 40 + return gf100_fb_new_(&ga100_fb, device, type, inst, pfb); 41 41 }
+8 -13
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
··· 25 25 #include <engine/nvdec.h> 26 26 27 27 static int 28 - ga102_fb_vpr_scrub(struct nvkm_fb *fb) 28 + ga102_fb_oneinit(struct nvkm_fb *fb) 29 29 { 30 - struct nvkm_falcon_fw fw = {}; 31 - int ret; 30 + struct nvkm_subdev *subdev = &fb->subdev; 32 31 33 - ret = nvkm_falcon_fw_ctor_hs_v2(&ga102_flcn_fw, "mem-unlock", &fb->subdev, "nvdec/scrubber", 34 - 0, &fb->subdev.device->nvdec[0]->falcon, &fw); 35 - if (ret) 36 - return ret; 32 + nvkm_falcon_fw_ctor_hs_v2(&ga102_flcn_fw, "mem-unlock", subdev, "nvdec/scrubber", 33 + 0, &subdev->device->nvdec[0]->falcon, &fb->vpr_scrubber); 37 34 38 - ret = nvkm_falcon_fw_boot(&fw, &fb->subdev, true, NULL, NULL, 0, 0); 39 - nvkm_falcon_fw_dtor(&fw); 40 - return ret; 35 + return gf100_fb_oneinit(fb); 41 36 } 42 37 43 38 static const struct nvkm_fb_func 44 39 ga102_fb = { 45 40 .dtor = gf100_fb_dtor, 46 - .oneinit = gf100_fb_oneinit, 41 + .oneinit = ga102_fb_oneinit, 47 42 .init = gm200_fb_init, 48 43 .init_page = gv100_fb_init_page, 49 44 .init_unkn = gp100_fb_init_unkn, ··· 46 51 .ram_new = ga102_ram_new, 47 52 .default_bigpage = 16, 48 53 .vpr.scrub_required = tu102_fb_vpr_scrub_required, 49 - .vpr.scrub = ga102_fb_vpr_scrub, 54 + .vpr.scrub = gp102_fb_vpr_scrub, 50 55 }; 51 56 52 57 int 53 58 ga102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) 54 59 { 55 - return gp102_fb_new_(&ga102_fb, device, type, inst, pfb); 60 + return gf100_fb_new_(&ga102_fb, device, type, inst, pfb); 56 61 } 57 62 58 63 MODULE_FIRMWARE("nvidia/ga102/nvdec/scrubber.bin");
+14 -27
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c
··· 29 29 int 30 30 gp102_fb_vpr_scrub(struct nvkm_fb *fb) 31 31 { 32 - struct nvkm_subdev *subdev = &fb->subdev; 33 - struct nvkm_falcon_fw fw = {}; 34 - int ret; 35 - 36 - ret = nvkm_falcon_fw_ctor_hs(&gm200_flcn_fw, "mem-unlock", subdev, NULL, 37 - "nvdec/scrubber", 0, &subdev->device->nvdec[0]->falcon, &fw); 38 - if (ret) 39 - return ret; 40 - 41 - ret = nvkm_falcon_fw_boot(&fw, subdev, true, NULL, NULL, 0, 0x00000000); 42 - nvkm_falcon_fw_dtor(&fw); 43 - return ret; 32 + return nvkm_falcon_fw_boot(&fb->vpr_scrubber, &fb->subdev, true, NULL, NULL, 0, 0x00000000); 44 33 } 45 34 46 35 bool ··· 40 51 return (nvkm_rd32(device, 0x100cd0) & 0x00000010) != 0; 41 52 } 42 53 54 + int 55 + gp102_fb_oneinit(struct nvkm_fb *fb) 56 + { 57 + struct nvkm_subdev *subdev = &fb->subdev; 58 + 59 + nvkm_falcon_fw_ctor_hs(&gm200_flcn_fw, "mem-unlock", subdev, NULL, "nvdec/scrubber", 60 + 0, &subdev->device->nvdec[0]->falcon, &fb->vpr_scrubber); 61 + 62 + return gf100_fb_oneinit(fb); 63 + } 64 + 43 65 static const struct nvkm_fb_func 44 66 gp102_fb = { 45 67 .dtor = gf100_fb_dtor, 46 - .oneinit = gf100_fb_oneinit, 68 + .oneinit = gp102_fb_oneinit, 47 69 .init = gm200_fb_init, 48 70 .init_remapper = gp100_fb_init_remapper, 49 71 .init_page = gm200_fb_init_page, ··· 65 65 }; 66 66 67 67 int 68 - gp102_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device, 69 - enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) 70 - { 71 - int ret = gf100_fb_new_(func, device, type, inst, pfb); 72 - if (ret) 73 - return ret; 74 - 75 - nvkm_firmware_load_blob(&(*pfb)->subdev, "nvdec/scrubber", "", 0, 76 - &(*pfb)->vpr_scrubber); 77 - return 0; 78 - } 79 - 80 - int 81 68 gp102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) 82 69 { 83 - return gp102_fb_new_(&gp102_fb, device, type, inst, pfb); 70 + return gf100_fb_new_(&gp102_fb, device, type, inst, pfb); 84 71 } 85 72 86 73 MODULE_FIRMWARE("nvidia/gp102/nvdec/scrubber.bin");
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c
··· 31 31 static const struct nvkm_fb_func 32 32 gv100_fb = { 33 33 .dtor = gf100_fb_dtor, 34 - .oneinit = gf100_fb_oneinit, 34 + .oneinit = gp102_fb_oneinit, 35 35 .init = gm200_fb_init, 36 36 .init_page = gv100_fb_init_page, 37 37 .init_unkn = gp100_fb_init_unkn, ··· 45 45 int 46 46 gv100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) 47 47 { 48 - return gp102_fb_new_(&gv100_fb, device, type, inst, pfb); 48 + return gf100_fb_new_(&gv100_fb, device, type, inst, pfb); 49 49 } 50 50 51 51 MODULE_FIRMWARE("nvidia/gv100/nvdec/scrubber.bin");
+1 -2
drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
··· 83 83 void gp100_fb_init_remapper(struct nvkm_fb *); 84 84 void gp100_fb_init_unkn(struct nvkm_fb *); 85 85 86 - int gp102_fb_new_(const struct nvkm_fb_func *, struct nvkm_device *, enum nvkm_subdev_type, int, 87 - struct nvkm_fb **); 86 + int gp102_fb_oneinit(struct nvkm_fb *); 88 87 bool gp102_fb_vpr_scrub_required(struct nvkm_fb *); 89 88 int gp102_fb_vpr_scrub(struct nvkm_fb *); 90 89
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c
··· 31 31 static const struct nvkm_fb_func 32 32 tu102_fb = { 33 33 .dtor = gf100_fb_dtor, 34 - .oneinit = gf100_fb_oneinit, 34 + .oneinit = gp102_fb_oneinit, 35 35 .init = gm200_fb_init, 36 36 .init_page = gv100_fb_init_page, 37 37 .init_unkn = gp100_fb_init_unkn, ··· 45 45 int 46 46 tu102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) 47 47 { 48 - return gp102_fb_new_(&tu102_fb, device, type, inst, pfb); 48 + return gf100_fb_new_(&tu102_fb, device, type, inst, pfb); 49 49 } 50 50 51 51 MODULE_FIRMWARE("nvidia/tu102/nvdec/scrubber.bin");