drm/amdgpu: add 64bit wb functions
authorKen Wang <Qingqing.Wang@amd.com>
Fri, 18 Mar 2016 07:08:49 +0000 (15:08 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 30 Mar 2017 03:53:35 +0000 (23:53 -0400)
Newer asics need 64 bit writeback slots.

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Ken Wang <Qingqing.Wang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c

index 93ecf692b9f63ee7ffe5934d3c9660b3c94e3507..9c1ce40b33b2b4f6046cb5e3e6e51a27bc995dd7 100644 (file)
@@ -1021,6 +1021,8 @@ struct amdgpu_wb {
 
 int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb);
 void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb);
+int amdgpu_wb_get_64bit(struct amdgpu_device *adev, u32 *wb);
+void amdgpu_wb_free_64bit(struct amdgpu_device *adev, u32 wb);
 
 void amdgpu_get_pcie_info(struct amdgpu_device *adev);
 
index ffaa703e89f56fa2debb864bfbbc70497c295bbb..fcf83178b113bc3fd138f2516ebdaef5b23375f8 100644 (file)
@@ -515,6 +515,29 @@ int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb)
        }
 }
 
+/**
+ * amdgpu_wb_get_64bit - Allocate a wb entry
+ *
+ * @adev: amdgpu_device pointer
+ * @wb: wb index
+ *
+ * Allocate a wb slot for use by the driver (all asics).
+ * Returns 0 on success or -EINVAL on failure.
+ */
+int amdgpu_wb_get_64bit(struct amdgpu_device *adev, u32 *wb)
+{
+       unsigned long offset = bitmap_find_next_zero_area_off(adev->wb.used,
+                               adev->wb.num_wb, 0, 2, 7, 0);
+       if ((offset + 1) < adev->wb.num_wb) {
+               __set_bit(offset, adev->wb.used);
+               __set_bit(offset + 1, adev->wb.used);
+               *wb = offset;
+               return 0;
+       } else {
+               return -EINVAL;
+       }
+}
+
 /**
  * amdgpu_wb_free - Free a wb entry
  *
@@ -529,6 +552,22 @@ void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb)
                __clear_bit(wb, adev->wb.used);
 }
 
+/**
+ * amdgpu_wb_free_64bit - Free a wb entry
+ *
+ * @adev: amdgpu_device pointer
+ * @wb: wb index
+ *
+ * Free a wb slot allocated for use by the driver (all asics)
+ */
+void amdgpu_wb_free_64bit(struct amdgpu_device *adev, u32 wb)
+{
+       if ((wb + 1) < adev->wb.num_wb) {
+               __clear_bit(wb, adev->wb.used);
+               __clear_bit(wb + 1, adev->wb.used);
+       }
+}
+
 /**
  * amdgpu_vram_location - try to find VRAM location
  * @adev: amdgpu device structure holding all necessary informations
index c9b536f4b0196017eaadc62f8c41810666b4848b..bfd4022210ed2213261a543dff7a032cce0e07e8 100644 (file)
@@ -182,16 +182,32 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
                        return r;
        }
 
-       r = amdgpu_wb_get(adev, &ring->rptr_offs);
-       if (r) {
-               dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
-               return r;
-       }
+       if (ring->funcs->support_64bit_ptrs) {
+               r = amdgpu_wb_get_64bit(adev, &ring->rptr_offs);
+               if (r) {
+                       dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
+                       return r;
+               }
+
+               r = amdgpu_wb_get_64bit(adev, &ring->wptr_offs);
+               if (r) {
+                       dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
+                       return r;
+               }
+
+       } else {
+               r = amdgpu_wb_get(adev, &ring->rptr_offs);
+               if (r) {
+                       dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
+                       return r;
+               }
+
+               r = amdgpu_wb_get(adev, &ring->wptr_offs);
+               if (r) {
+                       dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
+                       return r;
+               }
 
-       r = amdgpu_wb_get(adev, &ring->wptr_offs);
-       if (r) {
-               dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
-               return r;
        }
 
        r = amdgpu_wb_get(adev, &ring->fence_offs);
@@ -256,10 +272,18 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
 {
        ring->ready = false;
 
-       amdgpu_wb_free(ring->adev, ring->cond_exe_offs);
-       amdgpu_wb_free(ring->adev, ring->fence_offs);
-       amdgpu_wb_free(ring->adev, ring->rptr_offs);
-       amdgpu_wb_free(ring->adev, ring->wptr_offs);
+       if (ring->funcs->support_64bit_ptrs) {
+               amdgpu_wb_free_64bit(ring->adev, ring->cond_exe_offs);
+               amdgpu_wb_free_64bit(ring->adev, ring->fence_offs);
+               amdgpu_wb_free_64bit(ring->adev, ring->rptr_offs);
+               amdgpu_wb_free_64bit(ring->adev, ring->wptr_offs);
+       } else {
+               amdgpu_wb_free(ring->adev, ring->cond_exe_offs);
+               amdgpu_wb_free(ring->adev, ring->fence_offs);
+               amdgpu_wb_free(ring->adev, ring->rptr_offs);
+               amdgpu_wb_free(ring->adev, ring->wptr_offs);
+       }
+
 
        amdgpu_bo_free_kernel(&ring->ring_obj,
                              &ring->gpu_addr,