aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2013-11-12 07:34:08 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-13 16:48:03 -0500
commitc3c43400a29dba30a581c97a6eb6952d187c3e07 (patch)
tree5a65e01f2ec18957e0f7db120ea6e88aefbf4377 /drivers/gpu
parent4f66403630544a1e5ad3b041fe0dba9db16ff6d9 (diff)
drm/nouveau: fix m2mf copy to tiled gart
commit ce8f7699f2b6ffe4aa8368b8d9d370875accaa5f upstream. Commit de7b7d59d54852c introduced tiled GART, but a linear copy is still performed. This may result in errors on eviction, fix it by checking tiling from memtype. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c33
1 files changed, 8 insertions, 25 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7ff10711a4d0..5a5f021d5863 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -788,25 +788,25 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
788 struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) 788 struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
789{ 789{
790 struct nouveau_mem *node = old_mem->mm_node; 790 struct nouveau_mem *node = old_mem->mm_node;
791 struct nouveau_bo *nvbo = nouveau_bo(bo);
792 u64 length = (new_mem->num_pages << PAGE_SHIFT); 791 u64 length = (new_mem->num_pages << PAGE_SHIFT);
793 u64 src_offset = node->vma[0].offset; 792 u64 src_offset = node->vma[0].offset;
794 u64 dst_offset = node->vma[1].offset; 793 u64 dst_offset = node->vma[1].offset;
794 int src_tiled = !!node->memtype;
795 int dst_tiled = !!((struct nouveau_mem *)new_mem->mm_node)->memtype;
795 int ret; 796 int ret;
796 797
797 while (length) { 798 while (length) {
798 u32 amount, stride, height; 799 u32 amount, stride, height;
799 800
801 ret = RING_SPACE(chan, 18 + 6 * (src_tiled + dst_tiled));
802 if (ret)
803 return ret;
804
800 amount = min(length, (u64)(4 * 1024 * 1024)); 805 amount = min(length, (u64)(4 * 1024 * 1024));
801 stride = 16 * 4; 806 stride = 16 * 4;
802 height = amount / stride; 807 height = amount / stride;
803 808
804 if (old_mem->mem_type == TTM_PL_VRAM && 809 if (src_tiled) {
805 nouveau_bo_tile_layout(nvbo)) {
806 ret = RING_SPACE(chan, 8);
807 if (ret)
808 return ret;
809
810 BEGIN_NV04(chan, NvSubCopy, 0x0200, 7); 810 BEGIN_NV04(chan, NvSubCopy, 0x0200, 7);
811 OUT_RING (chan, 0); 811 OUT_RING (chan, 0);
812 OUT_RING (chan, 0); 812 OUT_RING (chan, 0);
@@ -816,19 +816,10 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
816 OUT_RING (chan, 0); 816 OUT_RING (chan, 0);
817 OUT_RING (chan, 0); 817 OUT_RING (chan, 0);
818 } else { 818 } else {
819 ret = RING_SPACE(chan, 2);
820 if (ret)
821 return ret;
822
823 BEGIN_NV04(chan, NvSubCopy, 0x0200, 1); 819 BEGIN_NV04(chan, NvSubCopy, 0x0200, 1);
824 OUT_RING (chan, 1); 820 OUT_RING (chan, 1);
825 } 821 }
826 if (new_mem->mem_type == TTM_PL_VRAM && 822 if (dst_tiled) {
827 nouveau_bo_tile_layout(nvbo)) {
828 ret = RING_SPACE(chan, 8);
829 if (ret)
830 return ret;
831
832 BEGIN_NV04(chan, NvSubCopy, 0x021c, 7); 823 BEGIN_NV04(chan, NvSubCopy, 0x021c, 7);
833 OUT_RING (chan, 0); 824 OUT_RING (chan, 0);
834 OUT_RING (chan, 0); 825 OUT_RING (chan, 0);
@@ -838,18 +829,10 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
838 OUT_RING (chan, 0); 829 OUT_RING (chan, 0);
839 OUT_RING (chan, 0); 830 OUT_RING (chan, 0);
840 } else { 831 } else {
841 ret = RING_SPACE(chan, 2);
842 if (ret)
843 return ret;
844
845 BEGIN_NV04(chan, NvSubCopy, 0x021c, 1); 832 BEGIN_NV04(chan, NvSubCopy, 0x021c, 1);
846 OUT_RING (chan, 1); 833 OUT_RING (chan, 1);
847 } 834 }
848 835
849 ret = RING_SPACE(chan, 14);
850 if (ret)
851 return ret;
852
853 BEGIN_NV04(chan, NvSubCopy, 0x0238, 2); 836 BEGIN_NV04(chan, NvSubCopy, 0x0238, 2);
854 OUT_RING (chan, upper_32_bits(src_offset)); 837 OUT_RING (chan, upper_32_bits(src_offset));
855 OUT_RING (chan, upper_32_bits(dst_offset)); 838 OUT_RING (chan, upper_32_bits(dst_offset));