Merge tag 'drm-misc-fixes-2017-11-02' of git://anongit.freedesktop.org/drm/drm-misc...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / nouveau / nvkm / engine / gr / gf100.c
index 99689f4de502d66b174825afc922a2fc3d397401..2f8dc107047dc8c14b91f60af01304f189ce68c1 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <nvif/class.h>
 #include <nvif/cl9097.h>
+#include <nvif/if900d.h>
 #include <nvif/unpack.h>
 
 /*******************************************************************************
@@ -327,13 +328,13 @@ gf100_gr_chan_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent,
 
        if (!gr->firmware) {
                nvkm_wo32(*pgpuobj, 0x00, chan->mmio_nr / 2);
-               nvkm_wo32(*pgpuobj, 0x04, chan->mmio_vma.offset >> 8);
+               nvkm_wo32(*pgpuobj, 0x04, chan->mmio_vma->addr >> 8);
        } else {
                nvkm_wo32(*pgpuobj, 0xf4, 0);
                nvkm_wo32(*pgpuobj, 0xf8, 0);
                nvkm_wo32(*pgpuobj, 0x10, chan->mmio_nr / 2);
-               nvkm_wo32(*pgpuobj, 0x14, lower_32_bits(chan->mmio_vma.offset));
-               nvkm_wo32(*pgpuobj, 0x18, upper_32_bits(chan->mmio_vma.offset));
+               nvkm_wo32(*pgpuobj, 0x14, lower_32_bits(chan->mmio_vma->addr));
+               nvkm_wo32(*pgpuobj, 0x18, upper_32_bits(chan->mmio_vma->addr));
                nvkm_wo32(*pgpuobj, 0x1c, 1);
                nvkm_wo32(*pgpuobj, 0x20, 0);
                nvkm_wo32(*pgpuobj, 0x28, 0);
@@ -350,18 +351,13 @@ gf100_gr_chan_dtor(struct nvkm_object *object)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(chan->data); i++) {
-               if (chan->data[i].vma.node) {
-                       nvkm_vm_unmap(&chan->data[i].vma);
-                       nvkm_vm_put(&chan->data[i].vma);
-               }
-               nvkm_memory_del(&chan->data[i].mem);
+               nvkm_vmm_put(chan->vmm, &chan->data[i].vma);
+               nvkm_memory_unref(&chan->data[i].mem);
        }
 
-       if (chan->mmio_vma.node) {
-               nvkm_vm_unmap(&chan->mmio_vma);
-               nvkm_vm_put(&chan->mmio_vma);
-       }
-       nvkm_memory_del(&chan->mmio);
+       nvkm_vmm_put(chan->vmm, &chan->mmio_vma);
+       nvkm_memory_unref(&chan->mmio);
+       nvkm_vmm_unref(&chan->vmm);
        return chan;
 }
 
@@ -380,6 +376,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
        struct gf100_gr_data *data = gr->mmio_data;
        struct gf100_gr_mmio *mmio = gr->mmio_list;
        struct gf100_gr_chan *chan;
+       struct gf100_vmm_map_v0 args = { .priv = 1 };
        struct nvkm_device *device = gr->base.engine.subdev.device;
        int ret, i;
 
@@ -387,6 +384,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
                return -ENOMEM;
        nvkm_object_ctor(&gf100_gr_chan, oclass, &chan->object);
        chan->gr = gr;
+       chan->vmm = nvkm_vmm_ref(fifoch->vmm);
        *pobject = &chan->object;
 
        /* allocate memory for a "mmio list" buffer that's used by the HUB
@@ -398,12 +396,14 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
        if (ret)
                return ret;
 
-       ret = nvkm_vm_get(fifoch->vm, 0x1000, 12, NV_MEM_ACCESS_RW |
-                         NV_MEM_ACCESS_SYS, &chan->mmio_vma);
+       ret = nvkm_vmm_get(fifoch->vmm, 12, 0x1000, &chan->mmio_vma);
        if (ret)
                return ret;
 
-       nvkm_memory_map(chan->mmio, &chan->mmio_vma, 0);
+       ret = nvkm_memory_map(chan->mmio, 0, fifoch->vmm,
+                             chan->mmio_vma, &args, sizeof(args));
+       if (ret)
+               return ret;
 
        /* allocate buffers referenced by mmio list */
        for (i = 0; data->size && i < ARRAY_SIZE(gr->mmio_data); i++) {
@@ -413,13 +413,19 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
                if (ret)
                        return ret;
 
-               ret = nvkm_vm_get(fifoch->vm,
-                                 nvkm_memory_size(chan->data[i].mem), 12,
-                                 data->access, &chan->data[i].vma);
+               ret = nvkm_vmm_get(fifoch->vmm, 12,
+                                  nvkm_memory_size(chan->data[i].mem),
+                                  &chan->data[i].vma);
+               if (ret)
+                       return ret;
+
+               args.priv = data->priv;
+
+               ret = nvkm_memory_map(chan->data[i].mem, 0, chan->vmm,
+                                     chan->data[i].vma, &args, sizeof(args));
                if (ret)
                        return ret;
 
-               nvkm_memory_map(chan->data[i].mem, &chan->data[i].vma, 0);
                data++;
        }
 
