These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / nouveau / nvkm / subdev / mmu / gf100.c
index 294cda3..7ac507c 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include <subdev/mmu.h>
-#include <subdev/bar.h>
+#include "priv.h"
+
 #include <subdev/fb.h>
 #include <subdev/ltc.h>
 #include <subdev/timer.h>
 
 #include <core/gpuobj.h>
 
-struct gf100_mmu_priv {
-       struct nvkm_mmu base;
-};
-
-
 /* Map from compressed to corresponding uncompressed storage type.
  * The value 0xff represents an invalid storage type.
  */
@@ -75,17 +70,19 @@ const u8 gf100_pte_storage_type_map[256] =
 
 
 static void
-gf100_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 index, struct nvkm_gpuobj *pgt[2])
+gf100_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 index, struct nvkm_memory *pgt[2])
 {
        u32 pde[2] = { 0, 0 };
 
        if (pgt[0])
-               pde[1] = 0x00000001 | (pgt[0]->addr >> 8);
+               pde[1] = 0x00000001 | (nvkm_memory_addr(pgt[0]) >> 8);
        if (pgt[1])
-               pde[0] = 0x00000001 | (pgt[1]->addr >> 8);
+               pde[0] = 0x00000001 | (nvkm_memory_addr(pgt[1]) >> 8);
 
-       nv_wo32(pgd, (index * 8) + 0, pde[0]);
-       nv_wo32(pgd, (index * 8) + 4, pde[1]);
+       nvkm_kmap(pgd);
+       nvkm_wo32(pgd, (index * 8) + 0, pde[0]);
+       nvkm_wo32(pgd, (index * 8) + 4, pde[1]);
+       nvkm_done(pgd);
 }
 
 static inline u64
@@ -103,7 +100,7 @@ gf100_vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target)
 }
 
 static void
-gf100_vm_map(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+gf100_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt,
             struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
 {
        u64 next = 1 << (vma->node->type - 8);
@@ -112,126 +109,113 @@ gf100_vm_map(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
        pte <<= 3;
 
        if (mem->tag) {
-               struct nvkm_ltc *ltc = nvkm_ltc(vma->vm->mmu);
+               struct nvkm_ltc *ltc = vma->vm->mmu->subdev.device->ltc;
                u32 tag = mem->tag->offset + (delta >> 17);
                phys |= (u64)tag << (32 + 12);
                next |= (u64)1   << (32 + 12);
-               ltc->tags_clear(ltc, tag, cnt);
+               nvkm_ltc_tags_clear(ltc, tag, cnt);
        }
 
+       nvkm_kmap(pgt);
        while (cnt--) {
-               nv_wo32(pgt, pte + 0, lower_32_bits(phys));
-               nv_wo32(pgt, pte + 4, upper_32_bits(phys));
+               nvkm_wo32(pgt, pte + 0, lower_32_bits(phys));
+               nvkm_wo32(pgt, pte + 4, upper_32_bits(phys));
                phys += next;
                pte  += 8;
        }
+       nvkm_done(pgt);
 }
 
 static void
-gf100_vm_map_sg(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+gf100_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt,
                struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
 {
        u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5;
        /* compressed storage types are invalid for system memory */
        u32 memtype = gf100_pte_storage_type_map[mem->memtype & 0xff];
 
+       nvkm_kmap(pgt);
        pte <<= 3;
        while (cnt--) {
                u64 phys = gf100_vm_addr(vma, *list++, memtype, target);
-               nv_wo32(pgt, pte + 0, lower_32_bits(phys));
-               nv_wo32(pgt, pte + 4, upper_32_bits(phys));
+               nvkm_wo32(pgt, pte + 0, lower_32_bits(phys));
+               nvkm_wo32(pgt, pte + 4, upper_32_bits(phys));
                pte += 8;
        }
+       nvkm_done(pgt);
 }
 
 static void
-gf100_vm_unmap(struct nvkm_gpuobj *pgt, u32 pte, u32 cnt)
+gf100_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt)
 {
+       nvkm_kmap(pgt);
        pte <<= 3;
        while (cnt--) {
-               nv_wo32(pgt, pte + 0, 0x00000000);
-               nv_wo32(pgt, pte + 4, 0x00000000);
+               nvkm_wo32(pgt, pte + 0, 0x00000000);
+               nvkm_wo32(pgt, pte + 4, 0x00000000);
                pte += 8;
        }
+       nvkm_done(pgt);
 }
 
 static void
 gf100_vm_flush(struct nvkm_vm *vm)
 {
-       struct gf100_mmu_priv *priv = (void *)vm->mmu;
-       struct nvkm_bar *bar = nvkm_bar(priv);
+       struct nvkm_mmu *mmu = vm->mmu;
+       struct nvkm_device *device = mmu->subdev.device;
        struct nvkm_vm_pgd *vpgd;
        u32 type;
 
-       bar->flush(bar);
-
        type = 0x00000001; /* PAGE_ALL */
-       if (atomic_read(&vm->engref[NVDEV_SUBDEV_BAR]))
+       if (atomic_read(&vm->engref[NVKM_SUBDEV_BAR]))
                type |= 0x00000004; /* HUB_ONLY */
 
-       mutex_lock(&nv_subdev(priv)->mutex);
+       mutex_lock(&mmu->subdev.mutex);
        list_for_each_entry(vpgd, &vm->pgd_list, head) {
                /* looks like maybe a "free flush slots" counter, the
                 * faster you write to 0x100cbc to more it decreases
                 */
-               if (!nv_wait_ne(priv, 0x100c80, 0x00ff0000, 0x00000000)) {
-                       nv_error(priv, "vm timeout 0: 0x%08x %d\n",
-                                nv_rd32(priv, 0x100c80), type);
-               }
+               nvkm_msec(device, 2000,
+                       if (nvkm_rd32(device, 0x100c80) & 0x00ff0000)
+                               break;
+               );
 
-               nv_wr32(priv, 0x100cb8, vpgd->obj->addr >> 8);
-               nv_wr32(priv, 0x100cbc, 0x80000000 | type);
+               nvkm_wr32(device, 0x100cb8, vpgd->obj->addr >> 8);
+               nvkm_wr32(device, 0x100cbc, 0x80000000 | type);
 
                /* wait for flush to be queued? */
-               if (!nv_wait(priv, 0x100c80, 0x00008000, 0x00008000)) {
-                       nv_error(priv, "vm timeout 1: 0x%08x %d\n",
-                                nv_rd32(priv, 0x100c80), type);
-               }
+               nvkm_msec(device, 2000,
+                       if (nvkm_rd32(device, 0x100c80) & 0x00008000)
+                               break;
+               );
        }
-       mutex_unlock(&nv_subdev(priv)->mutex);
+       mutex_unlock(&mmu->subdev.mutex);
 }
 
 static int
 gf100_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset,
-               struct nvkm_vm **pvm)
+               struct lock_class_key *key, struct nvkm_vm **pvm)
 {
-       return nvkm_vm_create(mmu, offset, length, mm_offset, 4096, pvm);
+       return nvkm_vm_create(mmu, offset, length, mm_offset, 4096, key, pvm);
 }
 
