drm/nouveau/engine: add HAL for engine-specific rc reset procedure
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:48:02 +0000 (20:48 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:45:10 +0000 (10:45 +1000)
Will be used to improve gr reset on GF100 and newer.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
drivers/gpu/drm/nouveau/nvkm/core/engine.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c

index 6d15c13509bfb75e4e969842ffcd4d1803365c09..b67b9c1a6b4e5fd498b2af5166afaa98501ba032 100644 (file)
@@ -21,6 +21,7 @@ struct nvkm_engine_func {
        int (*info)(struct nvkm_engine *, u64 mthd, u64 *data);
        int (*init)(struct nvkm_engine *);
        int (*fini)(struct nvkm_engine *, bool suspend);
+       int (*reset)(struct nvkm_engine *);
        void (*intr)(struct nvkm_engine *);
        void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *);
        bool (*chsw_load)(struct nvkm_engine *);
@@ -48,6 +49,7 @@ int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *,
 
 struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *);
 void nvkm_engine_unref(struct nvkm_engine **);
+int nvkm_engine_reset(struct nvkm_engine *);
 void nvkm_engine_tile(struct nvkm_engine *, int region);
 bool nvkm_engine_chsw_load(struct nvkm_engine *);
 #endif
index 964615a6099718ff9fcbea8c72415212a6076bc4..36a31e9eea228eaec5269431daedd697c96cb50f 100644 (file)
@@ -35,6 +35,16 @@ nvkm_engine_chsw_load(struct nvkm_engine *engine)
        return false;
 }
 
+int
+nvkm_engine_reset(struct nvkm_engine *engine)
+{
+       if (engine->func->reset)
+               return engine->func->reset(engine);
+
+       nvkm_subdev_fini(&engine->subdev, false);
+       return nvkm_subdev_init(&engine->subdev);
+}
+
 void
 nvkm_engine_unref(struct nvkm_engine **pengine)
 {
index fe51c075d6c41872aea63ccbb4992ae8b080a832..b5836cbc29aa3cbe03019d0d7097152653fd8ac7 100644 (file)
@@ -113,8 +113,8 @@ nvkm_runl_rc(struct nvkm_runl *runl)
                }
 
                ENGN_DEBUG(engn, "resetting...");
-               nvkm_subdev_fini(&engn->engine->subdev, false);
-               WARN_ON(nvkm_subdev_init(&engn->engine->subdev));
+               /*TODO: can we do something less of a potential catastrophe on failure? */
+               WARN_ON(nvkm_engine_reset(engn->engine));
        }
 
        /* Submit runlist update, and clear any remaining exception state. */