drm/nouveau/disp: allow user direct access to channel control registers
authorBen Skeggs <bskeggs@redhat.com>
Sat, 9 Aug 2014 18:10:28 +0000 (04:10 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Sat, 9 Aug 2014 19:28:11 +0000 (05:28 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
drivers/gpu/drm/nouveau/nv50_display.c

index 8dafd41..858386b 100644 (file)
@@ -82,6 +82,16 @@ nv50_disp_chan_destroy(struct nv50_disp_chan *chan)
        nouveau_namedb_destroy(&chan->base);
 }
 
+int
+nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size)
+{
+       struct nv50_disp_chan *chan = (void *)object;
+       *addr = nv_device_resource_start(nv_device(object), 0) +
+               0x640000 + (chan->chid * 0x1000);
+       *size = 0x001000;
+       return 0;
+}
+
 u32
 nv50_disp_chan_rd32(struct nouveau_object *object, u64 addr)
 {
@@ -496,6 +506,7 @@ nv50_disp_mast_ofuncs = {
        .base.dtor = nv50_disp_dmac_dtor,
        .base.init = nv50_disp_mast_init,
        .base.fini = nv50_disp_mast_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 0,
@@ -596,6 +607,7 @@ nv50_disp_sync_ofuncs = {
        .base.dtor = nv50_disp_dmac_dtor,
        .base.init = nv50_disp_dmac_init,
        .base.fini = nv50_disp_dmac_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 1,
@@ -684,6 +696,7 @@ nv50_disp_ovly_ofuncs = {
        .base.dtor = nv50_disp_dmac_dtor,
        .base.init = nv50_disp_dmac_init,
        .base.fini = nv50_disp_dmac_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 3,
@@ -800,6 +813,7 @@ nv50_disp_oimm_ofuncs = {
        .base.dtor = nv50_disp_pioc_dtor,
        .base.init = nv50_disp_pioc_init,
        .base.fini = nv50_disp_pioc_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 5,
@@ -846,6 +860,7 @@ nv50_disp_curs_ofuncs = {
        .base.dtor = nv50_disp_pioc_dtor,
        .base.init = nv50_disp_pioc_init,
        .base.fini = nv50_disp_pioc_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 7,
index 9be9b45..8ab1446 100644 (file)
@@ -116,6 +116,7 @@ struct nv50_disp_chan {
        int chid;
 };
 
+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);
 
index f64647b..9c2ac13 100644 (file)
@@ -326,6 +326,7 @@ nvd0_disp_mast_ofuncs = {
        .base.dtor = nv50_disp_dmac_dtor,
        .base.init = nvd0_disp_mast_init,
        .base.fini = nvd0_disp_mast_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 0,
@@ -418,6 +419,7 @@ nvd0_disp_sync_ofuncs = {
        .base.dtor = nv50_disp_dmac_dtor,
        .base.init = nvd0_disp_dmac_init,
        .base.fini = nvd0_disp_dmac_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 1,
@@ -497,6 +499,7 @@ nvd0_disp_ovly_ofuncs = {
        .base.dtor = nv50_disp_dmac_dtor,
        .base.init = nvd0_disp_dmac_init,
        .base.fini = nvd0_disp_dmac_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 5,
@@ -567,6 +570,7 @@ nvd0_disp_oimm_ofuncs = {
        .base.dtor = nv50_disp_pioc_dtor,
        .base.init = nvd0_disp_pioc_init,
        .base.fini = nvd0_disp_pioc_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 9,
@@ -582,6 +586,7 @@ nvd0_disp_curs_ofuncs = {
        .base.dtor = nv50_disp_pioc_dtor,
        .base.init = nvd0_disp_pioc_init,
        .base.fini = nvd0_disp_pioc_fini,
+       .base.map  = nv50_disp_chan_map,
        .base.rd32 = nv50_disp_chan_rd32,
        .base.wr32 = nv50_disp_chan_wr32,
        .chid = 13,
index 82d6b4f..9e9fa58 100644 (file)
@@ -69,8 +69,10 @@ nv50_chan_create(struct nvif_object *disp, const u32 *oclass, u8 head,
                int ret = nvif_object_init(disp, NULL, (oclass[0] << 16) | head,
                                           oclass[0], data, size,
                                          &chan->user);
-               if (oclass++, ret == 0)
+               if (oclass++, ret == 0) {
+                       nvif_object_map(&chan->user);
                        return ret;
+               }
        }
        return -ENOSYS;
 }