When WPR2 heap size > 256MB, the FB memory needs to be scrubbed before
use.

If not, the GSP firmware hangs when booting.

Introduce ad102_gsp_init_fw_heap(). Load scrubber ucode image when
WRP2 heap size > 256MB after the FB memory layout initialization. Save the
fwif in nvkm_gsp for firmware loading in ad102_gsp_init_fw_heap().

Cc: Surath Mitra <smi...@nvidia.com>
Signed-off-by: Zhi Wang <z...@nvidia.com>
---
 .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h |  3 ++-
 .../gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c   | 21 ++++++++++++++++++-
 .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h    |  4 +++-
 .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c    |  6 +++++-
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
index a2055f2a014a..c6fe2d9d47de 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
@@ -33,7 +33,7 @@ struct nvkm_gsp {
        struct nvkm_subdev subdev;
 
        struct nvkm_falcon falcon;
-
+       const struct nvkm_gsp_fwif *fwif;
        struct {
                struct {
                        const struct firmware *load;
@@ -41,6 +41,7 @@ struct nvkm_gsp {
                } booter;
                const struct firmware *bl;
                const struct firmware *rm;
+               const struct firmware *scrubber;
        } fws;
 
        struct nvkm_firmware fw;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c
index 00a7ec875400..bd8bd37955fa 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c
@@ -21,6 +21,25 @@
  */
 #include "priv.h"
 
+static int
+ad102_gsp_init_fw_heap(struct nvkm_gsp *gsp)
+{
+       int ret;
+
+       nvkm_gsp_init_fw_heap(gsp);
+
+       if (gsp->fb.wpr2.heap.size <= SZ_256M)
+               return 0;
+
+       /* Load scrubber ucode image */
+       ret = r535_gsp_load_fw(gsp, "scrubber", gsp->fwif->ver,
+                              &gsp->fws.scrubber);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static const struct nvkm_gsp_func
 ad102_gsp_r535_113_01 = {
        .flcn = &ga102_gsp_flcn,
@@ -31,7 +50,7 @@ ad102_gsp_r535_113_01 = {
        .wpr_heap.os_carveout_size = 20 << 20,
        .wpr_heap.base_size = 8 << 20,
        .wpr_heap.min_size = 84 << 20,
-       .wpr_heap.init_fw_heap = tu102_gsp_init_fw_heap,
+       .wpr_heap.init_fw_heap = ad102_gsp_init_fw_heap,
 
        .booter.ctor = ga102_gsp_booter_ctor,
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h
index dfb41be3d677..a89ab7b22263 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h
@@ -16,7 +16,9 @@ struct nvkm_gsp_fwif {
 };
 
 int gv100_gsp_nofw(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *);
-int  r535_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *);
+int r535_gsp_load_fw(struct nvkm_gsp *gsp, const char *name,
+                    const char *ver, const struct firmware **pfw);
+int r535_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif 
*fwif);
 
 struct nvkm_gsp_func {
        const struct nvkm_falcon_func *flcn;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
index c56c545f2bdb..ef867eb20cff 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
@@ -2489,6 +2489,8 @@ r535_gsp_dtor_fws(struct nvkm_gsp *gsp)
        gsp->fws.booter.load = NULL;
        nvkm_firmware_put(gsp->fws.rm);
        gsp->fws.rm = NULL;
+       nvkm_firmware_put(gsp->fws.scrubber);
+       gsp->fws.scrubber = NULL;
 }
 
 void
@@ -2656,7 +2658,7 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp)
        return 0;
 }
 
-static int
+int
 r535_gsp_load_fw(struct nvkm_gsp *gsp, const char *name, const char *ver,
                 const struct firmware **pfw)
 {
@@ -2687,6 +2689,8 @@ r535_gsp_load(struct nvkm_gsp *gsp, int ver, const struct 
nvkm_gsp_fwif *fwif)
                return ret;
        }
 
+       gsp->fwif = fwif;
+
        return 0;
 }
 
-- 
2.34.1

Reply via email to