drm/nouveau/disp/nv50-: add channel interfaces to control error interrupts
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 May 2018 10:39:46 +0000 (20:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 18 May 2018 05:01:21 +0000 (15:01 +1000)
This will be required to support Volta, but also allows us to remove code
that's duplicated for each channel type already.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c

index 17a3d835cb4240ce7a564b0aab93ee154249a878..29e6dd58ac48ccc896d93eee82201fe5126ae174 100644 (file)
@@ -47,3 +47,16 @@ gf119_disp_chan_uevent = {
        .init = gf119_disp_chan_uevent_init,
        .fini = gf119_disp_chan_uevent_fini,
 };
+
+void
+gf119_disp_chan_intr(struct nv50_disp_chan *chan, bool en)
+{
+       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
+       const u64 mask = 0x00000001 << chan->chid.user;
+       if (!en) {
+               nvkm_mask(device, 0x610090, mask, 0x00000000);
+               nvkm_mask(device, 0x6100a0, mask, 0x00000000);
+       } else {
+               nvkm_mask(device, 0x6100a0, mask, mask);
+       }
+}
index 8e79aa5f52e696c64660abc85789b11d9e0e0e6f..53c3ed6da9aea36e59c6ab0f7a58bfcd75750b19 100644 (file)
@@ -162,6 +162,15 @@ nv50_disp_chan_user(struct nv50_disp_chan *chan, u64 *psize)
        return 0x640000 + (chan->chid.user * 0x1000);
 }
 
+void
+nv50_disp_chan_intr(struct nv50_disp_chan *chan, bool en)
+{
+       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
+       const u64 mask = 0x00010001 << chan->chid.user;
+       const u64 data = en ? 0x00010000 : 0x00000000;
+       nvkm_mask(device, 0x610028, mask, data);
+}
+
 static int
 nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data)
 {
@@ -288,6 +297,7 @@ nv50_disp_chan_fini(struct nvkm_object *object, bool suspend)
 {
        struct nv50_disp_chan *chan = nv50_disp_chan(object);
        chan->func->fini(chan);
+       chan->func->intr(chan, false);
        return 0;
 }
 
@@ -295,6 +305,7 @@ static int
 nv50_disp_chan_init(struct nvkm_object *object)
 {
        struct nv50_disp_chan *chan = nv50_disp_chan(object);
+       chan->func->intr(chan, true);
        return chan->func->init(chan);
 }
 
index 75ae181da0e813affd3532019e9e558fc42a97a3..2a48243b00aea128d74ef3cd2dc1716e3ca11f11 100644 (file)
@@ -25,6 +25,7 @@ struct nv50_disp_chan {
 struct nv50_disp_chan_func {
        int (*init)(struct nv50_disp_chan *);
        void (*fini)(struct nv50_disp_chan *);
+       void (*intr)(struct nv50_disp_chan *, bool en);
        u64 (*user)(struct nv50_disp_chan *, u64 *size);
        int (*bind)(struct nv50_disp_chan *, struct nvkm_object *, u32 handle);
 };
@@ -38,12 +39,14 @@ int nv50_disp_dmac_new_(const struct nv50_disp_chan_func *,
                        struct nv50_disp *, int chid, int head, u64 push,
                        const struct nvkm_oclass *, struct nvkm_object **);
 
+void nv50_disp_chan_intr(struct nv50_disp_chan *, bool);
 u64 nv50_disp_chan_user(struct nv50_disp_chan *, u64 *);
 extern const struct nv50_disp_chan_func nv50_disp_pioc_func;
 extern const struct nv50_disp_chan_func nv50_disp_dmac_func;
 int nv50_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32);
 extern const struct nv50_disp_chan_func nv50_disp_core_func;
 
+void gf119_disp_chan_intr(struct nv50_disp_chan *, bool);
 extern const struct nv50_disp_chan_func gf119_disp_pioc_func;
 extern const struct nv50_disp_chan_func gf119_disp_dmac_func;
 void gf119_disp_dmac_fini(struct nv50_disp_chan *);
index 9ba4a8cd3dba2aceae766d7ecb3cc1a780582c1b..d162b9cf4eac6fa4a48c3bf6511582d240d5ef94 100644 (file)
@@ -182,10 +182,6 @@ gf119_disp_core_fini(struct nv50_disp_chan *chan)
                nvkm_error(subdev, "core fini: %08x\n",
                           nvkm_rd32(device, 0x610490));
        }
