aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/r600.c4
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c280
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h4
3 files changed, 111 insertions, 177 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c4de1610088c..e106f30787fd 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2363,14 +2363,14 @@ int r600_copy_blit(struct radeon_device *rdev,
2363 2363
2364 mutex_lock(&rdev->r600_blit.mutex); 2364 mutex_lock(&rdev->r600_blit.mutex);
2365 rdev->r600_blit.vb_ib = NULL; 2365 rdev->r600_blit.vb_ib = NULL;
2366 r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); 2366 r = r600_blit_prepare_copy(rdev, num_pages);
2367 if (r) { 2367 if (r) {
2368 if (rdev->r600_blit.vb_ib) 2368 if (rdev->r600_blit.vb_ib)
2369 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); 2369 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
2370 mutex_unlock(&rdev->r600_blit.mutex); 2370 mutex_unlock(&rdev->r600_blit.mutex);
2371 return r; 2371 return r;
2372 } 2372 }
2373 r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); 2373 r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages);
2374 r600_blit_done_copy(rdev, fence); 2374 r600_blit_done_copy(rdev, fence);
2375 mutex_unlock(&rdev->r600_blit.mutex); 2375 mutex_unlock(&rdev->r600_blit.mutex);
2376 return 0; 2376 return 0;
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index bbbafe685543..3940be619af7 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -42,6 +42,10 @@
42#define COLOR_5_6_5 0x8 42#define COLOR_5_6_5 0x8
43#define COLOR_8_8_8_8 0x1a 43#define COLOR_8_8_8_8 0x1a
44 44
45#define RECT_UNIT_H 32
46#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
47#define MAX_RECT_DIM 8192
48
45/* emits 21 on rv770+, 23 on r600 */ 49/* emits 21 on rv770+, 23 on r600 */
46static void 50static void
47set_render_target(struct radeon_device *rdev, int format, 51set_render_target(struct radeon_device *rdev, int format,
@@ -600,13 +604,59 @@ static void r600_vb_ib_put(struct radeon_device *rdev)
600 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); 604 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
601} 605}
602 606
603int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) 607/* FIXME: the function is very similar to evergreen_blit_create_rect, except
608 that it different predefined constants; consider commonizing */
609static unsigned r600_blit_create_rect(unsigned num_pages, int *width, int *height)
610{
611 unsigned max_pages;
612 unsigned pages = num_pages;
613 int w, h;
614
615 if (num_pages == 0) {
616 /* not supposed to be called with no pages, but just in case */
617 h = 0;
618 w = 0;
619 pages = 0;
620 WARN_ON(1);
621 } else {
622 int rect_order = 2;
623 h = RECT_UNIT_H;
624 while (num_pages / rect_order) {
625 h *= 2;
626 rect_order *= 4;
627 if (h >= MAX_RECT_DIM) {
628 h = MAX_RECT_DIM;
629 break;
630 }
631 }
632 max_pages = (MAX_RECT_DIM * h) / (RECT_UNIT_W * RECT_UNIT_H);
633 if (pages > max_pages)
634 pages = max_pages;
635 w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h;
636 w = (w / RECT_UNIT_W) * RECT_UNIT_W;
637 pages = (w * h) / (RECT_UNIT_W * RECT_UNIT_H);
638 BUG_ON(pages == 0);
639 }
640
641
642 DRM_DEBUG("blit_rectangle: h=%d, w=%d, pages=%d\n", h, w, pages);
643
644 /* return width and height only of the caller wants it */
645 if (height)
646 *height = h;
647 if (width)
648 *width = w;
649
650 return pages;
651}
652
653
654int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_pages)
604{ 655{
605 int r; 656 int r;
606 int ring_size, line_size; 657 int ring_size;
607 int max_size;
608 /* loops of emits 64 + fence emit possible */ 658 /* loops of emits 64 + fence emit possible */
609 int dwords_per_loop = 76, num_loops; 659 int dwords_per_loop = 76, num_loops = 0;
610 660
611 r = r600_vb_ib_get(rdev); 661 r = r600_vb_ib_get(rdev);
612 if (r) 662 if (r)
@@ -616,18 +666,12 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
616 if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) 666 if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
617 dwords_per_loop += 2; 667 dwords_per_loop += 2;
618 668
619 /* 8 bpp vs 32 bpp for xfer unit */ 669 /* num loops */
620 if (size_bytes & 3) 670 while (num_pages) {
621 line_size = 8192; 671 num_pages -= r600_blit_create_rect(num_pages, NULL, NULL);
622 else 672 num_loops++;
623 line_size = 8192*4; 673 }
624
625 max_size = 8192 * line_size;
626 674
627 /* major loops cover the max size transfer */
628 num_loops = ((size_bytes + max_size) / max_size);
629 /* minor loops cover the extra non aligned bits */
630 num_loops += ((size_bytes % line_size) ? 1 : 0);
631 /* calculate number of loops correctly */ 675 /* calculate number of loops correctly */
632 ring_size = num_loops * dwords_per_loop; 676 ring_size = num_loops * dwords_per_loop;
633 /* set default + shaders */ 677 /* set default + shaders */
@@ -659,182 +703,72 @@ void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence)
659 703
660void r600_kms_blit_copy(struct radeon_device *rdev, 704void r600_kms_blit_copy(struct radeon_device *rdev,
661 u64 src_gpu_addr, u64 dst_gpu_addr, 705 u64 src_gpu_addr, u64 dst_gpu_addr,
662 int size_bytes) 706 unsigned num_pages)
663{ 707{
664 int max_bytes;
665 u64 vb_gpu_addr; 708 u64 vb_gpu_addr;
666 u32 *vb; 709 u32 *vb;
667 710
668 DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, 711 DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
669 size_bytes, rdev->r600_blit.vb_used); 712 num_pages, rdev->r600_blit.vb_used);
670 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); 713 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
671 if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
672 max_bytes = 8192;
673
674 while (size_bytes) {
675 int cur_size = size_bytes;
676 int src_x = src_gpu_addr & 255;
677 int dst_x = dst_gpu_addr & 255;
678 int h = 1;
679 src_gpu_addr = src_gpu_addr & ~255ULL;
680 dst_gpu_addr = dst_gpu_addr & ~255ULL;
681
682 if (!src_x && !dst_x) {
683 h = (cur_size / max_bytes);
684 if (h > 8192)
685 h = 8192;
686 if (h == 0)
687 h = 1;
688 else
689 cur_size = max_bytes;
690 } else {
691 if (cur_size > max_bytes)
692 cur_size = max_bytes;
693 if (cur_size > (max_bytes - dst_x))
694 cur_size = (max_bytes - dst_x);
695 if (cur_size > (max_bytes - src_x))
696 cur_size = (max_bytes - src_x);
697 }
698 714
699 if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { 715 while (num_pages) {
700 WARN_ON(1); 716 int w, h;
701 } 717 unsigned size_in_bytes;
718 unsigned pages_per_loop = r600_blit_create_rect(num_pages, &w, &h);