diff options
| author | Maarten Lankhorst <maarten.lankhorst@canonical.com> | 2013-11-12 07:34:08 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-13 16:48:03 -0500 |
| commit | c3c43400a29dba30a581c97a6eb6952d187c3e07 (patch) | |
| tree | 5a65e01f2ec18957e0f7db120ea6e88aefbf4377 /drivers/gpu | |
| parent | 4f66403630544a1e5ad3b041fe0dba9db16ff6d9 (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.c | 33 |
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)); |