-
-       /* disable error reporting and completion notification */
-       nvkm_mask(device, 0x610090, 0x00000001, 0x00000000);
-       nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000000);
 }
 
 static int
@@ -194,9 +190,6 @@ gf119_disp_core_init(struct nv50_disp_chan *chan)
        struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
        struct nvkm_device *device = subdev->device;
 
-       /* enable error reporting */
-       nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000001);
-
        /* initialise channel for dma command submission */
        nvkm_wr32(device, 0x610494, chan->push);
        nvkm_wr32(device, 0x610498, 0x00010000);
@@ -222,6 +215,7 @@ const struct nv50_disp_chan_func
 gf119_disp_core_func = {
        .init = gf119_disp_core_init,
        .fini = gf119_disp_core_fini,
+       .intr = gf119_disp_chan_intr,
        .user = nv50_disp_chan_user,
        .bind = gf119_disp_dmac_bind,
 };
index aae5db4dc622e2d7c74b65622a334d25aca7ae5e..5b7f993c73c7322cce3dafb3aa1f2243091f4b5b 100644 (file)
@@ -31,9 +31,6 @@ gp102_disp_core_init(struct nv50_disp_chan *chan)
        struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
        struct nvkm_device *device = subdev->device;
 
-       /* enable error reporting */
-       nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000001);
-
        /* initialise channel for dma command submission */
        nvkm_wr32(device, 0x611494, chan->push);
        nvkm_wr32(device, 0x611498, 0x00010000);
@@ -59,6 +56,7 @@ static const struct nv50_disp_chan_func
 gp102_disp_core_func = {
        .init = gp102_disp_core_init,
        .fini = gf119_disp_core_fini,
+       .intr = gf119_disp_chan_intr,
        .user = nv50_disp_chan_user,
        .bind = gf119_disp_dmac_bind,
 };
index 5fd449d32109dd2f04afef6d5f17a1cd2a3ade32..55db9a22b4be472d297436b878c4b96f72293989 100644 (file)
@@ -179,9 +179,6 @@ nv50_disp_core_fini(struct nv50_disp_chan *chan)
                nvkm_error(subdev, "core fini: %08x\n",
                           nvkm_rd32(device, 0x610200));
        }
-
-       /* disable error reporting and completion notifications */
-       nvkm_mask(device, 0x610028, 0x00010001, 0x00000000);
 }
 
 static int
@@ -190,9 +187,6 @@ nv50_disp_core_init(struct nv50_disp_chan *chan)
        struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
        struct nvkm_device *device = subdev->device;
 
-       /* enable error reporting */
-       nvkm_mask(device, 0x610028, 0x00010000, 0x00010000);
-
        /* attempt to unstick channel from some unknown state */
        if ((nvkm_rd32(device, 0x610200) & 0x009f0000) == 0x00020000)
                nvkm_mask(device, 0x610200, 0x00800000, 0x00800000);
@@ -224,6 +218,7 @@ const struct nv50_disp_chan_func
 nv50_disp_core_func = {
        .init = nv50_disp_core_init,
        .fini = nv50_disp_core_fini,
+       .intr = nv50_disp_chan_intr,
        .user = nv50_disp_chan_user,
        .bind = nv50_disp_dmac_bind,
 };
index 2a6d0728dd2e2140083c88ebbfd83d459007a4e9..edf7dd0d931df7a427228c3cfaaadd7d6c4041da 100644 (file)
@@ -53,10 +53,6 @@ gf119_disp_dmac_fini(struct nv50_disp_chan *chan)
                nvkm_error(subdev, "ch %d fini: %08x\n", user,
                           nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
        }
-
-       /* disable error reporting and completion notification */
-       nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000);
-       nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000);
 }
 
 static int
@@ -67,9 +63,6 @@ gf119_disp_dmac_init(struct nv50_disp_chan *chan)
        int ctrl = chan->chid.ctrl;
        int user = chan->chid.user;
 
