drm/nouveau/disp/nv50-: pass nvkm_memory objects for channel push buffers
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)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvif/mem.h
drivers/gpu/drm/nouveau/include/nvif/mmu.h
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nvif/mem.c
drivers/gpu/drm/nouveau/nvif/mmu.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/dmacnv50.c

index b542fe38398eaa14bb90fca5c028226033d6fa89..80ee4ab0f016be69ef5af865287ad1053bba49d7 100644 (file)
@@ -15,4 +15,6 @@ int nvif_mem_init_type(struct nvif_mmu *mmu, s32 oclass, int type, u8 page,
 int nvif_mem_init(struct nvif_mmu *mmu, s32 oclass, u8 type, u8 page,
                  u64 size, void *argv, u32 argc, struct nvif_mem *);
 void nvif_mem_fini(struct nvif_mem *);
+
+int nvif_mem_init_map(struct nvif_mmu *, u8 type, u64 size, struct nvif_mem *);
 #endif
index c8cd5b5b06889b6bc1b71a83e558f7ff924c181f..747ecf67e40382e165431323b233ffb2ac13e588 100644 (file)
@@ -8,6 +8,7 @@ struct nvif_mmu {
        u8  heap_nr;
        u8  type_nr;
        u16 kind_nr;
+       s32 mem;
 
        struct {
                u64 size;
index 2b3ccd85075058b86e0fb17e07eb9f3e791abf5e..e90330e4e8c519a6ddcbecbce995d1115a4d365f 100644 (file)
@@ -34,6 +34,8 @@
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_edid.h>
 
+#include <nvif/mem.h>
+
 #include <nvif/class.h>
 #include <nvif/cl0002.h>
 #include <nvif/cl5070.h>
@@ -400,7 +402,8 @@ struct nv50_dmac_ctxdma {
 
 struct nv50_dmac {
        struct nv50_chan base;
-       dma_addr_t handle;
+
+       struct nvif_mem push;
        u32 *ptr;
 
        struct nvif_object sync;
@@ -482,9 +485,8 @@ nv50_dmac_ctxdma_new(struct nv50_dmac *dmac, struct nouveau_framebuffer *fb)
 }
 
 static void
-nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp)
+nv50_dmac_destroy(struct nv50_dmac *dmac)
 {
-       struct nvif_device *device = dmac->base.device;
        struct nv50_dmac_ctxdma *ctxdma, *ctxtmp;
 
        list_for_each_entry_safe(ctxdma, ctxtmp, &dmac->ctxdma, head) {
@@ -496,10 +498,7 @@ nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp)
 
        nv50_chan_destroy(&dmac->base);
 
-       if (dmac->ptr) {
-               struct device *dev = nvxx_device(device)->dev;
-               dma_free_coherent(dev, PAGE_SIZE, dmac->ptr, dmac->handle);
-       }
+       nvif_mem_fini(&dmac->push);
 }
 
 static int
@@ -507,33 +506,24 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
                 const s32 *oclass, u8 head, void *data, u32 size, u64 syncbuf,
                 struct nv50_dmac *dmac)
 {
+       struct nouveau_cli *cli = (void *)device->object.client;
        struct nv50_disp_core_channel_dma_v0 *args = data;
-       struct nvif_object pushbuf;
        int ret;
 
        mutex_init(&dmac->lock);
        INIT_LIST_HEAD(&dmac->ctxdma);
 
-       dmac->ptr = dma_alloc_coherent(nvxx_device(device)->dev, PAGE_SIZE,
-                                      &dmac->handle, GFP_KERNEL);
-       if (!dmac->ptr)
-               return -ENOMEM;
-
-       ret = nvif_object_init(&device->object, 0, NV_DMA_FROM_MEMORY,
-                              &(struct nv_dma_v0) {
-                                       .target = NV_DMA_V0_TARGET_PCI_US,
-                                       .access = NV_DMA_V0_ACCESS_RD,
-                                       .start = dmac->handle + 0x0000,
-                                       .limit = dmac->handle + 0x0fff,
-                              }, sizeof(struct nv_dma_v0), &pushbuf);
+       ret = nvif_mem_init_map(&cli->mmu, NVIF_MEM_COHERENT, 0x1000,
+                               &dmac->push);
        if (ret)
                return ret;
 
-       args->pushbuf = nvif_handle(&pushbuf);
+       dmac->ptr = dmac->push.object.map.ptr;
+
+       args->pushbuf = nvif_handle(&dmac->push.object);
 
        ret = nv50_chan_create(device, disp, oclass, head, data, size,
                               &dmac->base);
-       nvif_object_fini(&pushbuf);
        if (ret)
                return ret;
 
@@ -574,9 +564,7 @@ static int
 nv50_core_create(struct nvif_device *device, struct nvif_object *disp,
                 u64 syncbuf, struct nv50_mast *core)
 {
-       struct nv50_disp_core_channel_dma_v0 args = {
-               .pushbuf = 0xb0007d00,
-       };
+       struct nv50_disp_core_channel_dma_v0 args = {};
        static const s32 oclass[] = {
                GP102_DISP_CORE_CHANNEL_DMA,
                GP100_DISP_CORE_CHANNEL_DMA,
@@ -612,7 +600,6 @@ nv50_base_create(struct nvif_device *device, struct nvif_object *disp,
                 int head, u64 syncbuf, struct nv50_sync *base)
 {
        struct nv50_disp_base_channel_dma_v0 args = {
-               .pushbuf = 0xb0007c00 | head,
                .head = head,
        };
        static const s32 oclass[] = {
@@ -643,7 +630,6 @@ nv50_ovly_create(struct nvif_device *device, struct nvif_object *disp,
                 int head, u64 syncbuf, struct nv50_ovly *ovly)
 {
        struct nv50_disp_overlay_channel_dma_v0 args = {
-               .pushbuf = 0xb0007e00 | head,
                .head = head,
        };
        static const s32 oclass[] = {
@@ -1472,9 +1458,8 @@ nv50_base_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
 static void *
 nv50_base_dtor(struct nv50_wndw *wndw)
 {
-       struct nv50_disp *disp = nv50_disp(wndw->plane.dev);
        struct nv50_base *base = nv50_base(wndw);
-       nv50_dmac_destroy(&base->chan.base, disp->disp);
+       nv50_dmac_destroy(&base->chan.base);
        return base;
 }
 
@@ -2354,11 +2339,10 @@ nv50_head_reset(struct drm_crtc *crtc)
 static void
 nv50_head_destroy(struct drm_crtc *crtc)
 {
-       struct nv50_disp *disp = nv50_disp(crtc->dev);
        struct nv50_head *head = nv50_head(crtc);
        int i;
 
-       nv50_dmac_destroy(&head->ovly.base, disp->disp);
+       nv50_dmac_destroy(&head->ovly.base);
        nv50_pioc_destroy(&head->oimm.base);
 
        for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++)
@@ -4430,7 +4414,7 @@ nv50_display_destroy(struct drm_device *dev)
 {
        struct nv50_disp *disp = nv50_disp(dev);
 
-       nv50_dmac_destroy(&disp->mast.base, disp->disp);
+       nv50_dmac_destroy(&disp->mast.base);
 
        nouveau_bo_unmap(disp->sync);
        if (disp->sync)
index 0f9382c6014589ffaf29cc0d14026faf32c4894a..b6ebb3b5867325d5c45fef05f0ae585d8b894c88 100644 (file)
 
 #include <nvif/if000a.h>
 
+int
+nvif_mem_init_map(struct nvif_mmu *mmu, u8 type, u64 size, struct nvif_mem *mem)
+{
+       int ret = nvif_mem_init(mmu, mmu->mem, NVIF_MEM_MAPPABLE | type, 0,
+                               size, NULL, 0, mem);
+       if (ret == 0) {
+               ret = nvif_object_map(&mem->object, NULL, 0);
+               if (ret)
+                       nvif_mem_fini(mem);
+       }
+       return ret;
+}
+
 void
 nvif_mem_fini(struct nvif_mem *mem)
 {
index 15d0dcbf7ab41d5599b472a0122042cc825ec34e..358ac4f3cf91d75a23d6844c36673d3aad832803 100644 (file)
@@ -36,6 +36,12 @@ nvif_mmu_fini(struct nvif_mmu *mmu)
 int
 nvif_mmu_init(struct nvif_object *parent, s32 oclass, struct nvif_mmu *mmu)
 {
+       static const struct nvif_mclass mems[] = {
+               { NVIF_CLASS_MEM_GF100, -1 },
+               { NVIF_CLASS_MEM_NV50 , -1 },
+               { NVIF_CLASS_MEM_NV04 , -1 },
+               {}
+       };
        struct nvif_mmu_v0 args;
        int ret, i;
 
@@ -54,6 +60,11 @@ nvif_mmu_init(struct nvif_object *parent, s32 oclass, struct nvif_mmu *mmu)
        mmu->type_nr = args.type_nr;
        mmu->kind_nr = args.kind_nr;
 
+       ret = nvif_mclass(&mmu->object, mems);
+       if (ret < 0)
+               goto done;
+       mmu->mem = mems[ret].oclass;
+
        mmu->heap = kmalloc(sizeof(*mmu->heap) * mmu->heap_nr, GFP_KERNEL);
        mmu->type = kmalloc(sizeof(*mmu->type) * mmu->type_nr, GFP_KERNEL);
        if (ret = -ENOMEM, !mmu->heap || !mmu->type)
index 53c3ed6da9aea36e59c6ab0f7a58bfcd75750b19..57719f675eec92ae32640cd0cd160c5cef481bae 100644 (file)
@@ -316,6 +316,7 @@ nv50_disp_chan_dtor(struct nvkm_object *object)
        struct nv50_disp *disp = chan->disp;
        if (chan->chid.user >= 0)
                disp->chan[chan->chid.user] = NULL;
+       nvkm_memory_unref(&chan->memory);
        return chan;
 }
 
index 2a48243b00aea128d74ef3cd2dc1716e3ca11f11..391b007a682434e8ce999a789a98085b58575a05 100644 (file)
@@ -19,6 +19,7 @@ struct nv50_disp_chan {
 
        struct nvkm_object object;
 
+       struct nvkm_memory *memory;
        u64 push;
 };
 
index 981b98def151e7633c22ca4b44aa034798821c7e..9e8a9d7a9b68b12e4327a694589d3bfde5d753b4 100644 (file)
@@ -26,6 +26,7 @@
 #include <core/client.h>
 #include <core/ramht.h>
 #include <subdev/fb.h>
+#include <subdev/mmu.h>
 #include <subdev/timer.h>
 #include <engine/dma.h>
 
@@ -37,7 +38,6 @@ nv50_disp_dmac_new_(const struct nv50_disp_chan_func *func,
                    struct nvkm_object **pobject)
 {
        struct nvkm_client *client = oclass->client;
-       struct nvkm_dmaobj *dmaobj;
        struct nv50_disp_chan *chan;
        int ret;
 
@@ -47,24 +47,22 @@ nv50_disp_dmac_new_(const struct nv50_disp_chan_func *func,
        if (ret)
                return ret;
 
-       dmaobj = nvkm_dmaobj_search(client, push);
-       if (IS_ERR(dmaobj))
-               return PTR_ERR(dmaobj);
+       chan->memory = nvkm_umem_search(client, push);
+       if (IS_ERR(chan->memory))
+               return PTR_ERR(chan->memory);
 
-       if (dmaobj->limit - dmaobj->start != 0xfff)
+       if (nvkm_memory_size(chan->memory) < 0x1000)
                return -EINVAL;
 
-       switch (dmaobj->target) {
-       case NV_MEM_TARGET_VRAM:
-               chan->push = 0x00000001 | dmaobj->start >> 8;
-               break;
-       case NV_MEM_TARGET_PCI_NOSNOOP:
-               chan->push = 0x00000003 | dmaobj->start >> 8;
-               break;
+       switch (nvkm_memory_target(chan->memory)) {
+       case NVKM_MEM_TARGET_VRAM: chan->push = 0x00000001; break;
+       case NVKM_MEM_TARGET_NCOH: chan->push = 0x00000002; break;
+       case NVKM_MEM_TARGET_HOST: chan->push = 0x00000003; break;
        default:
                return -EINVAL;
        }
 
+       chan->push |= nvkm_memory_addr(chan->memory) >> 8;
        return 0;
 }