Loading drivers/gpu/drm/nouveau/core/engine/disp/gm107.c +4 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,10 @@ gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (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)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nvd0_disp_intr; Loading drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +85 −4 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <core/enum.h> #include <nvif/unpack.h> #include <nvif/class.h> #include <nvif/event.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> Loading Loading @@ -82,6 +83,71 @@ nv50_disp_chan_destroy(struct nv50_disp_chan *chan) 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 nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size) { Loading Loading @@ -195,7 +261,7 @@ nv50_disp_dmac_init(struct nouveau_object *object) return ret; /* 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 */ nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push); Loading Loading @@ -232,7 +298,7 @@ nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend) return -EBUSY; } /* disable error reporting */ /* disable error reporting and completion notifications */ nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid); return nv50_disp_chan_fini(&dmac->base, suspend); Loading Loading @@ -454,7 +520,7 @@ nv50_disp_mast_init(struct nouveau_object *object) return ret; /* enable error reporting */ nv_mask(priv, 0x610028, 0x00010001, 0x00010001); nv_mask(priv, 0x610028, 0x00010000, 0x00010000); /* attempt to unstick channel from some unknown state */ if ((nv_rd32(priv, 0x610200) & 0x009f0000) == 0x00020000) Loading Loading @@ -494,7 +560,7 @@ nv50_disp_mast_fini(struct nouveau_object *object, bool suspend) return -EBUSY; } /* disable error reporting */ /* disable error reporting and completion notifications */ nv_mask(priv, 0x610028, 0x00010001, 0x00000000); return nv50_disp_chan_fini(&mast->base, suspend); Loading @@ -507,6 +573,7 @@ nv50_disp_mast_ofuncs = { .base.init = nv50_disp_mast_init, .base.fini = nv50_disp_mast_fini, .base.map = nv50_disp_chan_map, .base.ntfy = nv50_disp_chan_ntfy, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, .chid = 0, Loading Loading @@ -607,6 +674,7 @@ nv50_disp_sync_ofuncs = { .base.dtor = nv50_disp_dmac_dtor, .base.init = nv50_disp_dmac_init, .base.fini = nv50_disp_dmac_fini, .base.ntfy = nv50_disp_chan_ntfy, .base.map = nv50_disp_chan_map, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, Loading Loading @@ -696,6 +764,7 @@ nv50_disp_ovly_ofuncs = { .base.dtor = nv50_disp_dmac_dtor, .base.init = nv50_disp_dmac_init, .base.fini = nv50_disp_dmac_fini, .base.ntfy = nv50_disp_chan_ntfy, .base.map = nv50_disp_chan_map, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, Loading Loading @@ -813,6 +882,7 @@ nv50_disp_oimm_ofuncs = { .base.dtor = nv50_disp_pioc_dtor, .base.init = nv50_disp_pioc_init, .base.fini = nv50_disp_pioc_fini, .base.ntfy = nv50_disp_chan_ntfy, .base.map = nv50_disp_chan_map, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, Loading Loading @@ -860,6 +930,7 @@ nv50_disp_curs_ofuncs = { .base.dtor = nv50_disp_pioc_dtor, .base.init = nv50_disp_pioc_init, .base.fini = nv50_disp_pioc_fini, .base.ntfy = nv50_disp_chan_ntfy, .base.map = nv50_disp_chan_map, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, Loading Loading @@ -1846,6 +1917,12 @@ nv50_disp_intr(struct nouveau_subdev *subdev) intr0 &= ~(0x00010000 << chid); } while (intr0 & 0x0000001f) { u32 chid = __ffs(intr0 & 0x0000001f); nv50_disp_chan_uevent_send(priv, chid); intr0 &= ~(0x00000001 << chid); } if (intr1 & 0x00000004) { nouveau_disp_vblank(&priv->base, 0); nv_wr32(priv, 0x610024, 0x00000004); Loading Loading @@ -1880,6 +1957,10 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (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)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; Loading drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +9 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ struct nv50_disp_priv { struct work_struct supervisor; u32 super; struct nvkm_event uevent; struct { int nr; } head; Loading Loading @@ -116,9 +118,16 @@ struct nv50_disp_chan { int chid; }; int nv50_disp_chan_ntfy(struct nouveau_object *, u32, struct nvkm_event **); int nv50_disp_chan_map(struct nouveau_object *, u64 *, u32 *); u32 nv50_disp_chan_rd32(struct nouveau_object *, u64); 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) \ nouveau_namedb_init(&(a)->base) Loading drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +4 −0 Original line number Diff line number Diff line Loading @@ -236,6 +236,10 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (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)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; Loading drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +4 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,10 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (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)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; Loading Loading
drivers/gpu/drm/nouveau/core/engine/disp/gm107.c +4 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,10 @@ gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (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)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nvd0_disp_intr; Loading
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +85 −4 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <core/enum.h> #include <nvif/unpack.h> #include <nvif/class.h> #include <nvif/event.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> Loading Loading @@ -82,6 +83,71 @@ nv50_disp_chan_destroy(struct nv50_disp_chan *chan) 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 nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size) { Loading Loading @@ -195,7 +261,7 @@ nv50_disp_dmac_init(struct nouveau_object *object) return ret; /* 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 */ nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push); Loading Loading @@ -232,7 +298,7 @@ nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend) return -EBUSY; } /* disable error reporting */ /* disable error reporting and completion notifications */ nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid); return nv50_disp_chan_fini(&dmac->base, suspend); Loading Loading @@ -454,7 +520,7 @@ nv50_disp_mast_init(struct nouveau_object *object) return ret; /* enable error reporting */ nv_mask(priv, 0x610028, 0x00010001, 0x00010001); nv_mask(priv, 0x610028, 0x00010000, 0x00010000); /* attempt to unstick channel from some unknown state */ if ((nv_rd32(priv, 0x610200) & 0x009f0000) == 0x00020000) Loading Loading @@ -494,7 +560,7 @@ nv50_disp_mast_fini(struct nouveau_object *object, bool suspend) return -EBUSY; } /* disable error reporting */ /* disable error reporting and completion notifications */ nv_mask(priv, 0x610028, 0x00010001, 0x00000000); return nv50_disp_chan_fini(&mast->base, suspend); Loading @@ -507,6 +573,7 @@ nv50_disp_mast_ofuncs = { .base.init = nv50_disp_mast_init, .base.fini = nv50_disp_mast_fini, .base.map = nv50_disp_chan_map, .base.ntfy = nv50_disp_chan_ntfy, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, .chid = 0, Loading Loading @@ -607,6 +674,7 @@ nv50_disp_sync_ofuncs = { .base.dtor = nv50_disp_dmac_dtor, .base.init = nv50_disp_dmac_init, .base.fini = nv50_disp_dmac_fini, .base.ntfy = nv50_disp_chan_ntfy, .base.map = nv50_disp_chan_map, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, Loading Loading @@ -696,6 +764,7 @@ nv50_disp_ovly_ofuncs = { .base.dtor = nv50_disp_dmac_dtor, .base.init = nv50_disp_dmac_init, .base.fini = nv50_disp_dmac_fini, .base.ntfy = nv50_disp_chan_ntfy, .base.map = nv50_disp_chan_map, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, Loading Loading @@ -813,6 +882,7 @@ nv50_disp_oimm_ofuncs = { .base.dtor = nv50_disp_pioc_dtor, .base.init = nv50_disp_pioc_init, .base.fini = nv50_disp_pioc_fini, .base.ntfy = nv50_disp_chan_ntfy, .base.map = nv50_disp_chan_map, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, Loading Loading @@ -860,6 +930,7 @@ nv50_disp_curs_ofuncs = { .base.dtor = nv50_disp_pioc_dtor, .base.init = nv50_disp_pioc_init, .base.fini = nv50_disp_pioc_fini, .base.ntfy = nv50_disp_chan_ntfy, .base.map = nv50_disp_chan_map, .base.rd32 = nv50_disp_chan_rd32, .base.wr32 = nv50_disp_chan_wr32, Loading Loading @@ -1846,6 +1917,12 @@ nv50_disp_intr(struct nouveau_subdev *subdev) intr0 &= ~(0x00010000 << chid); } while (intr0 & 0x0000001f) { u32 chid = __ffs(intr0 & 0x0000001f); nv50_disp_chan_uevent_send(priv, chid); intr0 &= ~(0x00000001 << chid); } if (intr1 & 0x00000004) { nouveau_disp_vblank(&priv->base, 0); nv_wr32(priv, 0x610024, 0x00000004); Loading Loading @@ -1880,6 +1957,10 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (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)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; Loading
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +9 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ struct nv50_disp_priv { struct work_struct supervisor; u32 super; struct nvkm_event uevent; struct { int nr; } head; Loading Loading @@ -116,9 +118,16 @@ struct nv50_disp_chan { int chid; }; int nv50_disp_chan_ntfy(struct nouveau_object *, u32, struct nvkm_event **); int nv50_disp_chan_map(struct nouveau_object *, u64 *, u32 *); u32 nv50_disp_chan_rd32(struct nouveau_object *, u64); 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) \ nouveau_namedb_init(&(a)->base) Loading
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +4 −0 Original line number Diff line number Diff line Loading @@ -236,6 +236,10 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (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)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; Loading
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +4 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,10 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (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)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; Loading