Commit 7014285a authored by Ken Wang's avatar Ken Wang Committed by Alex Deucher

drm/amdgpu: add 64bit wb functions

Newer asics need 64 bit writeback slots.
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarKen Wang <Qingqing.Wang@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 536fbf94
...@@ -1021,6 +1021,8 @@ struct amdgpu_wb { ...@@ -1021,6 +1021,8 @@ struct amdgpu_wb {
int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb); int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb);
void amdgpu_wb_free(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); void amdgpu_get_pcie_info(struct amdgpu_device *adev);
......
...@@ -515,6 +515,29 @@ int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb) ...@@ -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 * amdgpu_wb_free - Free a wb entry
* *
...@@ -529,6 +552,22 @@ void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb) ...@@ -529,6 +552,22 @@ void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb)
__clear_bit(wb, adev->wb.used); __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 * amdgpu_vram_location - try to find VRAM location
* @adev: amdgpu device structure holding all necessary informations * @adev: amdgpu device structure holding all necessary informations
......
...@@ -182,6 +182,20 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, ...@@ -182,6 +182,20 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
return 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); r = amdgpu_wb_get(adev, &ring->rptr_offs);
if (r) { if (r) {
dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r); dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
...@@ -194,6 +208,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, ...@@ -194,6 +208,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
return r; return r;
} }
}
r = amdgpu_wb_get(adev, &ring->fence_offs); r = amdgpu_wb_get(adev, &ring->fence_offs);
if (r) { if (r) {
dev_err(adev->dev, "(%d) ring fence_offs wb alloc failed\n", r); dev_err(adev->dev, "(%d) ring fence_offs wb alloc failed\n", r);
...@@ -256,10 +272,18 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) ...@@ -256,10 +272,18 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
{ {
ring->ready = false; ring->ready = false;
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->cond_exe_offs);
amdgpu_wb_free(ring->adev, ring->fence_offs); amdgpu_wb_free(ring->adev, ring->fence_offs);
amdgpu_wb_free(ring->adev, ring->rptr_offs); amdgpu_wb_free(ring->adev, ring->rptr_offs);
amdgpu_wb_free(ring->adev, ring->wptr_offs); amdgpu_wb_free(ring->adev, ring->wptr_offs);
}
amdgpu_bo_free_kernel(&ring->ring_obj, amdgpu_bo_free_kernel(&ring->ring_obj,
&ring->gpu_addr, &ring->gpu_addr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment