Commit c9dbd705 authored by Alex Deucher's avatar Alex Deucher

drm/radeon: implement blit copy callback for CIK

Uses the CP ring rather than the DMA ring.  Useful
for debugging and benchmarking.
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 43e91725
......@@ -3094,6 +3094,85 @@ void cik_semaphore_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel);
}
/**
* cik_copy_cpdma - copy pages using the CP DMA engine
*
* @rdev: radeon_device pointer
* @src_offset: src GPU address
* @dst_offset: dst GPU address
* @num_gpu_pages: number of GPU pages to xfer
* @fence: radeon fence object
*
* Copy GPU paging using the CP DMA engine (CIK+).
* Used by the radeon ttm implementation to move pages if
* registered as the asic copy callback.
*/
int cik_copy_cpdma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages,
struct radeon_fence **fence)
{
struct radeon_semaphore *sem = NULL;
int ring_index = rdev->asic->copy.blit_ring_index;
struct radeon_ring *ring = &rdev->ring[ring_index];
u32 size_in_bytes, cur_size_in_bytes, control;
int i, num_loops;
int r = 0;
r = radeon_semaphore_create(rdev, &sem);
if (r) {
DRM_ERROR("radeon: moving bo (%d).\n", r);
return r;
}
size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff);
r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18);
if (r) {
DRM_ERROR("radeon: moving bo (%d).\n", r);
radeon_semaphore_free(rdev, &sem, NULL);
return r;
}
if (radeon_fence_need_sync(*fence, ring->idx)) {
radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
ring->idx);
radeon_fence_note_sync(*fence, ring->idx);
} else {
radeon_semaphore_free(rdev, &sem, NULL);
}
for (i = 0; i < num_loops; i++) {
cur_size_in_bytes = size_in_bytes;
if (cur_size_in_bytes > 0x1fffff)
cur_size_in_bytes = 0x1fffff;
size_in_bytes -= cur_size_in_bytes;
control = 0;
if (size_in_bytes == 0)
control |= PACKET3_DMA_DATA_CP_SYNC;
radeon_ring_write(ring, PACKET3(PACKET3_DMA_DATA, 5));
radeon_ring_write(ring, control);
radeon_ring_write(ring, lower_32_bits(src_offset));
radeon_ring_write(ring, upper_32_bits(src_offset));
radeon_ring_write(ring, lower_32_bits(dst_offset));
radeon_ring_write(ring, upper_32_bits(dst_offset));
radeon_ring_write(ring, cur_size_in_bytes);
src_offset += cur_size_in_bytes;
dst_offset += cur_size_in_bytes;
}
r = radeon_fence_emit(rdev, fence, ring->idx);
if (r) {
radeon_ring_unlock_undo(rdev, ring);
return r;
}
radeon_ring_unlock_commit(rdev, ring);
radeon_semaphore_free(rdev, &sem, *fence);
return r;
}
/*
* IB stuff
*/
......
......@@ -1747,6 +1747,68 @@
# define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28)
# define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28)
#define PACKET3_DMA_DATA 0x50
/* 1. header
* 2. CONTROL
* 3. SRC_ADDR_LO or DATA [31:0]
* 4. SRC_ADDR_HI [31:0]
* 5. DST_ADDR_LO [31:0]
* 6. DST_ADDR_HI [7:0]
* 7. COMMAND [30:21] | BYTE_COUNT [20:0]
*/
/* CONTROL */
# define PACKET3_DMA_DATA_ENGINE(x) ((x) << 0)
/* 0 - ME
* 1 - PFP
*/
# define PACKET3_DMA_DATA_SRC_CACHE_POLICY(x) ((x) << 13)
/* 0 - LRU
* 1 - Stream
* 2 - Bypass
*/
# define PACKET3_DMA_DATA_SRC_VOLATILE (1 << 15)
# define PACKET3_DMA_DATA_DST_SEL(x) ((x) << 20)
/* 0 - DST_ADDR using DAS
* 1 - GDS
* 3 - DST_ADDR using L2
*/
# define PACKET3_DMA_DATA_DST_CACHE_POLICY(x) ((x) << 25)
/* 0 - LRU
* 1 - Stream
* 2 - Bypass
*/
# define PACKET3_DMA_DATA_DST_VOLATILE (1 << 27)
# define PACKET3_DMA_DATA_SRC_SEL(x) ((x) << 29)
/* 0 - SRC_ADDR using SAS
* 1 - GDS
* 2 - DATA
* 3 - SRC_ADDR using L2
*/
# define PACKET3_DMA_DATA_CP_SYNC (1 << 31)
/* COMMAND */
# define PACKET3_DMA_DATA_DIS_WC (1 << 21)
# define PACKET3_DMA_DATA_CMD_SRC_SWAP(x) ((x) << 22)
/* 0 - none
* 1 - 8 in 16
* 2 - 8 in 32
* 3 - 8 in 64
*/
# define PACKET3_DMA_DATA_CMD_DST_SWAP(x) ((x) << 24)
/* 0 - none
* 1 - 8 in 16
* 2 - 8 in 32
* 3 - 8 in 64
*/
# define PACKET3_DMA_DATA_CMD_SAS (1 << 26)
/* 0 - memory
* 1 - register
*/
# define PACKET3_DMA_DATA_CMD_DAS (1 << 27)
/* 0 - memory
* 1 - register
*/
# define PACKET3_DMA_DATA_CMD_SAIC (1 << 28)
# define PACKET3_DMA_DATA_CMD_DAIC (1 << 29)
# define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30)
#define PACKET3_AQUIRE_MEM 0x58
#define PACKET3_REWIND 0x59
#define PACKET3_LOAD_UCONFIG_REG 0x5E
......
......@@ -705,6 +705,10 @@ int cik_copy_dma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages,
struct radeon_fence **fence);
int cik_copy_cpdma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages,
struct radeon_fence **fence);
int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
......
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