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 <smitra@xxxxxxxxxx> Signed-off-by: Zhi Wang <zhiw@xxxxxxxxxx> --- .../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