aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorIlija Hadzic <ihadzic@research.bell-labs.com>2011-10-12 23:29:41 -0400
committerDave Airlie <airlied@redhat.com>2011-10-18 05:10:52 -0400
commitfb3d9e97e1ad5f2c19b68fe5a0c6a95bf57c65c3 (patch)
tree144cf1b5b2cd3acee7ebb2c5a199074cf01d1fb4 /drivers/gpu/drm
parentb353096345f928d8c1164117804d1407790fb5f3 (diff)
drm/radeon/kms: blit code commoning
factor out most of evergreen blit code and use the refactored code from r600 that is now common for both r600 and evergreen Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c25
-rw-r--r--drivers/gpu/drm/radeon/evergreen_blit_kms.c260
-rw-r--r--drivers/gpu/drm/radeon/ni.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c16
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h10
5 files changed, 30 insertions, 285 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 7cd402412054..b37b6a0bbec9 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3087,7 +3087,7 @@ static int evergreen_startup(struct radeon_device *rdev)
3087 3087
3088 r = evergreen_blit_init(rdev); 3088 r = evergreen_blit_init(rdev);
3089 if (r) { 3089 if (r) {
3090 evergreen_blit_fini(rdev); 3090 r600_blit_fini(rdev);
3091 rdev->asic->copy = NULL; 3091 rdev->asic->copy = NULL;
3092 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); 3092 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
3093 } 3093 }
@@ -3172,27 +3172,6 @@ int evergreen_suspend(struct radeon_device *rdev)
3172 return 0; 3172 return 0;
3173} 3173}
3174 3174
3175int evergreen_copy_blit(struct radeon_device *rdev,
3176 uint64_t src_offset, uint64_t dst_offset,
3177 unsigned num_pages, struct radeon_fence *fence)
3178{
3179 int r;
3180
3181 mutex_lock(&rdev->r600_blit.mutex);
3182 rdev->r600_blit.vb_ib = NULL;
3183 r = evergreen_blit_prepare_copy(rdev, num_pages);
3184 if (r) {
3185 if (rdev->r600_blit.vb_ib)
3186 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
3187 mutex_unlock(&rdev->r600_blit.mutex);
3188 return r;
3189 }
3190 evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages);
3191 evergreen_blit_done_copy(rdev, fence);
3192 mutex_unlock(&rdev->r600_blit.mutex);
3193 return 0;
3194}
3195
3196/* Plan is to move initialization in that function and use 3175/* Plan is to move initialization in that function and use
3197 * helper function so that radeon_device_init pretty much 3176 * helper function so that radeon_device_init pretty much
3198 * do nothing more than calling asic specific function. This 3177 * do nothing more than calling asic specific function. This
@@ -3301,7 +3280,7 @@ int evergreen_init(struct radeon_device *rdev)
3301 3280
3302void evergreen_fini(struct radeon_device *rdev) 3281void evergreen_fini(struct radeon_device *rdev)
3303{ 3282{
3304 evergreen_blit_fini(rdev); 3283 r600_blit_fini(rdev);
3305 r700_cp_fini(rdev); 3284 r700_cp_fini(rdev);
3306 r600_irq_fini(rdev); 3285 r600_irq_fini(rdev);
3307 radeon_wb_fini(rdev); 3286 radeon_wb_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index 5befd5139002..dcf11bbc06d9 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -44,10 +44,6 @@
44#define COLOR_5_6_5 0x8 44#define COLOR_5_6_5 0x8
45#define COLOR_8_8_8_8 0x1a 45#define COLOR_8_8_8_8 0x1a
46 46
47#define RECT_UNIT_H 32
48#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
49#define MAX_RECT_DIM 16384
50
51/* emits 17 */ 47/* emits 17 */
52static void 48static void
53set_render_target(struct radeon_device *rdev, int format, 49set_render_target(struct radeon_device *rdev, int format,
@@ -599,31 +595,6 @@ set_default_state(struct radeon_device *rdev)
599 595
600} 596}
601 597
602static uint32_t i2f(uint32_t input)
603{
604 u32 result, i, exponent, fraction;
605
606 if ((input & 0x3fff) == 0)
607 result = 0; /* 0 is a special case */
608 else {
609 exponent = 140; /* exponent biased by 127; */
610 fraction = (input & 0x3fff) << 10; /* cheat and only
611 handle numbers below 2^^15 */
612 for (i = 0; i < 14; i++) {
613 if (fraction & 0x800000)
614 break;
615 else {
616 fraction = fraction << 1; /* keep
617 shifting left until top bit = 1 */
618 exponent = exponent - 1;
619 }
620 }
621 result = exponent << 23 | (fraction & 0x7fffff); /* mask
622 off top bit; assumed 1 */
623 }
624 return result;
625}
626
627int evergreen_blit_init(struct radeon_device *rdev) 598int evergreen_blit_init(struct radeon_device *rdev)
628{ 599{
629 u32 obj_size; 600 u32 obj_size;
@@ -632,6 +603,24 @@ int evergreen_blit_init(struct radeon_device *rdev)
632 u32 packet2s[16]; 603 u32 packet2s[16];
633 int num_packet2s = 0; 604 int num_packet2s = 0;
634 605
606 rdev->r600_blit.primitives.set_render_target = set_render_target;
607 rdev->r600_blit.primitives.cp_set_surface_sync = cp_set_surface_sync;
608 rdev->r600_blit.primitives.set_shaders = set_shaders;
609 rdev->r600_blit.primitives.set_vtx_resource = set_vtx_resource;
610 rdev->r600_blit.primitives.set_tex_resource = set_tex_resource;
611 rdev->r600_blit.primitives.set_scissors = set_scissors;
612 rdev->r600_blit.primitives.draw_auto = draw_auto;
613 rdev->r600_blit.primitives.set_default_state = set_default_state;
614
615 rdev->r600_blit.ring_size_common = 55; /* shaders + def state */
616 rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
617 rdev->r600_blit.ring_size_common += 5; /* done copy */
618 rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
619
620 rdev->r600_blit.ring_size_per_loop = 74;
621
622 rdev->r600_blit.max_dim = 16384;
623
635 /* pin copy shader into vram if already initialized */ 624 /* pin copy shader into vram if already initialized */
636 if (rdev->r600_blit.shader_obj) 625 if (rdev->r600_blit.shader_obj)
637 goto done; 626 goto done;
@@ -727,216 +716,3 @@ done:
727 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); 716 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
728 return 0; 717 return 0;
729} 718}
730
731void evergreen_blit_fini(struct radeon_device *rdev)
732{
733 int r;
734
735 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
736 if (rdev->r600_blit.shader_obj == NULL)
737 return;
738 /* If we can't reserve the bo, unref should be enough to destroy
739 * it when it becomes idle.
740 */
741 r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
742 if (!r) {
743 radeon_bo_unpin(rdev->r600_blit.shader_obj);
744 radeon_bo_unreserve(rdev->r600_blit.shader_obj);
745 }
746 radeon_bo_unref(&rdev->r600_blit.shader_obj);
747}
748
749static int evergreen_vb_ib_get(struct radeon_device *rdev)
750{
751 int r;
752 r = radeon_ib_get(rdev, &rdev->r600_blit.vb_ib);
753 if (r) {
754 DRM_ERROR("failed to get IB for vertex buffer\n");
755 return r;
756 }
757
758 rdev->r600_blit.vb_total = 64*1024;
759 rdev->r600_blit.vb_used = 0;
760 return 0;
761}
762
763static void evergreen_vb_ib_put(struct radeon_device *rdev)
764{
765 radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence);
766 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
767}
768
769
770/* maps the rectangle to the buffer so that satisfies the following properties:
771 * - dimensions are less or equal to the hardware limit (MAX_RECT_DIM)
772 * - rectangle consists of integer number of pages
773 * - height is an integer multiple of RECT_UNIT_H
774 * - width is an integer multiple of RECT_UNIT_W
775 * - (the above three conditions also guarantee tile-aligned size)
776 * - it is as square as possible (sides ratio never greater than 2:1)
777 * - uses maximum number of pages that fit the above constraints
778 *
779 * input: buffer size, pointers to width/height variables
780 * return: number of pages that were successfully mapped to the rectangle
781 * width/height of the rectangle
782 */
783static unsigned evergreen_blit_create_rect(unsigned num_pages, int *width, int *height)
784{
785 unsigned max_pages;
786 unsigned pages = num_pages;
787 int w, h;
788
789 if (num_pages == 0) {
790 /* not supposed to be called with no pages, but just in case */
791 h = 0;
792 w = 0;
793 pages = 0;
794 WARN_ON(1);
795 } else {
796 int rect_order = 2;
797 h = RECT_UNIT_H;
798 while (num_pages / rect_order) {
799 h *= 2;
800 rect_order *= 4;
801 if (h >= MAX_RECT_DIM) {
802 h = MAX_RECT_DIM;
803 break;
804 }
805 }
806 max_pages = (MAX_RECT_DIM * h) / (RECT_UNIT_W * RECT_UNIT_H);
807 if (pages > max_pages)
808 pages = max_pages;
809 w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h;
810 w = (w / RECT_UNIT_W) * RECT_UNIT_W;
811 pages = (w * h) / (RECT_UNIT_W * RECT_UNIT_H);
812 BUG_ON(pages == 0);
813 }
814
815
816 DRM_DEBUG("blit_rectangle: h=%d, w=%d, pages=%d\n", h, w, pages);
817
818 /* return width and height only of the caller wants it */
819 if (height)
820 *height = h;
821 if (width)
822 *width = w;
823
824 return pages;
825}
826
827int evergreen_blit_prepare_copy(struct radeon_device *rdev, unsigned num_pages)
828{
829 int r;
830 int ring_size;
831 /* loops of emits + fence emit possible */
832 int dwords_per_loop = 74, num_loops = 0;
833
834 r = evergreen_vb_ib_get(rdev);
835 if (r)
836 return r;
837
838 /* num loops */
839 while (num_pages) {
840 num_pages -= evergreen_blit_create_rect(num_pages, NULL, NULL);
841 num_loops++;
842 }
843 /* calculate number of loops correctly */
844 ring_size = num_loops * dwords_per_loop;
845 /* set default + shaders */
846 ring_size += 55; /* shaders + def state */
847 ring_size += 10; /* fence emit for VB IB */
848 ring_size += 5; /* done copy */
849 ring_size += 10; /* fence emit for done copy */
850 r = radeon_ring_lock(rdev, ring_size);
851 if (r)
852 return r;
853
854 set_default_state(rdev); /* 36 */
855 set_shaders(rdev); /* 16 */
856 return 0;
857}
858
859void evergreen_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence)
860{
861 int r;
862
863 if (rdev->r600_blit.vb_ib)
864 evergreen_vb_ib_put(rdev);
865
866 if (fence)
867 r = radeon_fence_emit(rdev, fence);
868
869 radeon_ring_unlock_commit(rdev);
870}
871
872void evergreen_kms_blit_copy(struct radeon_device *rdev,
873 u64 src_gpu_addr, u64 dst_gpu_addr,
874 unsigned num_pages)
875{
876 u64 vb_gpu_addr;
877 u32 *vb;
878
879 DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
880 num_pages, rdev->r600_blit.vb_used);
881 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
882
883 while (num_pages) {
884 int w, h;
885 unsigned size_in_bytes;
886 unsigned pages_per_loop = evergreen_blit_create_rect(num_pages, &w, &h);
887
888 size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE;
889 DRM_DEBUG("rectangle w=%d h=%d\n", w, h);
890
891 if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) {
892 WARN_ON(1);
893 }
894
895 vb[0] = 0;
896 vb[1] = 0;
897 vb[2] = 0;
898 vb[3] = 0;
899
900 vb[4] = 0;
901 vb[5] = i2f(h);
902 vb[6] = 0;
903 vb[7] = i2f(h);
904
905 vb[8] = i2f(w);
906 vb[9] = i2f(h);
907 vb[10] = i2f(w);
908 vb[11] = i2f(h);
909
910 /* src 10 */
911 set_tex_resource(rdev, FMT_8_8_8_8, w, h, w, src_gpu_addr);
912
913 /* 5 */
914 cp_set_surface_sync(rdev,
915 PACKET3_TC_ACTION_ENA, size_in_bytes, src_gpu_addr);
916
917 /* dst 17 */
918 set_render_target(rdev, COLOR_8_8_8_8, w, h, dst_gpu_addr);
919
920 /* scissors 12 */
921 set_scissors(rdev, 0, 0, w, h);
922
923 /* Vertex buffer setup 15 */
924 vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
925 set_vtx_resource(rdev, vb_gpu_addr);
926
927 /* draw 10 */
928 draw_auto(rdev);
929
930 /* 5 */
931 cp_set_surface_sync(rdev,
932 PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
933 size_in_bytes, dst_gpu_addr);
934
935 /* 74 ring dwords per loop */
936 vb += 12;
937 rdev->r600_blit.vb_used += 4*12;
938 src_gpu_addr += size_in_bytes;
939 dst_gpu_addr += size_in_bytes;
940 num_pages -= pages_per_loop;
941 }
942}
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index b6c8a4880a86..b5da6dab5682 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1401,7 +1401,7 @@ static int cayman_startup(struct radeon_device *rdev)
1401 1401
1402 r = evergreen_blit_init(rdev); 1402 r = evergreen_blit_init(rdev);
1403 if (r) { 1403 if (r) {
1404 evergreen_blit_fini(rdev); 1404 r600_blit_fini(rdev);
1405 rdev->asic->copy = NULL; 1405 rdev->asic->copy = NULL;
1406 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); 1406 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
1407 } 1407 }
@@ -1589,7 +1589,7 @@ int cayman_init(struct radeon_device *rdev)
1589 1589
1590void cayman_fini(struct radeon_device *rdev) 1590void cayman_fini(struct radeon_device *rdev)
1591{ 1591{
1592 evergreen_blit_fini(rdev); 1592 r600_blit_fini(rdev);
1593 cayman_cp_fini(rdev); 1593 cayman_cp_fini(rdev);
1594 r600_irq_fini(rdev); 1594 r600_irq_fini(rdev);
1595 radeon_wb_fini(rdev); 1595 radeon_wb_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index df8218bb83a6..e2944566ffea 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -765,9 +765,9 @@ static struct radeon_asic evergreen_asic = {
765 .get_vblank_counter = &evergreen_get_vblank_counter, 765 .get_vblank_counter = &evergreen_get_vblank_counter,
766 .fence_ring_emit = &r600_fence_ring_emit, 766 .fence_ring_emit = &r600_fence_ring_emit,
767 .cs_parse = &evergreen_cs_parse, 767 .cs_parse = &evergreen_cs_parse,
768 .copy_blit = &evergreen_copy_blit, 768 .copy_blit = &r600_copy_blit,
769 .copy_dma = NULL, 769 .copy_dma = NULL,
770 .copy = &evergreen_copy_blit, 770 .copy = &r600_copy_blit,
771 .get_engine_clock = &radeon_atom_get_engine_clock, 771 .get_engine_clock = &radeon_atom_get_engine_clock,
772 .set_engine_clock = &radeon_atom_set_engine_clock, 772 .set_engine_clock = &radeon_atom_set_engine_clock,
773 .get_memory_clock = &radeon_atom_get_memory_clock, 773 .get_memory_clock = &radeon_atom_get_memory_clock,
@@ -812,9 +812,9 @@ static struct radeon_asic sumo_asic = {
812 .get_vblank_counter = &evergreen_get_vblank_counter, 812 .get_vblank_counter = &evergreen_get_vblank_counter,
813 .fence_ring_emit = &r600_fence_ring_emit, 813 .fence_ring_emit = &r600_fence_ring_emit,
814 .cs_parse = &evergreen_cs_parse, 814 .cs_parse = &evergreen_cs_parse,
815 .copy_blit = &evergreen_copy_blit, 815 .copy_blit = &r600_copy_blit,
816 .copy_dma = NULL, 816 .copy_dma = NULL,
817 .copy = &evergreen_copy_blit, 817 .copy = &r600_copy_blit,
818 .get_engine_clock = &radeon_atom_get_engine_clock, 818 .get_engine_clock = &radeon_atom_get_engine_clock,
819 .set_engine_clock = &radeon_atom_set_engine_clock, 819 .set_engine_clock = &radeon_atom_set_engine_clock,
820 .get_memory_clock = NULL, 820 .get_memory_clock = NULL,
@@ -859,9 +859,9 @@ static struct radeon_asic btc_asic = {
859 .get_vblank_counter = &evergreen_get_vblank_counter, 859 .get_vblank_counter = &evergreen_get_vblank_counter,
860 .fence_ring_emit = &r600_fence_ring_emit, 860 .fence_ring_emit = &r600_fence_ring_emit,
861 .cs_parse = &evergreen_cs_parse, 861 .cs_parse = &evergreen_cs_parse,
862 .copy_blit = &evergreen_copy_blit, 862 .copy_blit = &r600_copy_blit,
863 .copy_dma = NULL, 863 .copy_dma = NULL,
864 .copy = &evergreen_copy_blit, 864 .copy = &r600_copy_blit,
865 .get_engine_clock = &radeon_atom_get_engine_clock, 865 .get_engine_clock = &radeon_atom_get_engine_clock,
866 .set_engine_clock = &radeon_atom_set_engine_clock, 866 .set_engine_clock = &radeon_atom_set_engine_clock,
867 .get_memory_clock = &radeon_atom_get_memory_clock, 867 .get_memory_clock = &radeon_atom_get_memory_clock,
@@ -906,9 +906,9 @@ static struct radeon_asic cayman_asic = {
906 .get_vblank_counter = &evergreen_get_vblank_counter, 906 .get_vblank_counter = &evergreen_get_vblank_counter,
907 .fence_ring_emit = &r600_fence_ring_emit, 907 .fence_ring_emit = &r600_fence_ring_emit,
908 .cs_parse = &evergreen_cs_parse, 908 .cs_parse = &evergreen_cs_parse,
909 .copy_blit = &evergreen_copy_blit, 909 .copy_blit = &r600_copy_blit,
910 .copy_dma = NULL, 910 .copy_dma = NULL,
911 .copy = &evergreen_copy_blit, 911 .copy = &r600_copy_blit,
912 .get_engine_clock = &radeon_atom_get_engine_clock, 912 .get_engine_clock = &radeon_atom_get_engine_clock,
913 .set_engine_clock = &radeon_atom_set_engine_clock, 913 .set_engine_clock = &radeon_atom_set_engine_clock,
914 .get_memory_clock = &radeon_atom_get_memory_clock, 914 .get_memory_clock = &radeon_atom_get_memory_clock,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index cd60da562ecd..e040de3e8cc7 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -401,9 +401,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev);
401int evergreen_asic_reset(struct radeon_device *rdev); 401int evergreen_asic_reset(struct radeon_device *rdev);
402void evergreen_bandwidth_update(struct radeon_device *rdev); 402void evergreen_bandwidth_update(struct radeon_device *rdev);
403void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); 403void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
404int evergreen_copy_blit(struct radeon_device *rdev,
405 uint64_t src_offset, uint64_t dst_offset,
406 unsigned num_pages, struct radeon_fence *fence);
407void evergreen_hpd_init(struct radeon_device *rdev); 404void evergreen_hpd_init(struct radeon_device *rdev);
408void evergreen_hpd_fini(struct radeon_device *rdev); 405void evergreen_hpd_fini(struct radeon_device *rdev);
409bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); 406bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
@@ -421,13 +418,6 @@ extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_ba
421extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); 418extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
422void evergreen_disable_interrupt_state(struct radeon_device *rdev); 419void evergreen_disable_interrupt_state(struct radeon_device *rdev);
423int evergreen_blit_init(struct radeon_device *rdev); 420int evergreen_blit_init(struct radeon_device *rdev);
424void evergreen_blit_fini(struct radeon_device *rdev);
425/* evergreen blit */
426int evergreen_blit_prepare_copy(struct radeon_device *rdev, unsigned num_pages);
427void evergreen_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence);
428void evergreen_kms_blit_copy(struct radeon_device *rdev,
429 u64 src_gpu_addr, u64 dst_gpu_addr,
430 unsigned num_pages);
431 421
432/* 422/*
433 * cayman 423 * cayman