diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c0ae6bbbd9b..fd2b8bdffe3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -46,7 +46,6 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o | |||
46 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | 46 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); |
47 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 47 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, |
48 | unsigned alignment); | 48 | unsigned alignment); |
49 | static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write); | ||
50 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 49 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); |
51 | static int i915_gem_evict_something(struct drm_device *dev); | 50 | static int i915_gem_evict_something(struct drm_device *dev); |
52 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 51 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, |
@@ -1158,7 +1157,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1158 | /* Need a new fence register? */ | 1157 | /* Need a new fence register? */ |
1159 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && | 1158 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && |
1160 | obj_priv->tiling_mode != I915_TILING_NONE) { | 1159 | obj_priv->tiling_mode != I915_TILING_NONE) { |
1161 | ret = i915_gem_object_get_fence_reg(obj, write); | 1160 | ret = i915_gem_object_get_fence_reg(obj); |
1162 | if (ret) { | 1161 | if (ret) { |
1163 | mutex_unlock(&dev->struct_mutex); | 1162 | mutex_unlock(&dev->struct_mutex); |
1164 | return VM_FAULT_SIGBUS; | 1163 | return VM_FAULT_SIGBUS; |
@@ -1208,8 +1207,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) | |||
1208 | 1207 | ||
1209 | /* Set the object up for mmap'ing */ | 1208 | /* Set the object up for mmap'ing */ |
1210 | list = &obj->map_list; | 1209 | list = &obj->map_list; |
1211 | list->map = drm_calloc(1, sizeof(struct drm_map_list), | 1210 | list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); |
1212 | DRM_MEM_DRIVER); | ||
1213 | if (!list->map) | 1211 | if (!list->map) |
1214 | return -ENOMEM; | 1212 | return -ENOMEM; |
1215 | 1213 | ||
@@ -1249,7 +1247,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) | |||
1249 | out_free_mm: | 1247 | out_free_mm: |
1250 | drm_mm_put_block(list->file_offset_node); | 1248 | drm_mm_put_block(list->file_offset_node); |
1251 | out_free_list: | 1249 | out_free_list: |
1252 | drm_free(list->map, sizeof(struct drm_map_list), DRM_MEM_DRIVER); | 1250 | kfree(list->map); |
1253 | 1251 | ||
1254 | return ret; | 1252 | return ret; |
1255 | } | 1253 | } |
@@ -1271,7 +1269,7 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj) | |||
1271 | } | 1269 | } |
1272 | 1270 | ||
1273 | if (list->map) { | 1271 | if (list->map) { |
1274 | drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER); | 1272 | kfree(list->map); |
1275 | list->map = NULL; | 1273 | list->map = NULL; |
1276 | } | 1274 | } |
1277 | 1275 | ||
@@ -1494,7 +1492,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1494 | if (file_priv != NULL) | 1492 | if (file_priv != NULL) |
1495 | i915_file_priv = file_priv->driver_priv; | 1493 | i915_file_priv = file_priv->driver_priv; |
1496 | 1494 | ||
1497 | request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER); | 1495 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
1498 | if (request == NULL) | 1496 | if (request == NULL) |
1499 | return 0; | 1497 | return 0; |
1500 | 1498 | ||
@@ -1676,7 +1674,7 @@ i915_gem_retire_requests(struct drm_device *dev) | |||
1676 | 1674 | ||
1677 | list_del(&request->list); | 1675 | list_del(&request->list); |
1678 | list_del(&request->client_list); | 1676 | list_del(&request->client_list); |
1679 | drm_free(request, sizeof(*request), DRM_MEM_DRIVER); | 1677 | kfree(request); |
1680 | } else | 1678 | } else |
1681 | break; | 1679 | break; |
1682 | } | 1680 | } |
@@ -2163,13 +2161,11 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2163 | val |= I830_FENCE_REG_VALID; | 2161 | val |= I830_FENCE_REG_VALID; |
2164 | 2162 | ||
2165 | I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); | 2163 | I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); |
2166 | |||
2167 | } | 2164 | } |
2168 | 2165 | ||
2169 | /** | 2166 | /** |
2170 | * i915_gem_object_get_fence_reg - set up a fence reg for an object | 2167 | * i915_gem_object_get_fence_reg - set up a fence reg for an object |
2171 | * @obj: object to map through a fence reg | 2168 | * @obj: object to map through a fence reg |
2172 | * @write: object is about to be written | ||
2173 | * | 2169 | * |
2174 | * When mapping objects through the GTT, userspace wants to be able to write | 2170 | * When mapping objects through the GTT, userspace wants to be able to write |
2175 | * to them without having to worry about swizzling if the object is tiled. | 2171 | * to them without having to worry about swizzling if the object is tiled. |
@@ -2180,8 +2176,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2180 | * It then sets up the reg based on the object's properties: address, pitch | 2176 | * It then sets up the reg based on the object's properties: address, pitch |
2181 | * and tiling format. | 2177 | * and tiling format. |
2182 | */ | 2178 | */ |
2183 | static int | 2179 | int |
2184 | i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) | 2180 | i915_gem_object_get_fence_reg(struct drm_gem_object *obj) |
2185 | { | 2181 | { |
2186 | struct drm_device *dev = obj->dev; | 2182 | struct drm_device *dev = obj->dev; |
2187 | struct drm_i915_private *dev_priv = dev->dev_private; | 2183 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -2331,6 +2327,42 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2331 | } | 2327 | } |
2332 | 2328 | ||
2333 | /** | 2329 | /** |
2330 | * i915_gem_object_put_fence_reg - waits on outstanding fenced access | ||
2331 | * to the buffer to finish, and then resets the fence register. | ||
2332 | * @obj: tiled object holding a fence register. | ||
2333 | * | ||
2334 | * Zeroes out the fence register itself and clears out the associated | ||
2335 | * data structures in dev_priv and obj_priv. | ||
2336 | */ | ||
2337 | int | ||
2338 | i915_gem_object_put_fence_reg(struct drm_gem_object *obj) | ||
2339 | { | ||
2340 | struct drm_device *dev = obj->dev; | ||
2341 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
2342 | |||
2343 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE) | ||
2344 | return 0; | ||
2345 | |||
2346 | /* On the i915, GPU access to tiled buffers is via a fence, | ||
2347 | * therefore we must wait for any outstanding access to complete | ||
2348 | * before clearing the fence. | ||
2349 | */ | ||
2350 | if (!IS_I965G(dev)) { | ||
2351 | int ret; | ||
2352 | |||
2353 | i915_gem_object_flush_gpu_write_domain(obj); | ||
2354 | i915_gem_object_flush_gtt_write_domain(obj); | ||
2355 | ret = i915_gem_object_wait_rendering(obj); | ||
2356 | if (ret != 0) | ||
2357 | return ret; | ||
2358 | } | ||
2359 | |||
2360 | i915_gem_clear_fence_reg (obj); | ||
2361 | |||
2362 | return 0; | ||
2363 | } | ||
2364 | |||
2365 | /** | ||
2334 | * Finds free space in the GTT aperture and binds the object there. | 2366 | * Finds free space in the GTT aperture and binds the object there. |
2335 | */ | 2367 | */ |
2336 | static int | 2368 | static int |
@@ -2800,8 +2832,7 @@ i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) | |||
2800 | /* Free the page_cpu_valid mappings which are now stale, whether | 2832 | /* Free the page_cpu_valid mappings which are now stale, whether |
2801 | * or not we've got I915_GEM_DOMAIN_CPU. | 2833 | * or not we've got I915_GEM_DOMAIN_CPU. |
2802 | */ | 2834 | */ |
2803 | drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE, | 2835 | kfree(obj_priv->page_cpu_valid); |
2804 | DRM_MEM_DRIVER); | ||
2805 | obj_priv->page_cpu_valid = NULL; | 2836 | obj_priv->page_cpu_valid = NULL; |
2806 | } | 2837 | } |
2807 | 2838 | ||
@@ -2843,8 +2874,8 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | |||
2843 | * newly adding I915_GEM_DOMAIN_CPU | 2874 | * newly adding I915_GEM_DOMAIN_CPU |
2844 | */ | 2875 | */ |
2845 | if (obj_priv->page_cpu_valid == NULL) { | 2876 | if (obj_priv->page_cpu_valid == NULL) { |
2846 | obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, | 2877 | obj_priv->page_cpu_valid = kzalloc(obj->size / PAGE_SIZE, |
2847 | DRM_MEM_DRIVER); | 2878 | GFP_KERNEL); |
2848 | if (obj_priv->page_cpu_valid == NULL) | 2879 | if (obj_priv->page_cpu_valid == NULL) |
2849 | return -ENOMEM; | 2880 | return -ENOMEM; |
2850 | } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) | 2881 | } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) |
@@ -3267,8 +3298,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
3267 | } | 3298 | } |
3268 | 3299 | ||
3269 | if (args->num_cliprects != 0) { | 3300 | if (args->num_cliprects != 0) { |
3270 | cliprects = drm_calloc(args->num_cliprects, sizeof(*cliprects), | 3301 | cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), |
3271 | DRM_MEM_DRIVER); | 3302 | GFP_KERNEL); |
3272 | if (cliprects == NULL) | 3303 | if (cliprects == NULL) |
3273 | goto pre_mutex_err; | 3304 | goto pre_mutex_err; |
3274 | 3305 | ||
@@ -3521,8 +3552,7 @@ err: | |||
3521 | pre_mutex_err: | 3552 | pre_mutex_err: |
3522 | drm_free_large(object_list); | 3553 | drm_free_large(object_list); |
3523 | drm_free_large(exec_list); | 3554 | drm_free_large(exec_list); |
3524 | drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects, | 3555 | kfree(cliprects); |
3525 | DRM_MEM_DRIVER); | ||
3526 | 3556 | ||
3527 | return ret; | 3557 | return ret; |
3528 | } | 3558 | } |
@@ -3550,7 +3580,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
3550 | if (!IS_I965G(dev) && | 3580 | if (!IS_I965G(dev) && |
3551 | obj_priv->fence_reg == I915_FENCE_REG_NONE && | 3581 | obj_priv->fence_reg == I915_FENCE_REG_NONE && |
3552 | obj_priv->tiling_mode != I915_TILING_NONE) { | 3582 | obj_priv->tiling_mode != I915_TILING_NONE) { |
3553 | ret = i915_gem_object_get_fence_reg(obj, true); | 3583 | ret = i915_gem_object_get_fence_reg(obj); |
3554 | if (ret != 0) { | 3584 | if (ret != 0) { |
3555 | if (ret != -EBUSY && ret != -ERESTARTSYS) | 3585 | if (ret != -EBUSY && ret != -ERESTARTSYS) |
3556 | DRM_ERROR("Failure to install fence: %d\n", | 3586 | DRM_ERROR("Failure to install fence: %d\n", |
@@ -3739,7 +3769,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
3739 | { | 3769 | { |
3740 | struct drm_i915_gem_object *obj_priv; | 3770 | struct drm_i915_gem_object *obj_priv; |
3741 | 3771 | ||
3742 | obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER); | 3772 | obj_priv = kzalloc(sizeof(*obj_priv), GFP_KERNEL); |
3743 | if (obj_priv == NULL) | 3773 | if (obj_priv == NULL) |
3744 | return -ENOMEM; | 3774 | return -ENOMEM; |
3745 | 3775 | ||
@@ -3777,9 +3807,9 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
3777 | 3807 | ||
3778 | i915_gem_free_mmap_offset(obj); | 3808 | i915_gem_free_mmap_offset(obj); |
3779 | 3809 | ||
3780 | drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); | 3810 | kfree(obj_priv->page_cpu_valid); |
3781 | kfree(obj_priv->bit_17); | 3811 | kfree(obj_priv->bit_17); |
3782 | drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); | 3812 | kfree(obj->driver_private); |
3783 | } | 3813 | } |
3784 | 3814 | ||
3785 | /** Unbinds all objects that are on the given buffer list. */ | 3815 | /** Unbinds all objects that are on the given buffer list. */ |
@@ -4233,7 +4263,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
4233 | if (dev_priv->mm.phys_objs[id - 1] || !size) | 4263 | if (dev_priv->mm.phys_objs[id - 1] || !size) |
4234 | return 0; | 4264 | return 0; |
4235 | 4265 | ||
4236 | phys_obj = drm_calloc(1, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); | 4266 | phys_obj = kzalloc(sizeof(struct drm_i915_gem_phys_object), GFP_KERNEL); |
4237 | if (!phys_obj) | 4267 | if (!phys_obj) |
4238 | return -ENOMEM; | 4268 | return -ENOMEM; |
4239 | 4269 | ||
@@ -4252,7 +4282,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
4252 | 4282 | ||
4253 | return 0; | 4283 | return 0; |
4254 | kfree_obj: | 4284 | kfree_obj: |
4255 | drm_free(phys_obj, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); | 4285 | kfree(phys_obj); |
4256 | return ret; | 4286 | return ret; |
4257 | } | 4287 | } |
4258 | 4288 | ||
@@ -4312,6 +4342,8 @@ void i915_gem_detach_phys_object(struct drm_device *dev, | |||
4312 | } | 4342 | } |
4313 | drm_clflush_pages(obj_priv->pages, page_count); | 4343 | drm_clflush_pages(obj_priv->pages, page_count); |
4314 | drm_agp_chipset_flush(dev); | 4344 | drm_agp_chipset_flush(dev); |
4345 | |||
4346 | i915_gem_object_put_pages(obj); | ||
4315 | out: | 4347 | out: |
4316 | obj_priv->phys_obj->cur_obj = NULL; | 4348 | obj_priv->phys_obj->cur_obj = NULL; |
4317 | obj_priv->phys_obj = NULL; | 4349 | obj_priv->phys_obj = NULL; |
@@ -4369,6 +4401,8 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
4369 | kunmap_atomic(src, KM_USER0); | 4401 | kunmap_atomic(src, KM_USER0); |
4370 | } | 4402 | } |
4371 | 4403 | ||
4404 | i915_gem_object_put_pages(obj); | ||
4405 | |||
4372 | return 0; | 4406 | return 0; |
4373 | out: | 4407 | out: |
4374 | return ret; | 4408 | return ret; |