-       /* enable error reporting */
-       nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
-
        /* initialise channel for dma command submission */
        nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push);
        nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000);
@@ -95,6 +88,7 @@ const struct nv50_disp_chan_func
 gf119_disp_dmac_func = {
        .init = gf119_disp_dmac_init,
        .fini = gf119_disp_dmac_fini,
+       .intr = gf119_disp_chan_intr,
        .user = nv50_disp_chan_user,
        .bind = gf119_disp_dmac_bind,
 };
index 7e6b308eb596a00e4859bd597b65bf5c6e91e9d2..f21a433199aa00ca96a6931aed2c8bc829343687 100644 (file)
@@ -33,9 +33,6 @@ gp102_disp_dmac_init(struct nv50_disp_chan *chan)
        int ctrl = chan->chid.ctrl;
        int user = chan->chid.user;
 
-       /* enable error reporting */
-       nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
-
        /* initialise channel for dma command submission */
        nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push);
        nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000);
@@ -61,6 +58,7 @@ const struct nv50_disp_chan_func
 gp102_disp_dmac_func = {
        .init = gp102_disp_dmac_init,
        .fini = gf119_disp_dmac_fini,
+       .intr = gf119_disp_chan_intr,
        .user = nv50_disp_chan_user,
        .bind = gf119_disp_dmac_bind,
 };
index 5db26e31a799af35e01ee92faa88305eef40f320..981b98def151e7633c22ca4b44aa034798821c7e 100644 (file)
@@ -96,9 +96,6 @@ nv50_disp_dmac_fini(struct nv50_disp_chan *chan)
                nvkm_error(subdev, "ch %d fini timeout, %08x\n", user,
                           nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
        }
-
-       /* disable error reporting and completion notifications */
-       nvkm_mask(device, 0x610028, 0x00010001 << user, 0x00000000 << user);
 }
 
 static int
@@ -109,9 +106,6 @@ nv50_disp_dmac_init(struct nv50_disp_chan *chan)
        int ctrl = chan->chid.ctrl;
        int user = chan->chid.user;
 
-       /* enable error reporting */
-       nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user);
-
        /* initialise channel for dma command submission */
        nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push);
        nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000);
@@ -137,6 +131,7 @@ const struct nv50_disp_chan_func
 nv50_disp_dmac_func = {
        .init = nv50_disp_dmac_init,
        .fini = nv50_disp_dmac_fini,
+       .intr = nv50_disp_chan_intr,
        .user = nv50_disp_chan_user,
        .bind = nv50_disp_dmac_bind,
 };
index 5970e40f4d69c3a9366ef882a3d0544fa45cad89..5296e7bee81334d4cb1f5f9ff377a78cec11d4d3 100644 (file)
@@ -43,10 +43,6 @@ gf119_disp_pioc_fini(struct nv50_disp_chan *chan)
                nvkm_error(subdev, "ch %d fini: %08x\n", user,
                           nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
        }
-
-       /* disable error reporting and completion notification */
-       nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000);
-       nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000);
 }
 
 static int
@@ -58,9 +54,6 @@ gf119_disp_pioc_init(struct nv50_disp_chan *chan)
        int ctrl = chan->chid.ctrl;
        int user = chan->chid.user;
 
-       /* enable error reporting */
-       nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
-
        /* activate channel */
        nvkm_wr32(device, 0x610490 + (ctrl * 0x10), 0x00000001);
        if (nvkm_msec(device, 2000,
@@ -80,5 +73,6 @@ const struct nv50_disp_chan_func
 gf119_disp_pioc_func = {
        .init = gf119_disp_pioc_init,
        .fini = gf119_disp_pioc_fini,
+       .intr = gf119_disp_chan_intr,
        .user = nv50_disp_chan_user,
 };
index 0a76bda4ef2a51d54effa94163f3c03d704cb6a9..4faed6fce682b95f69d4948bffe41fde5beeefea 100644 (file)
@@ -82,5 +82,6 @@ const struct nv50_disp_chan_func
 nv50_disp_pioc_func = {
        .init = nv50_disp_pioc_init,
        .fini = nv50_disp_pioc_fini,
+       .intr = nv50_disp_chan_intr,
        .user = nv50_disp_chan_user,
 };