1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- #include <drm/drmP.h>
- #include "radeon.h"
- #include "radeon_asic.h"
- #include "rv770d.h"
- struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
- uint64_t src_offset, uint64_t dst_offset,
- unsigned num_gpu_pages,
- struct reservation_object *resv)
- {
- struct radeon_fence *fence;
- struct radeon_sync sync;
- int ring_index = rdev->asic->copy.dma_ring_index;
- struct radeon_ring *ring = &rdev->ring[ring_index];
- u32 size_in_dw, cur_size_in_dw;
- int i, num_loops;
- int r = 0;
- radeon_sync_create(&sync);
- size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
- num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF);
- r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8);
- if (r) {
- DRM_ERROR("radeon: moving bo (%d).\n", r);
- radeon_sync_free(rdev, &sync, NULL);
- return ERR_PTR(r);
- }
- radeon_sync_resv(rdev, &sync, resv, false);
- radeon_sync_rings(rdev, &sync, ring->idx);
- for (i = 0; i < num_loops; i++) {
- cur_size_in_dw = size_in_dw;
- if (cur_size_in_dw > 0xFFFF)
- cur_size_in_dw = 0xFFFF;
- size_in_dw -= cur_size_in_dw;
- radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw));
- radeon_ring_write(ring, dst_offset & 0xfffffffc);
- radeon_ring_write(ring, src_offset & 0xfffffffc);
- radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
- radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff);
- src_offset += cur_size_in_dw * 4;
- dst_offset += cur_size_in_dw * 4;
- }
- r = radeon_fence_emit(rdev, &fence, ring->idx);
- if (r) {
- radeon_ring_unlock_undo(rdev, ring);
- radeon_sync_free(rdev, &sync, NULL);
- return ERR_PTR(r);
- }
- radeon_ring_unlock_commit(rdev, ring, false);
- radeon_sync_free(rdev, &sync, fence);
- return fence;
- }
|