diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-01-04 09:24:18 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-01-04 09:29:54 -0500 |
commit | 43fb778754ffd1ef8b4f579a5c94f118292acfb5 (patch) | |
tree | 044dac1f191507b1348d558a2a805003c00a1414 /drivers/gpu | |
parent | eda85d6ad490923152544fba0473798b6cc0edf6 (diff) |
drm/radeon: split r6xx and r7xx copy_dma functions
- r6xx actually uses a slightly different packet format,
although both formats seem to work ok.
- r7xx doesn't have the count multiple of 2 limitation.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 74 |
4 files changed, 85 insertions, 7 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 923f93647042..537e259b3837 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2646,7 +2646,7 @@ int r600_copy_blit(struct radeon_device *rdev, | |||
2646 | * @num_gpu_pages: number of GPU pages to xfer | 2646 | * @num_gpu_pages: number of GPU pages to xfer |
2647 | * @fence: radeon fence object | 2647 | * @fence: radeon fence object |
2648 | * | 2648 | * |
2649 | * Copy GPU paging using the DMA engine (r6xx-r7xx). | 2649 | * Copy GPU paging using the DMA engine (r6xx). |
2650 | * Used by the radeon ttm implementation to move pages if | 2650 | * Used by the radeon ttm implementation to move pages if |
2651 | * registered as the asic copy callback. | 2651 | * registered as the asic copy callback. |
2652 | */ | 2652 | */ |
@@ -2669,8 +2669,8 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
2669 | } | 2669 | } |
2670 | 2670 | ||
2671 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | 2671 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; |
2672 | num_loops = DIV_ROUND_UP(size_in_dw, 0xffff); | 2672 | num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE); |
2673 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); | 2673 | r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8); |
2674 | if (r) { | 2674 | if (r) { |
2675 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 2675 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
2676 | radeon_semaphore_free(rdev, &sem, NULL); | 2676 | radeon_semaphore_free(rdev, &sem, NULL); |
@@ -2693,8 +2693,8 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
2693 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); | 2693 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); |
2694 | radeon_ring_write(ring, dst_offset & 0xfffffffc); | 2694 | radeon_ring_write(ring, dst_offset & 0xfffffffc); |
2695 | radeon_ring_write(ring, src_offset & 0xfffffffc); | 2695 | radeon_ring_write(ring, src_offset & 0xfffffffc); |
2696 | radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff); | 2696 | radeon_ring_write(ring, (((upper_32_bits(dst_offset) & 0xff) << 16) | |
2697 | radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff); | 2697 | (upper_32_bits(src_offset) & 0xff))); |
2698 | src_offset += cur_size_in_dw * 4; | 2698 | src_offset += cur_size_in_dw * 4; |
2699 | dst_offset += cur_size_in_dw * 4; | 2699 | dst_offset += cur_size_in_dw * 4; |
2700 | } | 2700 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 596bcbe80ed0..9056fafb00ea 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1140,9 +1140,9 @@ static struct radeon_asic rv770_asic = { | |||
1140 | .copy = { | 1140 | .copy = { |
1141 | .blit = &r600_copy_blit, | 1141 | .blit = &r600_copy_blit, |
1142 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1142 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1143 | .dma = &r600_copy_dma, | 1143 | .dma = &rv770_copy_dma, |
1144 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, | 1144 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
1145 | .copy = &r600_copy_dma, | 1145 | .copy = &rv770_copy_dma, |
1146 | .copy_ring_index = R600_RING_TYPE_DMA_INDEX, | 1146 | .copy_ring_index = R600_RING_TYPE_DMA_INDEX, |
1147 | }, | 1147 | }, |
1148 | .surface = { | 1148 | .surface = { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 5f4882cc2152..15d70e613076 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -403,6 +403,10 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | |||
403 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); | 403 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); |
404 | void r700_cp_stop(struct radeon_device *rdev); | 404 | void r700_cp_stop(struct radeon_device *rdev); |
405 | void r700_cp_fini(struct radeon_device *rdev); | 405 | void r700_cp_fini(struct radeon_device *rdev); |
406 | int rv770_copy_dma(struct radeon_device *rdev, | ||
407 | uint64_t src_offset, uint64_t dst_offset, | ||
408 | unsigned num_gpu_pages, | ||
409 | struct radeon_fence **fence); | ||
406 | 410 | ||
407 | /* | 411 | /* |
408 | * evergreen | 412 | * evergreen |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 87c979c4f721..1b2444f4d8f4 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -887,6 +887,80 @@ static int rv770_mc_init(struct radeon_device *rdev) | |||
887 | return 0; | 887 | return 0; |
888 | } | 888 | } |
889 | 889 | ||
890 | /** | ||
891 | * rv770_copy_dma - copy pages using the DMA engine | ||
892 | * | ||
893 | * @rdev: radeon_device pointer | ||
894 | * @src_offset: src GPU address | ||
895 | * @dst_offset: dst GPU address | ||
896 | * @num_gpu_pages: number of GPU pages to xfer | ||
897 | * @fence: radeon fence object | ||
898 | * | ||
899 | * Copy GPU paging using the DMA engine (r7xx). | ||
900 | * Used by the radeon ttm implementation to move pages if | ||
901 | * registered as the asic copy callback. | ||
902 | */ | ||
903 | int rv770_copy_dma(struct radeon_device *rdev, | ||
904 | uint64_t src_offset, uint64_t dst_offset, | ||
905 | unsigned num_gpu_pages, | ||
906 | struct radeon_fence **fence) | ||
907 | { | ||
908 | struct radeon_semaphore *sem = NULL; | ||
909 | int ring_index = rdev->asic->copy.dma_ring_index; | ||
910 | struct radeon_ring *ring = &rdev->ring[ring_index]; | ||
911 | u32 size_in_dw, cur_size_in_dw; | ||
912 | int i, num_loops; | ||
913 | int r = 0; | ||
914 | |||
915 | r = radeon_semaphore_create(rdev, &sem); | ||
916 | if (r) { | ||
917 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
918 | return r; | ||
919 | } | ||
920 | |||
921 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | ||
922 | num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF); | ||
923 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); | ||
924 | if (r) { | ||
925 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
926 | radeon_semaphore_free(rdev, &sem, NULL); | ||
927 | return r; | ||
928 | } | ||
929 | |||
930 | if (radeon_fence_need_sync(*fence, ring->idx)) { | ||
931 | radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, | ||
932 | ring->idx); | ||
933 | radeon_fence_note_sync(*fence, ring->idx); | ||
934 | } else { | ||
935 | radeon_semaphore_free(rdev, &sem, NULL); | ||
936 | } | ||
937 | |||
938 | for (i = 0; i < num_loops; i++) { | ||
939 | cur_size_in_dw = size_in_dw; | ||
940 | if (cur_size_in_dw > 0xFFFF) | ||
941 | cur_size_in_dw = 0xFFFF; | ||
942 | size_in_dw -= cur_size_in_dw; | ||
943 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); | ||
944 | radeon_ring_write(ring, dst_offset & 0xfffffffc); | ||
945 | radeon_ring_write(ring, src_offset & 0xfffffffc); | ||
946 | radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff); | ||
947 | radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff); | ||
948 | src_offset += cur_size_in_dw * 4; | ||
949 | dst_offset += cur_size_in_dw * 4; | ||
950 | } | ||
951 | |||
952 | r = radeon_fence_emit(rdev, fence, ring->idx); | ||
953 | if (r) { | ||
954 | radeon_ring_unlock_undo(rdev, ring); | ||
955 | return r; | ||
956 | } | ||
957 | |||
958 | radeon_ring_unlock_commit(rdev, ring); | ||
959 | radeon_semaphore_free(rdev, &sem, *fence); | ||
960 | |||
961 | return r; | ||
962 | } | ||
963 | |||
890 | static int rv770_startup(struct radeon_device *rdev) | 964 | static int rv770_startup(struct radeon_device *rdev) |
891 | { | 965 | { |
892 | struct radeon_ring *ring; | 966 | struct radeon_ring *ring; |