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: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
43e917251a
commit
c9dbd70552
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue