drm/amdgpu: drop redundant null-pointer checks in amdgpu_ttm_tt_populate() and amdgpu...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_ttm.c
index 6e02bdd..38dade4 100644 (file)
@@ -149,14 +149,16 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
                         * BOs to be evicted from VRAM
                         */
                        amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM |
-                                                        AMDGPU_GEM_DOMAIN_GTT);
+                                                       AMDGPU_GEM_DOMAIN_GTT |
+                                                       AMDGPU_GEM_DOMAIN_CPU);
                        abo->placements[0].fpfn = adev->gmc.visible_vram_size >> PAGE_SHIFT;
                        abo->placements[0].lpfn = 0;
                        abo->placement.busy_placement = &abo->placements[1];
                        abo->placement.num_busy_placement = 1;
                } else {
                        /* Move to GTT memory */
-                       amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT);
+                       amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT |
+                                                       AMDGPU_GEM_DOMAIN_CPU);
                }
                break;
        case TTM_PL_TT:
@@ -521,7 +523,7 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
                        hop->fpfn = 0;
                        hop->lpfn = 0;
                        hop->mem_type = TTM_PL_TT;
-                       hop->flags = 0;
+                       hop->flags = TTM_PL_FLAG_TEMPORARY;
                        return -EMULTIHOP;
                }
 
@@ -677,23 +679,23 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
                return -ESRCH;
 
        mmap_read_lock(mm);
-       vma = find_vma(mm, start);
-       mmap_read_unlock(mm);
-       if (unlikely(!vma || start < vma->vm_start)) {
+       vma = vma_lookup(mm, start);
+       if (unlikely(!vma)) {
                r = -EFAULT;
-               goto out_putmm;
+               goto out_unlock;
        }
        if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
                vma->vm_file)) {
                r = -EPERM;
-               goto out_putmm;
+               goto out_unlock;
        }
 
        readonly = amdgpu_ttm_tt_is_readonly(ttm);
        r = amdgpu_hmm_range_get_pages(&bo->notifier, mm, pages, start,
                                       ttm->num_pages, &gtt->range, readonly,
-                                      false, NULL);
-out_putmm:
+                                      true, NULL);
+out_unlock:
+       mmap_read_unlock(mm);
        mmput(mm);
 
        return r;
@@ -919,7 +921,8 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
            bo_mem->mem_type == AMDGPU_PL_OA)
                return -EINVAL;
 
-       if (!amdgpu_gtt_mgr_has_gart_addr(bo_mem)) {
+       if (bo_mem->mem_type != TTM_PL_TT ||
+           !amdgpu_gtt_mgr_has_gart_addr(bo_mem)) {
                gtt->offset = AMDGPU_BO_INVALID_OFFSET;
                return 0;
        }
@@ -1120,7 +1123,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev,
        struct amdgpu_ttm_tt *gtt = (void *)ttm;
 
        /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */
-       if (gtt && gtt->userptr) {
+       if (gtt->userptr) {
                ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
                if (!ttm->sg)
                        return -ENOMEM;
@@ -1145,7 +1148,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev,
        struct amdgpu_ttm_tt *gtt = (void *)ttm;
        struct amdgpu_device *adev;
 
-       if (gtt && gtt->userptr) {
+       if (gtt->userptr) {
                amdgpu_ttm_tt_set_user_pages(ttm, NULL);
                kfree(ttm->sg);
                ttm->sg = NULL;
@@ -1393,6 +1396,41 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
        return ttm_bo_eviction_valuable(bo, place);
 }
 
+static void amdgpu_ttm_vram_mm_access(struct amdgpu_device *adev, loff_t pos,
+                                     void *buf, size_t size, bool write)
+{
+       while (size) {
+               uint64_t aligned_pos = ALIGN_DOWN(pos, 4);
+               uint64_t bytes = 4 - (pos & 0x3);
+               uint32_t shift = (pos & 0x3) * 8;
+               uint32_t mask = 0xffffffff << shift;
+               uint32_t value = 0;
+
+               if (size < bytes) {
+                       mask &= 0xffffffff >> (bytes - size) * 8;
+                       bytes = size;
+               }
+
+               if (mask != 0xffffffff) {
+                       amdgpu_device_mm_access(adev, aligned_pos, &value, 4, false);
+                       if (write) {
+                               value &= ~mask;
+                               value |= (*(uint32_t *)buf << shift) & mask;
+                               amdgpu_device_mm_access(adev, aligned_pos, &value, 4, true);
+                       } else {
+                               value = (value & mask) >> shift;
+                               memcpy(buf, &value, bytes);
+                       }
+               } else {
+                       amdgpu_device_mm_access(adev, aligned_pos, buf, 4, write);
+               }
+
+               pos += bytes;
+               buf += bytes;
+               size -= bytes;
+       }
+}
+
 /**
  * amdgpu_ttm_access_memory - Read or Write memory that backs a buffer object.
  *
@@ -1412,8 +1450,6 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
        struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
        struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
        struct amdgpu_res_cursor cursor;
-       unsigned long flags;
-       uint32_t value = 0;
        int ret = 0;
 
        if (bo->resource->mem_type != TTM_PL_VRAM)
@@ -1421,41 +1457,21 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
 
        amdgpu_res_first(bo->resource, offset, len, &cursor);
        while (cursor.remaining) {
-               uint64_t aligned_pos = cursor.start & ~(uint64_t)3;
-               uint64_t bytes = 4 - (cursor.start & 3);
-               uint32_t shift = (cursor.start & 3) * 8;
-               uint32_t mask = 0xffffffff << shift;
-
-               if (cursor.size < bytes) {
-                       mask &= 0xffffffff >> (bytes - cursor.size) * 8;
-                       bytes = cursor.size;
+               size_t count, size = cursor.size;
+               loff_t pos = cursor.start;
+
+               count = amdgpu_device_aper_access(adev, pos, buf, size, write);
+               size -= count;
+               if (size) {
+                       /* using MM to access rest vram and handle un-aligned address */
+                       pos += count;
+                       buf += count;
+                       amdgpu_ttm_vram_mm_access(adev, pos, buf, size, write);
                }
 
-               if (mask != 0xffffffff) {
-                       spin_lock_irqsave(&adev->mmio_idx_lock, flags);
-                       WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)aligned_pos) | 0x80000000);
-                       WREG32_NO_KIQ(mmMM_INDEX_HI, aligned_pos >> 31);
-                       value = RREG32_NO_KIQ(mmMM_DATA);
-                       if (write) {
-                               value &= ~mask;
-                               value |= (*(uint32_t *)buf << shift) & mask;
-                               WREG32_NO_KIQ(mmMM_DATA, value);
-                       }
-                       spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
-                       if (!write) {
-                               value = (value & mask) >> shift;
-                               memcpy(buf, &value, bytes);
-                       }
-               } else {
-                       bytes = cursor.size & ~0x3ULL;
-                       amdgpu_device_vram_access(adev, cursor.start,
-                                                 (uint32_t *)buf, bytes,
-                                                 write);
-               }
-
-               ret += bytes;
-               buf = (uint8_t *)buf + bytes;
-               amdgpu_res_next(&cursor, bytes);
+               ret += cursor.size;
+               buf += cursor.size;
+               amdgpu_res_next(&cursor, cursor.size);
        }
 
        return ret;