-static int
-gf100_mmu_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-              struct nvkm_oclass *oclass, void *data, u32 size,
-              struct nvkm_object **pobject)
+static const struct nvkm_mmu_func
+gf100_mmu = {
+       .limit = (1ULL << 40),
+       .dma_bits = 40,
+       .pgt_bits  = 27 - 12,
+       .spg_shift = 12,
+       .lpg_shift = 17,
+       .create = gf100_vm_create,
+       .map_pgt = gf100_vm_map_pgt,
+       .map = gf100_vm_map,
+       .map_sg = gf100_vm_map_sg,
+       .unmap = gf100_vm_unmap,
+       .flush = gf100_vm_flush,
+};
+
+int
+gf100_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu)
 {
-       struct gf100_mmu_priv *priv;
-       int ret;
-
-       ret = nvkm_mmu_create(parent, engine, oclass, "VM", "vm", &priv);
-       *pobject = nv_object(priv);
-       if (ret)
-               return ret;
-
-       priv->base.limit = 1ULL << 40;
-       priv->base.dma_bits = 40;
-       priv->base.pgt_bits  = 27 - 12;
-       priv->base.spg_shift = 12;
-       priv->base.lpg_shift = 17;
-       priv->base.create = gf100_vm_create;
-       priv->base.map_pgt = gf100_vm_map_pgt;
-       priv->base.map = gf100_vm_map;
-       priv->base.map_sg = gf100_vm_map_sg;
-       priv->base.unmap = gf100_vm_unmap;
-       priv->base.flush = gf100_vm_flush;
-       return 0;
+       return nvkm_mmu_new_(&gf100_mmu, device, index, pmmu);
 }
-
-struct nvkm_oclass
-gf100_mmu_oclass = {
-       .handle = NV_SUBDEV(MMU, 0xc0),
-       .ofuncs = &(struct nvkm_ofuncs) {
-               .ctor = gf100_mmu_ctor,
-               .dtor = _nvkm_mmu_dtor,
-               .init = _nvkm_mmu_init,
-               .fini = _nvkm_mmu_fini,
-       },
-};