]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/nouveau/gr/gf100-: expose fecs methods for pausing ctxsw
authorBen Skeggs <bskeggs@redhat.com>
Fri, 1 Feb 2019 03:52:50 +0000 (13:52 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 19 Feb 2019 23:00:00 +0000 (09:00 +1000)
MMU will need access to these.

v2. Apply fix from Rhys Kidd to send correct FECS method for STOP_CTXSW.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h

index ba1518ff8b66a4a8bae7f36b300017c8229ecb57..87cc7370a216f888b1f4d0fe2fc2bc2b29ada125 100644 (file)
@@ -10,6 +10,8 @@ struct nvkm_gr {
 
 u64 nvkm_gr_units(struct nvkm_gr *);
 int nvkm_gr_tlb_flush(struct nvkm_gr *);
+int nvkm_gr_ctxsw_pause(struct nvkm_device *);
+int nvkm_gr_ctxsw_resume(struct nvkm_device *);
 
 int nv04_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
 int nv10_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
index cd8cf6f7024c2c4b916ae20b1fda7e2ded9080e0..53f62827260b35f8007ecb6f9ac5c27e7fe9b62c 100644 (file)
 
 #include <engine/fifo.h>
 
+int
+nvkm_gr_ctxsw_resume(struct nvkm_device *device)
+{
+       struct nvkm_gr *gr = device->gr;
+       if (gr && gr->func->ctxsw.resume)
+               return gr->func->ctxsw.resume(gr);
+       return 0;
+}
+
+int
+nvkm_gr_ctxsw_pause(struct nvkm_device *device)
+{
+       struct nvkm_gr *gr = device->gr;
+       if (gr && gr->func->ctxsw.pause)
+               return gr->func->ctxsw.pause(gr);
+       return 0;
+}
+
 static bool
 nvkm_gr_chsw_load(struct nvkm_engine *engine)
 {
index bfe740033cf4eca0eb9ac73a8d1b2ef20cffbbc2..63802edf89d464bab36c4cce4293d4345302c953 100644 (file)
@@ -715,6 +715,56 @@ gf100_gr_pack_mmio[] = {
  * PGRAPH engine/subdev functions
  ******************************************************************************/
 
+static int
+gf100_gr_fecs_ctrl_ctxsw(struct gf100_gr *gr, u32 mthd)
+{
+       struct nvkm_device *device = gr->base.engine.subdev.device;
+
+       nvkm_wr32(device, 0x409804, 0xffffffff);
+       nvkm_wr32(device, 0x409840, 0xffffffff);
+       nvkm_wr32(device, 0x409500, 0xffffffff);
+       nvkm_wr32(device, 0x409504, mthd);
+       nvkm_msec(device, 2000,
+               u32 stat = nvkm_rd32(device, 0x409804);
+               if (stat == 0x00000002)
+                       return -EIO;
+               if (stat == 0x00000001)
+                       return 0;
+       );
+
+       return -ETIMEDOUT;
+}
+
+int
+gf100_gr_fecs_start_ctxsw(struct nvkm_gr *base)
+{
+       struct gf100_gr *gr = gf100_gr(base);
+       int ret = 0;
+
+       mutex_lock(&gr->fecs.mutex);
+       if (!--gr->fecs.disable) {
+               if (WARN_ON(ret = gf100_gr_fecs_ctrl_ctxsw(gr, 0x39)))
+                       gr->fecs.disable++;
+       }
+       mutex_unlock(&gr->fecs.mutex);
+       return ret;
+}
+
+int
+gf100_gr_fecs_stop_ctxsw(struct nvkm_gr *base)
+{
+       struct gf100_gr *gr = gf100_gr(base);
+       int ret = 0;
+
+       mutex_lock(&gr->fecs.mutex);
+       if (!gr->fecs.disable++) {
+               if (WARN_ON(ret = gf100_gr_fecs_ctrl_ctxsw(gr, 0x38)))
+                       gr->fecs.disable--;
+       }
+       mutex_unlock(&gr->fecs.mutex);
+       return ret;
+}
+
 int
 gf100_gr_fecs_bind_pointer(struct gf100_gr *gr, u32 inst)
 {
@@ -1891,6 +1941,8 @@ gf100_gr_oneinit(struct nvkm_gr *base)
        if (ret)
                return ret;
 
+       mutex_init(&gr->fecs.mutex);
+
        ret = nvkm_falcon_v1_new(subdev, "GPCCS", 0x41a000, &gr->gpccs.falcon);
        if (ret)
                return ret;
@@ -2004,6 +2056,8 @@ gf100_gr_ = {
        .chan_new = gf100_gr_chan_new,
        .object_get = gf100_gr_object_get,
        .chsw_load = gf100_gr_chsw_load,
+       .ctxsw.pause = gf100_gr_fecs_stop_ctxsw,
+       .ctxsw.resume = gf100_gr_fecs_start_ctxsw,
 };
 
 int
index 2c031af6881afc615dafd796b8ab134a98b443c9..fafdd0bbea9bdb705e3205f2302c6d8027ae7c57 100644 (file)
@@ -84,6 +84,8 @@ struct gf100_gr {
 
        struct {
                struct nvkm_falcon *falcon;
+               struct mutex mutex;
+               u32 disable;
        } fecs;
 
        struct {
index 66359c23cbce278bfaad51e963dc0a7cdaa70923..b8023a6b77a181a09c568dfebe5b2d73539c4c9b 100644 (file)
@@ -27,6 +27,10 @@ struct nvkm_gr_func {
         */
        u64 (*units)(struct nvkm_gr *);
        bool (*chsw_load)(struct nvkm_gr *);
+       struct {
+               int (*pause)(struct nvkm_gr *);
+               int (*resume)(struct nvkm_gr *);
+       } ctxsw;
        struct nvkm_sclass sclass[];
 };