Commit a9c44a88 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/disp/nv50-: add channel interfaces to control error interrupts

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: default avatarBen Skeggs <bskeggs@redhat.com>
parent 4a8621a2
...@@ -47,3 +47,16 @@ gf119_disp_chan_uevent = { ...@@ -47,3 +47,16 @@ gf119_disp_chan_uevent = {
.init = gf119_disp_chan_uevent_init, .init = gf119_disp_chan_uevent_init,
.fini = gf119_disp_chan_uevent_fini, .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);
}
}
...@@ -162,6 +162,15 @@ nv50_disp_chan_user(struct nv50_disp_chan *chan, u64 *psize) ...@@ -162,6 +162,15 @@ nv50_disp_chan_user(struct nv50_disp_chan *chan, u64 *psize)
return 0x640000 + (chan->chid.user * 0x1000); 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 static int
nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data) 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) ...@@ -288,6 +297,7 @@ nv50_disp_chan_fini(struct nvkm_object *object, bool suspend)
{ {
struct nv50_disp_chan *chan = nv50_disp_chan(object); struct nv50_disp_chan *chan = nv50_disp_chan(object);
chan->func->fini(chan); chan->func->fini(chan);
chan->func->intr(chan, false);
return 0; return 0;
} }
...@@ -295,6 +305,7 @@ static int ...@@ -295,6 +305,7 @@ static int
nv50_disp_chan_init(struct nvkm_object *object) nv50_disp_chan_init(struct nvkm_object *object)
{ {
struct nv50_disp_chan *chan = nv50_disp_chan(object); struct nv50_disp_chan *chan = nv50_disp_chan(object);
chan->func->intr(chan, true);
return chan->func->init(chan); return chan->func->init(chan);
} }
......
...@@ -25,6 +25,7 @@ struct nv50_disp_chan { ...@@ -25,6 +25,7 @@ struct nv50_disp_chan {
struct nv50_disp_chan_func { struct nv50_disp_chan_func {
int (*init)(struct nv50_disp_chan *); int (*init)(struct nv50_disp_chan *);
void (*fini)(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); u64 (*user)(struct nv50_disp_chan *, u64 *size);
int (*bind)(struct nv50_disp_chan *, struct nvkm_object *, u32 handle); 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 *, ...@@ -38,12 +39,14 @@ int nv50_disp_dmac_new_(const struct nv50_disp_chan_func *,
struct nv50_disp *, int chid, int head, u64 push, struct nv50_disp *, int chid, int head, u64 push,
const struct nvkm_oclass *, struct nvkm_object **); 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 *); 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_pioc_func;
extern const struct nv50_disp_chan_func nv50_disp_dmac_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); int nv50_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32);
extern const struct nv50_disp_chan_func nv50_disp_core_func; 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_pioc_func;
extern const struct nv50_disp_chan_func gf119_disp_dmac_func; extern const struct nv50_disp_chan_func gf119_disp_dmac_func;
void gf119_disp_dmac_fini(struct nv50_disp_chan *); void gf119_disp_dmac_fini(struct nv50_disp_chan *);
......
...@@ -182,10 +182,6 @@ gf119_disp_core_fini(struct nv50_disp_chan *chan) ...@@ -182,10 +182,6 @@ gf119_disp_core_fini(struct nv50_disp_chan *chan)
nvkm_error(subdev, "core fini: %08x\n", nvkm_error(subdev, "core fini: %08x\n",
nvkm_rd32(device, 0x610490)); nvkm_rd32(device, 0x610490));
} }
/* disable error reporting and completion notification */
nvkm_mask(device, 0x610090, 0x00000001, 0x00000000);
nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000000);
} }
static int static int
...@@ -194,9 +190,6 @@ gf119_disp_core_init(struct nv50_disp_chan *chan) ...@@ -194,9 +190,6 @@ gf119_disp_core_init(struct nv50_disp_chan *chan)
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
/* enable error reporting */
nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000001);
/* initialise channel for dma command submission */ /* initialise channel for dma command submission */
nvkm_wr32(device, 0x610494, chan->push); nvkm_wr32(device, 0x610494, chan->push);
nvkm_wr32(device, 0x610498, 0x00010000); nvkm_wr32(device, 0x610498, 0x00010000);
...@@ -222,6 +215,7 @@ const struct nv50_disp_chan_func ...@@ -222,6 +215,7 @@ const struct nv50_disp_chan_func
gf119_disp_core_func = { gf119_disp_core_func = {
.init = gf119_disp_core_init, .init = gf119_disp_core_init,
.fini = gf119_disp_core_fini, .fini = gf119_disp_core_fini,
.intr = gf119_disp_chan_intr,
.user = nv50_disp_chan_user, .user = nv50_disp_chan_user,
.bind = gf119_disp_dmac_bind, .bind = gf119_disp_dmac_bind,
}; };
......
...@@ -31,9 +31,6 @@ gp102_disp_core_init(struct nv50_disp_chan *chan) ...@@ -31,9 +31,6 @@ gp102_disp_core_init(struct nv50_disp_chan *chan)
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
/* enable error reporting */
nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000001);
/* initialise channel for dma command submission */ /* initialise channel for dma command submission */
nvkm_wr32(device, 0x611494, chan->push); nvkm_wr32(device, 0x611494, chan->push);
nvkm_wr32(device, 0x611498, 0x00010000); nvkm_wr32(device, 0x611498, 0x00010000);
...@@ -59,6 +56,7 @@ static const struct nv50_disp_chan_func ...@@ -59,6 +56,7 @@ static const struct nv50_disp_chan_func
gp102_disp_core_func = { gp102_disp_core_func = {
.init = gp102_disp_core_init, .init = gp102_disp_core_init,
.fini = gf119_disp_core_fini, .fini = gf119_disp_core_fini,
.intr = gf119_disp_chan_intr,
.user = nv50_disp_chan_user, .user = nv50_disp_chan_user,
.bind = gf119_disp_dmac_bind, .bind = gf119_disp_dmac_bind,
}; };
......
...@@ -179,9 +179,6 @@ nv50_disp_core_fini(struct nv50_disp_chan *chan) ...@@ -179,9 +179,6 @@ nv50_disp_core_fini(struct nv50_disp_chan *chan)
nvkm_error(subdev, "core fini: %08x\n", nvkm_error(subdev, "core fini: %08x\n",
nvkm_rd32(device, 0x610200)); nvkm_rd32(device, 0x610200));
} }
/* disable error reporting and completion notifications */
nvkm_mask(device, 0x610028, 0x00010001, 0x00000000);
} }
static int static int
...@@ -190,9 +187,6 @@ nv50_disp_core_init(struct nv50_disp_chan *chan) ...@@ -190,9 +187,6 @@ nv50_disp_core_init(struct nv50_disp_chan *chan)
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
/* enable error reporting */
nvkm_mask(device, 0x610028, 0x00010000, 0x00010000);
/* attempt to unstick channel from some unknown state */ /* attempt to unstick channel from some unknown state */
if ((nvkm_rd32(device, 0x610200) & 0x009f0000) == 0x00020000) if ((nvkm_rd32(device, 0x610200) & 0x009f0000) == 0x00020000)
nvkm_mask(device, 0x610200, 0x00800000, 0x00800000); nvkm_mask(device, 0x610200, 0x00800000, 0x00800000);
...@@ -224,6 +218,7 @@ const struct nv50_disp_chan_func ...@@ -224,6 +218,7 @@ const struct nv50_disp_chan_func
nv50_disp_core_func = { nv50_disp_core_func = {
.init = nv50_disp_core_init, .init = nv50_disp_core_init,
.fini = nv50_disp_core_fini, .fini = nv50_disp_core_fini,
.intr = nv50_disp_chan_intr,
.user = nv50_disp_chan_user, .user = nv50_disp_chan_user,
.bind = nv50_disp_dmac_bind, .bind = nv50_disp_dmac_bind,
}; };
......
...@@ -53,10 +53,6 @@ gf119_disp_dmac_fini(struct nv50_disp_chan *chan) ...@@ -53,10 +53,6 @@ gf119_disp_dmac_fini(struct nv50_disp_chan *chan)
nvkm_error(subdev, "ch %d fini: %08x\n", user, nvkm_error(subdev, "ch %d fini: %08x\n", user,
nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); 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 static int
...@@ -67,9 +63,6 @@ gf119_disp_dmac_init(struct nv50_disp_chan *chan) ...@@ -67,9 +63,6 @@ gf119_disp_dmac_init(struct nv50_disp_chan *chan)
int ctrl = chan->chid.ctrl; int ctrl = chan->chid.ctrl;
int user = chan->chid.user; int user = chan->chid.user;
/* enable error reporting */
nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
/* initialise channel for dma command submission */ /* initialise channel for dma command submission */
nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push); nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push);
nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000); nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000);
...@@ -95,6 +88,7 @@ const struct nv50_disp_chan_func ...@@ -95,6 +88,7 @@ const struct nv50_disp_chan_func
gf119_disp_dmac_func = { gf119_disp_dmac_func = {
.init = gf119_disp_dmac_init, .init = gf119_disp_dmac_init,
.fini = gf119_disp_dmac_fini, .fini = gf119_disp_dmac_fini,
.intr = gf119_disp_chan_intr,
.user = nv50_disp_chan_user, .user = nv50_disp_chan_user,
.bind = gf119_disp_dmac_bind, .bind = gf119_disp_dmac_bind,
}; };
...@@ -33,9 +33,6 @@ gp102_disp_dmac_init(struct nv50_disp_chan *chan) ...@@ -33,9 +33,6 @@ gp102_disp_dmac_init(struct nv50_disp_chan *chan)
int ctrl = chan->chid.ctrl; int ctrl = chan->chid.ctrl;
int user = chan->chid.user; int user = chan->chid.user;
/* enable error reporting */
nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
/* initialise channel for dma command submission */ /* initialise channel for dma command submission */
nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push); nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push);
nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000); nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000);
...@@ -61,6 +58,7 @@ const struct nv50_disp_chan_func ...@@ -61,6 +58,7 @@ const struct nv50_disp_chan_func
gp102_disp_dmac_func = { gp102_disp_dmac_func = {
.init = gp102_disp_dmac_init, .init = gp102_disp_dmac_init,
.fini = gf119_disp_dmac_fini, .fini = gf119_disp_dmac_fini,
.intr = gf119_disp_chan_intr,
.user = nv50_disp_chan_user, .user = nv50_disp_chan_user,
.bind = gf119_disp_dmac_bind, .bind = gf119_disp_dmac_bind,
}; };
...@@ -96,9 +96,6 @@ nv50_disp_dmac_fini(struct nv50_disp_chan *chan) ...@@ -96,9 +96,6 @@ nv50_disp_dmac_fini(struct nv50_disp_chan *chan)
nvkm_error(subdev, "ch %d fini timeout, %08x\n", user, nvkm_error(subdev, "ch %d fini timeout, %08x\n", user,
nvkm_rd32(device, 0x610200 + (ctrl * 0x10))); nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
} }
/* disable error reporting and completion notifications */
nvkm_mask(device, 0x610028, 0x00010001 << user, 0x00000000 << user);
} }
static int static int
...@@ -109,9 +106,6 @@ nv50_disp_dmac_init(struct nv50_disp_chan *chan) ...@@ -109,9 +106,6 @@ nv50_disp_dmac_init(struct nv50_disp_chan *chan)
int ctrl = chan->chid.ctrl; int ctrl = chan->chid.ctrl;
int user = chan->chid.user; int user = chan->chid.user;
/* enable error reporting */
nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user);
/* initialise channel for dma command submission */ /* initialise channel for dma command submission */
nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push); nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push);
nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000); nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000);
...@@ -137,6 +131,7 @@ const struct nv50_disp_chan_func ...@@ -137,6 +131,7 @@ const struct nv50_disp_chan_func
nv50_disp_dmac_func = { nv50_disp_dmac_func = {
.init = nv50_disp_dmac_init, .init = nv50_disp_dmac_init,
.fini = nv50_disp_dmac_fini, .fini = nv50_disp_dmac_fini,
.intr = nv50_disp_chan_intr,
.user = nv50_disp_chan_user, .user = nv50_disp_chan_user,
.bind = nv50_disp_dmac_bind, .bind = nv50_disp_dmac_bind,
}; };
...@@ -43,10 +43,6 @@ gf119_disp_pioc_fini(struct nv50_disp_chan *chan) ...@@ -43,10 +43,6 @@ gf119_disp_pioc_fini(struct nv50_disp_chan *chan)
nvkm_error(subdev, "ch %d fini: %08x\n", user, nvkm_error(subdev, "ch %d fini: %08x\n", user,
nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); 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 static int
...@@ -58,9 +54,6 @@ gf119_disp_pioc_init(struct nv50_disp_chan *chan) ...@@ -58,9 +54,6 @@ gf119_disp_pioc_init(struct nv50_disp_chan *chan)
int ctrl = chan->chid.ctrl; int ctrl = chan->chid.ctrl;
int user = chan->chid.user; int user = chan->chid.user;
/* enable error reporting */
nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
/* activate channel */ /* activate channel */
nvkm_wr32(device, 0x610490 + (ctrl * 0x10), 0x00000001); nvkm_wr32(device, 0x610490 + (ctrl * 0x10), 0x00000001);
if (nvkm_msec(device, 2000, if (nvkm_msec(device, 2000,
...@@ -80,5 +73,6 @@ const struct nv50_disp_chan_func ...@@ -80,5 +73,6 @@ const struct nv50_disp_chan_func
gf119_disp_pioc_func = { gf119_disp_pioc_func = {
.init = gf119_disp_pioc_init, .init = gf119_disp_pioc_init,
.fini = gf119_disp_pioc_fini, .fini = gf119_disp_pioc_fini,
.intr = gf119_disp_chan_intr,
.user = nv50_disp_chan_user, .user = nv50_disp_chan_user,
}; };
...@@ -82,5 +82,6 @@ const struct nv50_disp_chan_func ...@@ -82,5 +82,6 @@ const struct nv50_disp_chan_func
nv50_disp_pioc_func = { nv50_disp_pioc_func = {
.init = nv50_disp_pioc_init, .init = nv50_disp_pioc_init,
.fini = nv50_disp_pioc_fini, .fini = nv50_disp_pioc_fini,
.intr = nv50_disp_chan_intr,
.user = nv50_disp_chan_user, .user = nv50_disp_chan_user,
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment