]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/gpu/drm/nouveau/nv50_vm.c
drm/nouveau: split ramin_lock into two locks, one hardirq safe
[mv-sheeva.git] / drivers / gpu / drm / nouveau / nv50_vm.c
index 6144156f255af02389775d78444cb56fd7f22fe6..6c26944907418b0d090d35758b8e22d7ce9de06c 100644 (file)
@@ -31,7 +31,6 @@ void
 nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
                struct nouveau_gpuobj *pgt[2])
 {
-       struct drm_nouveau_private *dev_priv = pgd->dev->dev_private;
        u64 phys = 0xdeadcafe00000000ULL;
        u32 coverage = 0;
 
@@ -58,10 +57,9 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
 }
 
 static inline u64
-nv50_vm_addr(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-            u64 phys, u32 memtype, u32 target)
+nv50_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
 {
-       struct drm_nouveau_private *dev_priv = pgt->dev->dev_private;
+       struct drm_nouveau_private *dev_priv = vma->vm->dev->dev_private;
 
        phys |= 1; /* present */
        phys |= (u64)memtype << 40;
@@ -85,12 +83,13 @@ nv50_vm_addr(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
 
 void
 nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-           struct nouveau_vram *mem, u32 pte, u32 cnt, u64 phys)
+           struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
 {
+       u32 comp = (mem->memtype & 0x180) >> 7;
        u32 block;
        int i;
 
-       phys  = nv50_vm_addr(vma, pgt, phys, mem->memtype, 0);
+       phys  = nv50_vm_addr(vma, phys, mem->memtype, 0);
        pte <<= 3;
        cnt <<= 3;
 
@@ -107,6 +106,11 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
 
                phys += block << (vma->node->type - 3);
                cnt  -= block;
+               if (comp) {
+                       u32 tag = mem->tag->start + ((delta >> 16) * comp);
+                       offset_h |= (tag << 17);
+                       delta    += block << (vma->node->type - 3);
+               }
 
                while (block) {
                        nv_wo32(pgt, pte + 0, offset_l);
@@ -119,11 +123,11 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
 
 void
 nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-              u32 pte, dma_addr_t *list, u32 cnt)
+              struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
 {
        pte <<= 3;
        while (cnt--) {
-               u64 phys = nv50_vm_addr(vma, pgt, (u64)*list++, 0, 2);
+               u64 phys = nv50_vm_addr(vma, (u64)*list++, mem->memtype, 2);
                nv_wo32(pgt, pte + 0, lower_32_bits(phys));
                nv_wo32(pgt, pte + 4, upper_32_bits(phys));
                pte += 8;
@@ -170,10 +174,11 @@ void
 nv50_vm_flush_engine(struct drm_device *dev, int engine)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       unsigned long flags;
 
-       spin_lock(&dev_priv->ramin_lock);
+       spin_lock_irqsave(&dev_priv->vm_lock, flags);
        nv_wr32(dev, 0x100c80, (engine << 16) | 1);
        if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000))
                NV_ERROR(dev, "vm flush timeout: engine %d\n", engine);
-       spin_unlock(&dev_priv->ramin_lock);
+       spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
 }