diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index df5a7135c261..bced9b25c71e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/intel-gtt.h> | ||
37 | 38 | ||
38 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | 39 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); |
39 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 40 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
@@ -135,12 +136,15 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
135 | return -ENOMEM; | 136 | return -ENOMEM; |
136 | 137 | ||
137 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 138 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
138 | drm_gem_object_unreference_unlocked(obj); | 139 | if (ret) { |
139 | if (ret) | 140 | drm_gem_object_unreference_unlocked(obj); |
140 | return ret; | 141 | return ret; |
142 | } | ||
141 | 143 | ||
142 | args->handle = handle; | 144 | /* Sink the floating reference from kref_init(handlecount) */ |
145 | drm_gem_object_handle_unreference_unlocked(obj); | ||
143 | 146 | ||
147 | args->handle = handle; | ||
144 | return 0; | 148 | return 0; |
145 | } | 149 | } |
146 | 150 | ||
@@ -2347,14 +2351,21 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2347 | 2351 | ||
2348 | reg->obj = obj; | 2352 | reg->obj = obj; |
2349 | 2353 | ||
2350 | if (IS_GEN6(dev)) | 2354 | switch (INTEL_INFO(dev)->gen) { |
2355 | case 6: | ||
2351 | sandybridge_write_fence_reg(reg); | 2356 | sandybridge_write_fence_reg(reg); |
2352 | else if (IS_I965G(dev)) | 2357 | break; |
2358 | case 5: | ||
2359 | case 4: | ||
2353 | i965_write_fence_reg(reg); | 2360 | i965_write_fence_reg(reg); |
2354 | else if (IS_I9XX(dev)) | 2361 | break; |
2362 | case 3: | ||
2355 | i915_write_fence_reg(reg); | 2363 | i915_write_fence_reg(reg); |
2356 | else | 2364 | break; |
2365 | case 2: | ||
2357 | i830_write_fence_reg(reg); | 2366 | i830_write_fence_reg(reg); |
2367 | break; | ||
2368 | } | ||
2358 | 2369 | ||
2359 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, | 2370 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, |
2360 | obj_priv->tiling_mode); | 2371 | obj_priv->tiling_mode); |
@@ -2377,22 +2388,26 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2377 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2388 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2378 | struct drm_i915_fence_reg *reg = | 2389 | struct drm_i915_fence_reg *reg = |
2379 | &dev_priv->fence_regs[obj_priv->fence_reg]; | 2390 | &dev_priv->fence_regs[obj_priv->fence_reg]; |
2391 | uint32_t fence_reg; | ||
2380 | 2392 | ||
2381 | if (IS_GEN6(dev)) { | 2393 | switch (INTEL_INFO(dev)->gen) { |
2394 | case 6: | ||
2382 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + | 2395 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + |
2383 | (obj_priv->fence_reg * 8), 0); | 2396 | (obj_priv->fence_reg * 8), 0); |
2384 | } else if (IS_I965G(dev)) { | 2397 | break; |
2398 | case 5: | ||
2399 | case 4: | ||
2385 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); | 2400 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); |
2386 | } else { | 2401 | break; |
2387 | uint32_t fence_reg; | 2402 | case 3: |
2388 | 2403 | if (obj_priv->fence_reg >= 8) | |
2389 | if (obj_priv->fence_reg < 8) | 2404 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4; |
2390 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; | ||
2391 | else | 2405 | else |
2392 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - | 2406 | case 2: |
2393 | 8) * 4; | 2407 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; |
2394 | 2408 | ||
2395 | I915_WRITE(fence_reg, 0); | 2409 | I915_WRITE(fence_reg, 0); |
2410 | break; | ||
2396 | } | 2411 | } |
2397 | 2412 | ||
2398 | reg->obj = NULL; | 2413 | reg->obj = NULL; |
@@ -3585,6 +3600,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3585 | if (ret != 0) { | 3600 | if (ret != 0) { |
3586 | DRM_ERROR("copy %d cliprects failed: %d\n", | 3601 | DRM_ERROR("copy %d cliprects failed: %d\n", |
3587 | args->num_cliprects, ret); | 3602 | args->num_cliprects, ret); |
3603 | ret = -EFAULT; | ||
3588 | goto pre_mutex_err; | 3604 | goto pre_mutex_err; |
3589 | } | 3605 | } |
3590 | } | 3606 | } |