One of the things that OpenRM does right before initiating fbsr is apply a
special workaround (nvidia issue #3172217) which temporarily disables raw
compression mode on the GPU. It is later re-enabled after resuming with
fbsr completes.

Since we don't currently save the compbit backing with fbsr, this shouldn't
currently make any functional difference in the suspend/resume process. But
it will be required for implementing support for saving and restoring
compbit backings from the GPU.

Signed-off-by: Lyude Paul <[email protected]>
---
 .../nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c    | 47 +++++++++++++++++++
 .../nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h       |  6 +++
 2 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c
index af5aa5065c3dd..7f5aae0c055b8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c
@@ -26,6 +26,34 @@ r570_fbsr_suspend_channels(struct nvkm_gsp *gsp, bool 
suspend)
        return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl);
 }
 
+static int
+r570_memsys_enable_raw_comp_mode(struct nvkm_gsp *gsp, bool enable)
+{
+       NV2080_CTRL_INTERNAL_MEMSYS_PROGRAM_RAW_COMPRESSION_MODE_PARAMS *ctrl;
+       int ret;
+
+       ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.object,
+                                   
NV2080_CTRL_CMD_INTERNAL_MEMSYS_PROGRAM_RAW_COMPRESSION_MODE,
+                                   sizeof(*ctrl));
+       if (IS_ERR(ctrl))
+               return PTR_ERR(ctrl);
+
+       ctrl->bRawMode = enable;
+
+       ret = nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl);
+       if (!ret)
+               nvkm_debug(&gsp->subdev, "Raw compression mode %s\n", 
str_enabled_disabled(enable));
+
+       return ret;
+}
+
+static bool
+r570_need_raw_comp_war(struct nvkm_gsp *gsp, struct nvkm_device *device)
+{
+       return (device->card_type == GA100 || device->card_type == AD100) &&
+           gsp->memsys.use_raw_mode_comptagline_alloc;
+}
+
 static void
 r570_fbsr_resume(struct nvkm_gsp *gsp)
 {
@@ -33,6 +61,7 @@ r570_fbsr_resume(struct nvkm_gsp *gsp)
        struct nvkm_instmem *imem = device->imem;
        struct nvkm_instobj *iobj;
        struct nvkm_vmm *vmm;
+       int ret;
 
        /* Restore BAR2 page tables via BAR0 window, and re-enable BAR2. */
        list_for_each_entry(iobj, &imem->boot, head) {
@@ -59,6 +88,13 @@ r570_fbsr_resume(struct nvkm_gsp *gsp)
 
        /* Finish cleaning up. */
        r535_fbsr_resume(gsp);
+
+       /* Re-enable raw mode if it was previously disabled */
+       if (r570_need_raw_comp_war(gsp, device)) {
+               ret = r570_memsys_enable_raw_comp_mode(gsp, true);
+               if (ret)
+                       nvkm_error(&gsp->subdev, "Failed to re-enable raw comp 
mode\n");
+       }
 }
 
 static int
@@ -104,6 +140,17 @@ r570_fbsr_suspend(struct nvkm_gsp *gsp)
        /* Stop channel scheduling. */
        r570_fbsr_suspend_channels(gsp, true);
 
+       /* Temporarily disable raw mode to prevent FBSR restore operations from 
corrupting
+        * compressed surfaces. Required for ampere and ada.
+        *
+        * Nvidia bug #3172217
+        */
+       if (r570_need_raw_comp_war(gsp, device)) {
+               ret = r570_memsys_enable_raw_comp_mode(gsp, false);
+               if (ret)
+                       return ret;
+       }
+
        /* Save BAR2 allocations to system memory. */
        list_for_each_entry(iobj, &imem->list, head) {
                if (iobj->preserve) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h
index 8af432375f7a2..9050a8274b273 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h
@@ -16,4 +16,10 @@ typedef struct NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS {
     NV_DECLARE_ALIGNED(NvU64 sysmemAddrOfSuspendResumeData, 8);
 } NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS;
 
+#define NV2080_CTRL_CMD_INTERNAL_MEMSYS_PROGRAM_RAW_COMPRESSION_MODE 
(0x20800a6f) /* finn: Evaluated from 
"(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | 
NV2080_CTRL_INTERNAL_MEMSYS_PROGRAM_RAW_COMPRESSION_MODE_PARAMS_MESSAGE_ID" */
+
+typedef struct NV2080_CTRL_INTERNAL_MEMSYS_PROGRAM_RAW_COMPRESSION_MODE_PARAMS 
{
+    NvBool bRawMode;
+} NV2080_CTRL_INTERNAL_MEMSYS_PROGRAM_RAW_COMPRESSION_MODE_PARAMS;
+
 #endif
-- 
2.55.0

Reply via email to