@@ -430,7 +436,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
                u32 data = mmio->data;
 
                if (mmio->buffer >= 0) {
-                       u64 info = chan->data[mmio->buffer].vma.offset;
+                       u64 info = chan->data[mmio->buffer].vma->addr;
                        data |= info >> mmio->shift;
                }
 
@@ -1855,8 +1861,12 @@ gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
        int ret;
 
        ret = nvkm_firmware_get(device, fwname, &fw);
-       if (ret)
-               return gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);
+       if (ret) {
+               ret = gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);
+               if (ret)
+                       return -ENODEV;
+               return 0;
+       }
 
        fuc->size = fw->size;
        fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
@@ -1903,25 +1913,33 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device,
        return 0;
 }
 
+void
+gf100_gr_init_gpc_mmu(struct gf100_gr *gr)
+{
+       struct nvkm_device *device = gr->base.engine.subdev.device;
+       struct nvkm_fb *fb = device->fb;
+
+       nvkm_wr32(device, 0x418880, nvkm_rd32(device, 0x100c80) & 0x00000001);
+       nvkm_wr32(device, 0x4188a4, 0x00000000);
+       nvkm_wr32(device, 0x418888, 0x00000000);
+       nvkm_wr32(device, 0x41888c, 0x00000000);
+       nvkm_wr32(device, 0x418890, 0x00000000);
+       nvkm_wr32(device, 0x418894, 0x00000000);
+       nvkm_wr32(device, 0x4188b4, nvkm_memory_addr(fb->mmu_wr) >> 8);
+       nvkm_wr32(device, 0x4188b8, nvkm_memory_addr(fb->mmu_rd) >> 8);
+}
+
 int
 gf100_gr_init(struct gf100_gr *gr)
 {
        struct nvkm_device *device = gr->base.engine.subdev.device;
-       struct nvkm_fb *fb = device->fb;
        const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
        u32 data[TPC_MAX / 8] = {};
        u8  tpcnr[GPC_MAX];
        int gpc, tpc, rop;
        int i;
 
-       nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000);
-       nvkm_wr32(device, GPC_BCAST(0x08a4), 0x00000000);
-       nvkm_wr32(device, GPC_BCAST(0x0888), 0x00000000);
-       nvkm_wr32(device, GPC_BCAST(0x088c), 0x00000000);
-       nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000);
-       nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000);
-       nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8);
-       nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8);
+       gr->func->init_gpc_mmu(gr);
 
        gf100_gr_mmio(gr, gr->func->mmio);
 
@@ -2036,6 +2054,7 @@ gf100_gr_gpccs_ucode = {
 static const struct gf100_gr_func
 gf100_gr = {
        .init = gf100_gr_init,
+       .init_gpc_mmu = gf100_gr_init_gpc_mmu,
        .mmio = gf100_gr_pack_mmio,
        .fecs.ucode = &gf100_gr_fecs_ucode,
        .gpccs.ucode = &gf100_gr_gpccs_ucode,