aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ttm/ttm_bo.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-12-10 11:16:27 -0500
committerDave Airlie <airlied@redhat.com>2009-12-10 23:09:05 -0500
commit09855acb1c2e3779f25317ec9a8ffe1b1784a4a8 (patch)
tree4a96a67c6bc9694036a95aafd4004c9e9b89eadc /drivers/gpu/drm/ttm/ttm_bo.c
parent4361e52ad0372e6fd2240a2207b49a4de1f45ca9 (diff)
drm/ttm: Convert ttm_buffer_object_init to use ttm_placement
Convert ttm_buffer_object_init to use struct ttm_placement and rename to ttm_bo_init for consistency with function naming. This allow to give more complex placement at buffer creation. For instance you ask to allocate bo into vram first but if there is not enough vram you can give system as a second possible placement. It also allow to create buffer in a specific range. Also rename ttm_buffer_object_validate to ttm_bo_validate. Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo.c')
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c130
1 files changed, 57 insertions, 73 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index a835b6fe42a1..fae5c158351c 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1002,9 +1002,9 @@ static int ttm_bo_mem_compat(struct ttm_placement *placement,
1002 return -1; 1002 return -1;
1003} 1003}
1004 1004
1005int ttm_buffer_object_validate(struct ttm_buffer_object *bo, 1005int ttm_bo_validate(struct ttm_buffer_object *bo,
1006 struct ttm_placement *placement, 1006 struct ttm_placement *placement,
1007 bool interruptible, bool no_wait) 1007 bool interruptible, bool no_wait)
1008{ 1008{
1009 int ret; 1009 int ret;
1010 1010
@@ -1040,55 +1040,57 @@ int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
1040 } 1040 }
1041 return 0; 1041 return 0;
1042} 1042}
1043EXPORT_SYMBOL(ttm_buffer_object_validate); 1043EXPORT_SYMBOL(ttm_bo_validate);
1044 1044
1045int 1045int ttm_bo_check_placement(struct ttm_buffer_object *bo,
1046ttm_bo_check_placement(struct ttm_buffer_object *bo, 1046 struct ttm_placement *placement)
1047 uint32_t set_flags, uint32_t clr_flags)
1048{ 1047{
1049 uint32_t new_mask = set_flags | clr_flags; 1048 int i;
1050
1051 if ((bo->type == ttm_bo_type_user) &&
1052 (clr_flags & TTM_PL_FLAG_CACHED)) {
1053 printk(KERN_ERR TTM_PFX
1054 "User buffers require cache-coherent memory.\n");
1055 return -EINVAL;
1056 }
1057 1049
1058 if (!capable(CAP_SYS_ADMIN)) { 1050 if (placement->fpfn || placement->lpfn) {
1059 if (new_mask & TTM_PL_FLAG_NO_EVICT) { 1051 if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) {
1060 printk(KERN_ERR TTM_PFX "Need to be root to modify" 1052 printk(KERN_ERR TTM_PFX "Page number range to small "
1061 " NO_EVICT status.\n"); 1053 "Need %lu pages, range is [%u, %u]\n",
1054 bo->mem.num_pages, placement->fpfn,
1055 placement->lpfn);
1062 return -EINVAL; 1056 return -EINVAL;
1063 } 1057 }
1064 1058 }
1065 if ((clr_flags & bo->mem.placement & TTM_PL_MASK_MEMTYPE) && 1059 for (i = 0; i < placement->num_placement; i++) {
1066 (bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { 1060 if (!capable(CAP_SYS_ADMIN)) {
1067 printk(KERN_ERR TTM_PFX 1061 if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) {
1068 "Incompatible memory specification" 1062 printk(KERN_ERR TTM_PFX "Need to be root to "
1069 " for NO_EVICT buffer.\n"); 1063 "modify NO_EVICT status.\n");
1070 return -EINVAL; 1064 return -EINVAL;
1065 }
1066 }
1067 }
1068 for (i = 0; i < placement->num_busy_placement; i++) {
1069 if (!capable(CAP_SYS_ADMIN)) {
1070 if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) {
1071 printk(KERN_ERR TTM_PFX "Need to be root to "
1072 "modify NO_EVICT status.\n");
1073 return -EINVAL;
1074 }
1071 } 1075 }
1072 } 1076 }
1073 return 0; 1077 return 0;
1074} 1078}
1075 1079
1076int ttm_buffer_object_init(struct ttm_bo_device *bdev, 1080int ttm_bo_init(struct ttm_bo_device *bdev,
1077 struct ttm_buffer_object *bo, 1081 struct ttm_buffer_object *bo,
1078 unsigned long size, 1082 unsigned long size,
1079 enum ttm_bo_type type, 1083 enum ttm_bo_type type,
1080 uint32_t flags, 1084 struct ttm_placement *placement,
1081 uint32_t page_alignment, 1085 uint32_t page_alignment,
1082 unsigned long buffer_start, 1086 unsigned long buffer_start,
1083 bool interruptible, 1087 bool interruptible,
1084 struct file *persistant_swap_storage, 1088 struct file *persistant_swap_storage,
1085 size_t acc_size, 1089 size_t acc_size,
1086 void (*destroy) (struct ttm_buffer_object *)) 1090 void (*destroy) (struct ttm_buffer_object *))
1087{ 1091{
1088 int i, c, ret = 0; 1092 int ret = 0;
1089 unsigned long num_pages; 1093 unsigned long num_pages;
1090 uint32_t placements[8];
1091 struct ttm_placement placement;
1092 1094
1093 size += buffer_start & ~PAGE_MASK; 1095 size += buffer_start & ~PAGE_MASK;
1094 num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 1096 num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -1123,38 +1125,21 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev,
1123 bo->acc_size = acc_size; 1125 bo->acc_size = acc_size;
1124 atomic_inc(&bo->glob->bo_count); 1126 atomic_inc(&bo->glob->bo_count);
1125 1127
1126 ret = ttm_bo_check_placement(bo, flags, 0ULL); 1128 ret = ttm_bo_check_placement(bo, placement);
1127 if (unlikely(ret != 0)) 1129 if (unlikely(ret != 0))
1128 goto out_err; 1130 goto out_err;
1129 1131
1130 /* 1132 /*
1131 * If no caching attributes are set, accept any form of caching.
1132 */
1133
1134 if ((flags & TTM_PL_MASK_CACHING) == 0)
1135 flags |= TTM_PL_MASK_CACHING;
1136
1137 /*
1138 * For ttm_bo_type_device buffers, allocate 1133 * For ttm_bo_type_device buffers, allocate
1139 * address space from the device. 1134 * address space from the device.
1140 */ 1135 */
1141
1142 if (bo->type == ttm_bo_type_device) { 1136 if (bo->type == ttm_bo_type_device) {
1143 ret = ttm_bo_setup_vm(bo); 1137 ret = ttm_bo_setup_vm(bo);
1144 if (ret) 1138 if (ret)
1145 goto out_err; 1139 goto out_err;
1146 } 1140 }
1147 1141
1148 placement.fpfn = 0; 1142 ret = ttm_bo_validate(bo, placement, interruptible, false);
1149 placement.lpfn = 0;
1150 for (i = 0, c = 0; i <= TTM_PL_PRIV5; i++)
1151 if (flags & (1 << i))
1152 placements[c++] = (flags & ~TTM_PL_MASK_MEM) | (1 << i);
1153 placement.placement = placements;
1154 placement.num_placement = c;
1155 placement.busy_placement = placements;
1156 placement.num_busy_placement = c;
1157 ret = ttm_buffer_object_validate(bo, &placement, interruptible, false);
1158 if (ret) 1143 if (ret)
1159 goto out_err; 1144 goto out_err;
1160 1145
@@ -1167,7 +1152,7 @@ out_err:
1167 1152
1168 return ret; 1153 return ret;
1169} 1154}
1170EXPORT_SYMBOL(ttm_buffer_object_init); 1155EXPORT_SYMBOL(ttm_bo_init);
1171 1156
1172static inline size_t ttm_bo_size(struct ttm_bo_global *glob, 1157static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
1173 unsigned long num_pages) 1158 unsigned long num_pages)
@@ -1178,15 +1163,15 @@ static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
1178 return glob->ttm_bo_size + 2 * page_array_size; 1163 return glob->ttm_bo_size + 2 * page_array_size;
1179} 1164}
1180 1165
1181int ttm_buffer_object_create(struct ttm_bo_device *bdev, 1166int ttm_bo_create(struct ttm_bo_device *bdev,
1182 unsigned long size, 1167 unsigned long size,
1183 enum ttm_bo_type type, 1168 enum ttm_bo_type type,
1184 uint32_t flags, 1169 struct ttm_placement *placement,
1185 uint32_t page_alignment, 1170 uint32_t page_alignment,
1186 unsigned long buffer_start, 1171 unsigned long buffer_start,
1187 bool interruptible, 1172 bool interruptible,
1188 struct file *persistant_swap_storage, 1173 struct file *persistant_swap_storage,
1189 struct ttm_buffer_object **p_bo) 1174 struct ttm_buffer_object **p_bo)
1190{ 1175{
1191 struct ttm_buffer_object *bo; 1176 struct ttm_buffer_object *bo;
1192 struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; 1177 struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
@@ -1205,10 +1190,9 @@ int ttm_buffer_object_create(struct ttm_bo_device *bdev,
1205 return -ENOMEM; 1190 return -ENOMEM;
1206 } 1191 }
1207 1192
1208 ret = ttm_buffer_object_init(bdev, bo, size, type, flags, 1193 ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
1209 page_alignment, buffer_start, 1194 buffer_start, interruptible,
1210 interruptible, 1195 persistant_swap_storage, acc_size, NULL);
1211 persistant_swap_storage, acc_size, NULL);
1212 if (likely(ret == 0)) 1196 if (likely(ret == 0))
1213 *p_bo = bo; 1197 *p_bo = bo;
1214 1198