diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_bo.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bo.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 81599d6e636b..4435e115b929 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -89,12 +89,17 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags, | |||
89 | int | 89 | int |
90 | nouveau_bo_new(struct drm_device *dev, int size, int align, | 90 | nouveau_bo_new(struct drm_device *dev, int size, int align, |
91 | uint32_t flags, uint32_t tile_mode, uint32_t tile_flags, | 91 | uint32_t flags, uint32_t tile_mode, uint32_t tile_flags, |
92 | struct sg_table *sg, | ||
92 | struct nouveau_bo **pnvbo) | 93 | struct nouveau_bo **pnvbo) |
93 | { | 94 | { |
94 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 95 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
95 | struct nouveau_bo *nvbo; | 96 | struct nouveau_bo *nvbo; |
96 | size_t acc_size; | 97 | size_t acc_size; |
97 | int ret; | 98 | int ret; |
99 | int type = ttm_bo_type_device; | ||
100 | |||
101 | if (sg) | ||
102 | type = ttm_bo_type_sg; | ||
98 | 103 | ||
99 | nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); | 104 | nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); |
100 | if (!nvbo) | 105 | if (!nvbo) |
@@ -120,8 +125,8 @@ nouveau_bo_new(struct drm_device *dev, int size, int align, | |||
120 | sizeof(struct nouveau_bo)); | 125 | sizeof(struct nouveau_bo)); |
121 | 126 | ||
122 | ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, | 127 | ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, |
123 | ttm_bo_type_device, &nvbo->placement, | 128 | type, &nvbo->placement, |
124 | align >> PAGE_SHIFT, 0, false, NULL, acc_size, NULL, | 129 | align >> PAGE_SHIFT, 0, false, NULL, acc_size, sg, |
125 | nouveau_bo_del_ttm); | 130 | nouveau_bo_del_ttm); |
126 | if (ret) { | 131 | if (ret) { |
127 | /* ttm will call nouveau_bo_del_ttm if it fails.. */ | 132 | /* ttm will call nouveau_bo_del_ttm if it fails.. */ |
@@ -817,9 +822,14 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem) | |||
817 | } else | 822 | } else |
818 | if (new_mem && new_mem->mem_type == TTM_PL_TT && | 823 | if (new_mem && new_mem->mem_type == TTM_PL_TT && |
819 | nvbo->page_shift == vma->vm->spg_shift) { | 824 | nvbo->page_shift == vma->vm->spg_shift) { |
820 | nouveau_vm_map_sg(vma, 0, new_mem-> | 825 | if (((struct nouveau_mem *)new_mem->mm_node)->sg) |
821 | num_pages << PAGE_SHIFT, | 826 | nouveau_vm_map_sg_table(vma, 0, new_mem-> |
822 | new_mem->mm_node); | 827 | num_pages << PAGE_SHIFT, |
828 | new_mem->mm_node); | ||
829 | else | ||
830 | nouveau_vm_map_sg(vma, 0, new_mem-> | ||
831 | num_pages << PAGE_SHIFT, | ||
832 | new_mem->mm_node); | ||
823 | } else { | 833 | } else { |
824 | nouveau_vm_unmap(vma); | 834 | nouveau_vm_unmap(vma); |
825 | } | 835 | } |
@@ -1058,10 +1068,19 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) | |||
1058 | struct drm_device *dev; | 1068 | struct drm_device *dev; |
1059 | unsigned i; | 1069 | unsigned i; |
1060 | int r; | 1070 | int r; |
1071 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); | ||
1061 | 1072 | ||
1062 | if (ttm->state != tt_unpopulated) | 1073 | if (ttm->state != tt_unpopulated) |
1063 | return 0; | 1074 | return 0; |
1064 | 1075 | ||
1076 | if (slave && ttm->sg) { | ||
1077 | /* make userspace faulting work */ | ||
1078 | drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, | ||
1079 | ttm_dma->dma_address, ttm->num_pages); | ||
1080 | ttm->state = tt_unbound; | ||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1065 | dev_priv = nouveau_bdev(ttm->bdev); | 1084 | dev_priv = nouveau_bdev(ttm->bdev); |
1066 | dev = dev_priv->dev; | 1085 | dev = dev_priv->dev; |
1067 | 1086 | ||
@@ -1106,6 +1125,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) | |||
1106 | struct drm_nouveau_private *dev_priv; | 1125 | struct drm_nouveau_private *dev_priv; |
1107 | struct drm_device *dev; | 1126 | struct drm_device *dev; |
1108 | unsigned i; | 1127 | unsigned i; |
1128 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); | ||
1129 | |||
1130 | if (slave) | ||
1131 | return; | ||
1109 | 1132 | ||
1110 | dev_priv = nouveau_bdev(ttm->bdev); | 1133 | dev_priv = nouveau_bdev(ttm->bdev); |
1111 | dev = dev_priv->dev; | 1134 | dev = dev_priv->dev; |
@@ -1181,9 +1204,12 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm, | |||
1181 | 1204 | ||
1182 | if (nvbo->bo.mem.mem_type == TTM_PL_VRAM) | 1205 | if (nvbo->bo.mem.mem_type == TTM_PL_VRAM) |
1183 | nouveau_vm_map(vma, nvbo->bo.mem.mm_node); | 1206 | nouveau_vm_map(vma, nvbo->bo.mem.mm_node); |
1184 | else | 1207 | else if (nvbo->bo.mem.mem_type == TTM_PL_TT) { |
1185 | if (nvbo->bo.mem.mem_type == TTM_PL_TT) | 1208 | if (node->sg) |
1186 | nouveau_vm_map_sg(vma, 0, size, node); | 1209 | nouveau_vm_map_sg_table(vma, 0, size, node); |
1210 | else | ||
1211 | nouveau_vm_map_sg(vma, 0, size, node); | ||
1212 | } | ||
1187 | 1213 | ||
1188 | list_add_tail(&vma->head, &nvbo->vma_list); | 1214 | list_add_tail(&vma->head, &nvbo->vma_list); |
1189 | vma->refcount = 1; | 1215 | vma->refcount = 1; |