aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c48
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
38static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); 39static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
39static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); 40static 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 }