Commit b38a2322 authored by Ben Skeggs's avatar Ben Skeggs

drm/nv50-/disp: add support for completion events

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 996f5a08
...@@ -68,6 +68,10 @@ gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -68,6 +68,10 @@ gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = gm107_disp_base_oclass; nv_engine(priv)->sclass = gm107_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nvd0_disp_intr; nv_subdev(priv)->intr = nvd0_disp_intr;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <core/enum.h> #include <core/enum.h>
#include <nvif/unpack.h> #include <nvif/unpack.h>
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/event.h>
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/dcb.h> #include <subdev/bios/dcb.h>
...@@ -82,6 +83,71 @@ nv50_disp_chan_destroy(struct nv50_disp_chan *chan) ...@@ -82,6 +83,71 @@ nv50_disp_chan_destroy(struct nv50_disp_chan *chan)
nouveau_namedb_destroy(&chan->base); nouveau_namedb_destroy(&chan->base);
} }
static void
nv50_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
{
struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000000 << index);
}
static void
nv50_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
{
struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000001 << index);
}
void
nv50_disp_chan_uevent_send(struct nv50_disp_priv *priv, int chid)
{
struct nvif_notify_uevent_rep {
} rep;
nvkm_event_send(&priv->uevent, 1, chid, &rep, sizeof(rep));
}
int
nv50_disp_chan_uevent_ctor(struct nouveau_object *object, void *data, u32 size,
struct nvkm_notify *notify)
{
struct nv50_disp_dmac *dmac = (void *)object;
union {
struct nvif_notify_uevent_req none;
} *args = data;
int ret;
if (nvif_unvers(args->none)) {
notify->size = sizeof(struct nvif_notify_uevent_rep);
notify->types = 1;
notify->index = dmac->base.chid;
return 0;
}
return ret;
}
const struct nvkm_event_func
nv50_disp_chan_uevent = {
.ctor = nv50_disp_chan_uevent_ctor,
.init = nv50_disp_chan_uevent_init,
.fini = nv50_disp_chan_uevent_fini,
};
int
nv50_disp_chan_ntfy(struct nouveau_object *object, u32 type,
struct nvkm_event **pevent)
{
struct nv50_disp_priv *priv = (void *)object->engine;
switch (type) {
case NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT:
*pevent = &priv->uevent;
return 0;
default:
break;
}
return -EINVAL;
}
int int
nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size) nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size)
{ {
...@@ -195,7 +261,7 @@ nv50_disp_dmac_init(struct nouveau_object *object) ...@@ -195,7 +261,7 @@ nv50_disp_dmac_init(struct nouveau_object *object)
return ret; return ret;
/* enable error reporting */ /* enable error reporting */
nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00010001 << chid); nv_mask(priv, 0x610028, 0x00010000 << chid, 0x00010000 << chid);
/* initialise channel for dma command submission */ /* initialise channel for dma command submission */
nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push); nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push);
...@@ -232,7 +298,7 @@ nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend) ...@@ -232,7 +298,7 @@ nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend)
return -EBUSY; return -EBUSY;
} }
/* disable error reporting */ /* disable error reporting and completion notifications */
nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid); nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid);
return nv50_disp_chan_fini(&dmac->base, suspend); return nv50_disp_chan_fini(&dmac->base, suspend);
...@@ -454,7 +520,7 @@ nv50_disp_mast_init(struct nouveau_object *object) ...@@ -454,7 +520,7 @@ nv50_disp_mast_init(struct nouveau_object *object)
return ret; return ret;
/* enable error reporting */ /* enable error reporting */
nv_mask(priv, 0x610028, 0x00010001, 0x00010001); nv_mask(priv, 0x610028, 0x00010000, 0x00010000);
/* attempt to unstick channel from some unknown state */ /* attempt to unstick channel from some unknown state */
if ((nv_rd32(priv, 0x610200) & 0x009f0000) == 0x00020000) if ((nv_rd32(priv, 0x610200) & 0x009f0000) == 0x00020000)
...@@ -494,7 +560,7 @@ nv50_disp_mast_fini(struct nouveau_object *object, bool suspend) ...@@ -494,7 +560,7 @@ nv50_disp_mast_fini(struct nouveau_object *object, bool suspend)
return -EBUSY; return -EBUSY;
} }
/* disable error reporting */ /* disable error reporting and completion notifications */
nv_mask(priv, 0x610028, 0x00010001, 0x00000000); nv_mask(priv, 0x610028, 0x00010001, 0x00000000);
return nv50_disp_chan_fini(&mast->base, suspend); return nv50_disp_chan_fini(&mast->base, suspend);
...@@ -507,6 +573,7 @@ nv50_disp_mast_ofuncs = { ...@@ -507,6 +573,7 @@ nv50_disp_mast_ofuncs = {
.base.init = nv50_disp_mast_init, .base.init = nv50_disp_mast_init,
.base.fini = nv50_disp_mast_fini, .base.fini = nv50_disp_mast_fini,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.ntfy = nv50_disp_chan_ntfy,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
.chid = 0, .chid = 0,
...@@ -607,6 +674,7 @@ nv50_disp_sync_ofuncs = { ...@@ -607,6 +674,7 @@ nv50_disp_sync_ofuncs = {
.base.dtor = nv50_disp_dmac_dtor, .base.dtor = nv50_disp_dmac_dtor,
.base.init = nv50_disp_dmac_init, .base.init = nv50_disp_dmac_init,
.base.fini = nv50_disp_dmac_fini, .base.fini = nv50_disp_dmac_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -696,6 +764,7 @@ nv50_disp_ovly_ofuncs = { ...@@ -696,6 +764,7 @@ nv50_disp_ovly_ofuncs = {
.base.dtor = nv50_disp_dmac_dtor, .base.dtor = nv50_disp_dmac_dtor,
.base.init = nv50_disp_dmac_init, .base.init = nv50_disp_dmac_init,
.base.fini = nv50_disp_dmac_fini, .base.fini = nv50_disp_dmac_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -813,6 +882,7 @@ nv50_disp_oimm_ofuncs = { ...@@ -813,6 +882,7 @@ nv50_disp_oimm_ofuncs = {
.base.dtor = nv50_disp_pioc_dtor, .base.dtor = nv50_disp_pioc_dtor,
.base.init = nv50_disp_pioc_init, .base.init = nv50_disp_pioc_init,
.base.fini = nv50_disp_pioc_fini, .base.fini = nv50_disp_pioc_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -860,6 +930,7 @@ nv50_disp_curs_ofuncs = { ...@@ -860,6 +930,7 @@ nv50_disp_curs_ofuncs = {
.base.dtor = nv50_disp_pioc_dtor, .base.dtor = nv50_disp_pioc_dtor,
.base.init = nv50_disp_pioc_init, .base.init = nv50_disp_pioc_init,
.base.fini = nv50_disp_pioc_fini, .base.fini = nv50_disp_pioc_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -1846,6 +1917,12 @@ nv50_disp_intr(struct nouveau_subdev *subdev) ...@@ -1846,6 +1917,12 @@ nv50_disp_intr(struct nouveau_subdev *subdev)
intr0 &= ~(0x00010000 << chid); intr0 &= ~(0x00010000 << chid);
} }
while (intr0 & 0x0000001f) {
u32 chid = __ffs(intr0 & 0x0000001f);
nv50_disp_chan_uevent_send(priv, chid);
intr0 &= ~(0x00000001 << chid);
}
if (intr1 & 0x00000004) { if (intr1 & 0x00000004) {
nouveau_disp_vblank(&priv->base, 0); nouveau_disp_vblank(&priv->base, 0);
nv_wr32(priv, 0x610024, 0x00000004); nv_wr32(priv, 0x610024, 0x00000004);
...@@ -1880,6 +1957,10 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -1880,6 +1957,10 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = nv50_disp_base_oclass; nv_engine(priv)->sclass = nv50_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr; nv_subdev(priv)->intr = nv50_disp_intr;
......
...@@ -26,6 +26,8 @@ struct nv50_disp_priv { ...@@ -26,6 +26,8 @@ struct nv50_disp_priv {
struct work_struct supervisor; struct work_struct supervisor;
u32 super; u32 super;
struct nvkm_event uevent;
struct { struct {
int nr; int nr;
} head; } head;
...@@ -116,9 +118,16 @@ struct nv50_disp_chan { ...@@ -116,9 +118,16 @@ struct nv50_disp_chan {
int chid; int chid;
}; };
int nv50_disp_chan_ntfy(struct nouveau_object *, u32, struct nvkm_event **);
int nv50_disp_chan_map(struct nouveau_object *, u64 *, u32 *); int nv50_disp_chan_map(struct nouveau_object *, u64 *, u32 *);
u32 nv50_disp_chan_rd32(struct nouveau_object *, u64); u32 nv50_disp_chan_rd32(struct nouveau_object *, u64);
void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32); void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32);
extern const struct nvkm_event_func nv50_disp_chan_uevent;
int nv50_disp_chan_uevent_ctor(struct nouveau_object *, void *, u32,
struct nvkm_notify *);
void nv50_disp_chan_uevent_send(struct nv50_disp_priv *, int);
extern const struct nvkm_event_func nvd0_disp_chan_uevent;
#define nv50_disp_chan_init(a) \ #define nv50_disp_chan_init(a) \
nouveau_namedb_init(&(a)->base) nouveau_namedb_init(&(a)->base)
......
...@@ -236,6 +236,10 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -236,6 +236,10 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = nv84_disp_base_oclass; nv_engine(priv)->sclass = nv84_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr; nv_subdev(priv)->intr = nv50_disp_intr;
......
...@@ -95,6 +95,10 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -95,6 +95,10 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = nv94_disp_base_oclass; nv_engine(priv)->sclass = nv94_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr; nv_subdev(priv)->intr = nv50_disp_intr;
......
...@@ -112,6 +112,10 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -112,6 +112,10 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = nva0_disp_base_oclass; nv_engine(priv)->sclass = nva0_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr; nv_subdev(priv)->intr = nv50_disp_intr;
......
...@@ -67,6 +67,10 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -67,6 +67,10 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = nva3_disp_base_oclass; nv_engine(priv)->sclass = nva3_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr; nv_subdev(priv)->intr = nv50_disp_intr;
......
...@@ -42,6 +42,31 @@ ...@@ -42,6 +42,31 @@
#include "nv50.h" #include "nv50.h"
/*******************************************************************************
* EVO channel base class
******************************************************************************/
static void
nvd0_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
{
struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
nv_mask(priv, 0x610090, 0x00000001 << index, 0x00000000 << index);
}
static void
nvd0_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
{
struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
nv_mask(priv, 0x610090, 0x00000001 << index, 0x00000001 << index);
}
const struct nvkm_event_func
nvd0_disp_chan_uevent = {
.ctor = nv50_disp_chan_uevent_ctor,
.init = nvd0_disp_chan_uevent_init,
.fini = nvd0_disp_chan_uevent_fini,
};
/******************************************************************************* /*******************************************************************************
* EVO DMA channel base class * EVO DMA channel base class
******************************************************************************/ ******************************************************************************/
...@@ -77,7 +102,6 @@ nvd0_disp_dmac_init(struct nouveau_object *object) ...@@ -77,7 +102,6 @@ nvd0_disp_dmac_init(struct nouveau_object *object)
return ret; return ret;
/* enable error reporting */ /* enable error reporting */
nv_mask(priv, 0x610090, 0x00000001 << chid, 0x00000001 << chid);
nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid); nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
/* initialise channel for dma command submission */ /* initialise channel for dma command submission */
...@@ -115,7 +139,7 @@ nvd0_disp_dmac_fini(struct nouveau_object *object, bool suspend) ...@@ -115,7 +139,7 @@ nvd0_disp_dmac_fini(struct nouveau_object *object, bool suspend)
return -EBUSY; return -EBUSY;
} }
/* disable error reporting */ /* disable error reporting and completion notification */
nv_mask(priv, 0x610090, 0x00000001 << chid, 0x00000000); nv_mask(priv, 0x610090, 0x00000001 << chid, 0x00000000);
nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000000); nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000000);
...@@ -278,7 +302,6 @@ nvd0_disp_mast_init(struct nouveau_object *object) ...@@ -278,7 +302,6 @@ nvd0_disp_mast_init(struct nouveau_object *object)
return ret; return ret;
/* enable error reporting */ /* enable error reporting */
nv_mask(priv, 0x610090, 0x00000001, 0x00000001);
nv_mask(priv, 0x6100a0, 0x00000001, 0x00000001); nv_mask(priv, 0x6100a0, 0x00000001, 0x00000001);
/* initialise channel for dma command submission */ /* initialise channel for dma command submission */
...@@ -313,7 +336,7 @@ nvd0_disp_mast_fini(struct nouveau_object *object, bool suspend) ...@@ -313,7 +336,7 @@ nvd0_disp_mast_fini(struct nouveau_object *object, bool suspend)
return -EBUSY; return -EBUSY;
} }
/* disable error reporting */ /* disable error reporting and completion notification */
nv_mask(priv, 0x610090, 0x00000001, 0x00000000); nv_mask(priv, 0x610090, 0x00000001, 0x00000000);
nv_mask(priv, 0x6100a0, 0x00000001, 0x00000000); nv_mask(priv, 0x6100a0, 0x00000001, 0x00000000);
...@@ -326,6 +349,7 @@ nvd0_disp_mast_ofuncs = { ...@@ -326,6 +349,7 @@ nvd0_disp_mast_ofuncs = {
.base.dtor = nv50_disp_dmac_dtor, .base.dtor = nv50_disp_dmac_dtor,
.base.init = nvd0_disp_mast_init, .base.init = nvd0_disp_mast_init,
.base.fini = nvd0_disp_mast_fini, .base.fini = nvd0_disp_mast_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -419,6 +443,7 @@ nvd0_disp_sync_ofuncs = { ...@@ -419,6 +443,7 @@ nvd0_disp_sync_ofuncs = {
.base.dtor = nv50_disp_dmac_dtor, .base.dtor = nv50_disp_dmac_dtor,
.base.init = nvd0_disp_dmac_init, .base.init = nvd0_disp_dmac_init,
.base.fini = nvd0_disp_dmac_fini, .base.fini = nvd0_disp_dmac_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -499,6 +524,7 @@ nvd0_disp_ovly_ofuncs = { ...@@ -499,6 +524,7 @@ nvd0_disp_ovly_ofuncs = {
.base.dtor = nv50_disp_dmac_dtor, .base.dtor = nv50_disp_dmac_dtor,
.base.init = nvd0_disp_dmac_init, .base.init = nvd0_disp_dmac_init,
.base.fini = nvd0_disp_dmac_fini, .base.fini = nvd0_disp_dmac_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -524,7 +550,6 @@ nvd0_disp_pioc_init(struct nouveau_object *object) ...@@ -524,7 +550,6 @@ nvd0_disp_pioc_init(struct nouveau_object *object)
return ret; return ret;
/* enable error reporting */ /* enable error reporting */
nv_mask(priv, 0x610090, 0x00000001 << chid, 0x00000001 << chid);
nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid); nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
/* activate channel */ /* activate channel */
...@@ -553,7 +578,7 @@ nvd0_disp_pioc_fini(struct nouveau_object *object, bool suspend) ...@@ -553,7 +578,7 @@ nvd0_disp_pioc_fini(struct nouveau_object *object, bool suspend)
return -EBUSY; return -EBUSY;
} }
/* disable error reporting */ /* disable error reporting and completion notification */
nv_mask(priv, 0x610090, 0x00000001 << chid, 0x00000000); nv_mask(priv, 0x610090, 0x00000001 << chid, 0x00000000);
nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000000); nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000000);
...@@ -570,6 +595,7 @@ nvd0_disp_oimm_ofuncs = { ...@@ -570,6 +595,7 @@ nvd0_disp_oimm_ofuncs = {
.base.dtor = nv50_disp_pioc_dtor, .base.dtor = nv50_disp_pioc_dtor,
.base.init = nvd0_disp_pioc_init, .base.init = nvd0_disp_pioc_init,
.base.fini = nvd0_disp_pioc_fini, .base.fini = nvd0_disp_pioc_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -586,6 +612,7 @@ nvd0_disp_curs_ofuncs = { ...@@ -586,6 +612,7 @@ nvd0_disp_curs_ofuncs = {
.base.dtor = nv50_disp_pioc_dtor, .base.dtor = nv50_disp_pioc_dtor,
.base.init = nvd0_disp_pioc_init, .base.init = nvd0_disp_pioc_init,
.base.fini = nvd0_disp_pioc_fini, .base.fini = nvd0_disp_pioc_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map, .base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32, .base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32, .base.wr32 = nv50_disp_chan_wr32,
...@@ -1153,7 +1180,11 @@ nvd0_disp_intr(struct nouveau_subdev *subdev) ...@@ -1153,7 +1180,11 @@ nvd0_disp_intr(struct nouveau_subdev *subdev)
if (intr & 0x00000001) { if (intr & 0x00000001) {
u32 stat = nv_rd32(priv, 0x61008c); u32 stat = nv_rd32(priv, 0x61008c);
nv_wr32(priv, 0x61008c, stat); while (stat) {
int chid = __ffs(stat); stat &= ~(1 << chid);
nv50_disp_chan_uevent_send(priv, chid);
nv_wr32(priv, 0x61008c, 1 << chid);
}
intr &= ~0x00000001; intr &= ~0x00000001;
} }
...@@ -1209,6 +1240,10 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -1209,6 +1240,10 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = nvd0_disp_base_oclass; nv_engine(priv)->sclass = nvd0_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nvd0_disp_intr; nv_subdev(priv)->intr = nvd0_disp_intr;
......
...@@ -233,6 +233,10 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -233,6 +233,10 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = nve0_disp_base_oclass; nv_engine(priv)->sclass = nve0_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nvd0_disp_intr; nv_subdev(priv)->intr = nvd0_disp_intr;
......
...@@ -68,6 +68,10 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -68,6 +68,10 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = nvf0_disp_base_oclass; nv_engine(priv)->sclass = nvf0_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass; nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nvd0_disp_intr; nv_subdev(priv)->intr = nvd0_disp_intr;
......
...@@ -479,6 +479,8 @@ struct nv50_disp_core_channel_dma_v0 { ...@@ -479,6 +479,8 @@ struct nv50_disp_core_channel_dma_v0 {
__u32 pushbuf; __u32 pushbuf;
}; };
#define NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
/* cursor immediate */ /* cursor immediate */
struct nv50_disp_cursor_v0 { struct nv50_disp_cursor_v0 {
__u8 version; __u8 version;
...@@ -486,6 +488,8 @@ struct nv50_disp_cursor_v0 { ...@@ -486,6 +488,8 @@ struct nv50_disp_cursor_v0 {
__u8 pad02[6]; __u8 pad02[6];
}; };
#define NV50_DISP_CURSOR_V0_NTFY_UEVENT 0x00
/* base */ /* base */
struct nv50_disp_base_channel_dma_v0 { struct nv50_disp_base_channel_dma_v0 {
__u8 version; __u8 version;
...@@ -494,6 +498,8 @@ struct nv50_disp_base_channel_dma_v0 { ...@@ -494,6 +498,8 @@ struct nv50_disp_base_channel_dma_v0 {
__u32 pushbuf; __u32 pushbuf;
}; };
#define NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
/* overlay */ /* overlay */
struct nv50_disp_overlay_channel_dma_v0 { struct nv50_disp_overlay_channel_dma_v0 {
__u8 version; __u8 version;
...@@ -502,6 +508,8 @@ struct nv50_disp_overlay_channel_dma_v0 { ...@@ -502,6 +508,8 @@ struct nv50_disp_overlay_channel_dma_v0 {
__u32 pushbuf; __u32 pushbuf;
}; };
#define NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
/* overlay immediate */ /* overlay immediate */
struct nv50_disp_overlay_v0 { struct nv50_disp_overlay_v0 {
__u8 version; __u8 version;
...@@ -509,6 +517,7 @@ struct nv50_disp_overlay_v0 { ...@@ -509,6 +517,7 @@ struct nv50_disp_overlay_v0 {
__u8 pad02[6]; __u8 pad02[6];
}; };
#define NV50_DISP_OVERLAY_V0_NTFY_UEVENT 0x00
/******************************************************************************* /*******************************************************************************
* fermi * fermi
......
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