aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-09-24 16:15:47 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-29 06:15:07 -0400
commita00b10c360b35d6431a94cbf130a4e162870d661 (patch)
treee1c06b90d161bc81e8d2c819da3b676f75527dda
parent7465378fd7c681f6cf2b74b3494c4f0991d8c8ac (diff)
drm/i915: Only enforce fence limits inside the GTT.
So long as we adhere to the fence registers rules for alignment and no overlaps (including with unfenced accesses to linear memory) and account for the tiled access in our size allocation, we do not have to allocate the full fenced region for the object. This allows us to fight the bloat tiling imposed on pre-i965 chipsets and frees up RAM for real use. [Inside the GTT we still suffer the additional alignment constraints, so it doesn't magic allow us to render larger scenes without stalls -- we need the expanded GTT and fence pipelining to overcome those...] Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c3
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h8
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c290
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c32
-rw-r--r--drivers/gpu/drm/i915/intel_display.c7
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c4
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c4
-rw-r--r--include/drm/i915_drm.h1
9 files changed, 197 insertions, 155 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 4fc1e05b769f..ba2af4e046ed 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -130,7 +130,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
130 if (obj->fence_reg != I915_FENCE_REG_NONE) 130 if (obj->fence_reg != I915_FENCE_REG_NONE)
131 seq_printf(m, " (fence: %d)", obj->fence_reg); 131 seq_printf(m, " (fence: %d)", obj->fence_reg);
132 if (obj->gtt_space != NULL) 132 if (obj->gtt_space != NULL)
133 seq_printf(m, " (gtt_offset: %08x)", obj->gtt_offset); 133 seq_printf(m, " (gtt offset: %08x, size: %08x)",
134 obj->gtt_offset, (unsigned int)obj->gtt_space->size);
134 if (obj->pin_mappable || obj->fault_mappable) 135 if (obj->pin_mappable || obj->fault_mappable)
135 seq_printf(m, " (mappable)"); 136 seq_printf(m, " (mappable)");
136 if (obj->ring != NULL) 137 if (obj->ring != NULL)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index dddca007912a..00d8fb3e989f 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -770,6 +770,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
770 case I915_PARAM_HAS_BLT: 770 case I915_PARAM_HAS_BLT:
771 value = HAS_BLT(dev); 771 value = HAS_BLT(dev);
772 break; 772 break;
773 case I915_PARAM_HAS_RELAXED_FENCING:
774 value = 1;
775 break;
773 default: 776 default:
774 DRM_DEBUG_DRIVER("Unknown parameter %d\n", 777 DRM_DEBUG_DRIVER("Unknown parameter %d\n",
775 param->param); 778 param->param);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3df8a624ddc9..7aa7f8abf892 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -746,6 +746,8 @@ struct drm_i915_gem_object {
746 * Advice: are the backing pages purgeable? 746 * Advice: are the backing pages purgeable?
747 */ 747 */
748 unsigned int madv : 2; 748 unsigned int madv : 2;
749 unsigned int fenceable : 1;
750 unsigned int mappable : 1;
749 751
750 /** 752 /**
751 * Current tiling mode for the object. 753 * Current tiling mode for the object.
@@ -1005,7 +1007,7 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev,
1005 size_t size); 1007 size_t size);
1006void i915_gem_free_object(struct drm_gem_object *obj); 1008void i915_gem_free_object(struct drm_gem_object *obj);
1007int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, 1009int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment,
1008 bool mappable); 1010 bool mappable, bool need_fence);
1009void i915_gem_object_unpin(struct drm_gem_object *obj); 1011void i915_gem_object_unpin(struct drm_gem_object *obj);
1010int i915_gem_object_unbind(struct drm_gem_object *obj); 1012int i915_gem_object_unbind(struct drm_gem_object *obj);
1011void i915_gem_release_mmap(struct drm_gem_object *obj); 1013void i915_gem_release_mmap(struct drm_gem_object *obj);
@@ -1068,10 +1070,6 @@ int i915_gem_evict_inactive(struct drm_device *dev);
1068void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); 1070void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
1069void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); 1071void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj);
1070void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj); 1072void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj);
1071bool i915_tiling_ok(struct drm_device *dev, int stride, int size,
1072 int tiling_mode);
1073bool i915_gem_object_fence_offset_ok(struct drm_gem_object *obj,
1074 int tiling_mode);
1075 1073
1076/* i915_gem_debug.c */ 1074/* i915_gem_debug.c */
1077void i915_gem_dump_object(struct drm_gem_object *obj, int len, 1075void i915_gem_dump_object(struct drm_gem_object *obj, int len,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 08f57aedaf51..07ad1e354084 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -36,7 +36,8 @@
36#include <linux/pci.h> 36#include <linux/pci.h>
37#include <linux/intel-gtt.h> 37#include <linux/intel-gtt.h>
38 38
39static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); 39static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv);
40static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv);
40 41
41static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, 42static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
42 bool pipelined); 43 bool pipelined);
@@ -51,7 +52,9 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o
51static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, 52static int i915_gem_object_wait_rendering(struct drm_gem_object *obj,
52 bool interruptible); 53 bool interruptible);
53static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, 54static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
54 unsigned alignment, bool mappable); 55 unsigned alignment,
56 bool mappable,
57 bool need_fence);
55static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 58static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
56static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, 59static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
57 struct drm_i915_gem_pwrite *args, 60 struct drm_i915_gem_pwrite *args,
@@ -79,30 +82,26 @@ static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv,
79} 82}
80 83
81static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, 84static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv,
82 struct drm_gem_object *obj) 85 struct drm_i915_gem_object *obj)
83{ 86{
84 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
85 dev_priv->mm.gtt_count++; 87 dev_priv->mm.gtt_count++;
86 dev_priv->mm.gtt_memory += obj->size; 88 dev_priv->mm.gtt_memory += obj->gtt_space->size;
87 if (obj_priv->gtt_offset < dev_priv->mm.gtt_mappable_end) { 89 if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) {
88 dev_priv->mm.mappable_gtt_used += 90 dev_priv->mm.mappable_gtt_used +=
89 min_t(size_t, obj->size, 91 min_t(size_t, obj->gtt_space->size,
90 dev_priv->mm.gtt_mappable_end 92 dev_priv->mm.gtt_mappable_end - obj->gtt_offset);
91 - obj_priv->gtt_offset);
92 } 93 }
93} 94}
94 95
95static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, 96static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv,
96 struct drm_gem_object *obj) 97 struct drm_i915_gem_object *obj)
97{ 98{
98 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
99 dev_priv->mm.gtt_count--; 99 dev_priv->mm.gtt_count--;
100 dev_priv->mm.gtt_memory -= obj->size; 100 dev_priv->mm.gtt_memory -= obj->gtt_space->size;
101 if (obj_priv->gtt_offset < dev_priv->mm.gtt_mappable_end) { 101 if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) {
102 dev_priv->mm.mappable_gtt_used -= 102 dev_priv->mm.mappable_gtt_used -=
103 min_t(size_t, obj->size, 103 min_t(size_t, obj->gtt_space->size,
104 dev_priv->mm.gtt_mappable_end 104 dev_priv->mm.gtt_mappable_end - obj->gtt_offset);
105 - obj_priv->gtt_offset);
106 } 105 }
107} 106}
108 107
@@ -113,47 +112,43 @@ static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv,
113 */ 112 */
114static void 113static void
115i915_gem_info_update_mappable(struct drm_i915_private *dev_priv, 114i915_gem_info_update_mappable(struct drm_i915_private *dev_priv,
116 struct drm_gem_object *obj, 115 struct drm_i915_gem_object *obj,
117 bool mappable) 116 bool mappable)
118{ 117{
119 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
120
121 if (mappable) { 118 if (mappable) {
122 if (obj_priv->pin_mappable && obj_priv->fault_mappable) 119 if (obj->pin_mappable && obj->fault_mappable)
123 /* Combined state was already mappable. */ 120 /* Combined state was already mappable. */
124 return; 121 return;
125 dev_priv->mm.gtt_mappable_count++; 122 dev_priv->mm.gtt_mappable_count++;
126 dev_priv->mm.gtt_mappable_memory += obj->size; 123 dev_priv->mm.gtt_mappable_memory += obj->gtt_space->size;
127 } else { 124 } else {
128 if (obj_priv->pin_mappable || obj_priv->fault_mappable) 125 if (obj->pin_mappable || obj->fault_mappable)
129 /* Combined state still mappable. */ 126 /* Combined state still mappable. */
130 return; 127 return;
131 dev_priv->mm.gtt_mappable_count--; 128 dev_priv->mm.gtt_mappable_count--;
132 dev_priv->mm.gtt_mappable_memory -= obj->size; 129 dev_priv->mm.gtt_mappable_memory -= obj->gtt_space->size;
133 } 130 }
134} 131}
135 132
136static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv, 133static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv,
137 struct drm_gem_object *obj, 134 struct drm_i915_gem_object *obj,
138 bool mappable) 135 bool mappable)
139{ 136{
140 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
141 dev_priv->mm.pin_count++; 137 dev_priv->mm.pin_count++;
142 dev_priv->mm.pin_memory += obj->size; 138 dev_priv->mm.pin_memory += obj->gtt_space->size;
143 if (mappable) { 139 if (mappable) {
144 obj_priv->pin_mappable = true; 140 obj->pin_mappable = true;
145 i915_gem_info_update_mappable(dev_priv, obj, true); 141 i915_gem_info_update_mappable(dev_priv, obj, true);
146 } 142 }
147} 143}
148 144
149static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv, 145static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv,
150 struct drm_gem_object *obj) 146 struct drm_i915_gem_object *obj)
151{ 147{
152 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
153 dev_priv->mm.pin_count--; 148 dev_priv->mm.pin_count--;
154 dev_priv->mm.pin_memory -= obj->size; 149 dev_priv->mm.pin_memory -= obj->gtt_space->size;
155 if (obj_priv->pin_mappable) { 150 if (obj->pin_mappable) {
156 obj_priv->pin_mappable = false; 151 obj->pin_mappable = false;
157 i915_gem_info_update_mappable(dev_priv, obj, false); 152 i915_gem_info_update_mappable(dev_priv, obj, false);
158 } 153 }
159} 154}
@@ -309,16 +304,6 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
309 return 0; 304 return 0;
310} 305}
311 306
312static bool
313i915_gem_object_cpu_accessible(struct drm_i915_gem_object *obj)
314{
315 struct drm_device *dev = obj->base.dev;
316 drm_i915_private_t *dev_priv = dev->dev_private;
317
318 return obj->gtt_space == NULL ||
319 obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end;
320}
321
322static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) 307static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
323{ 308{
324 drm_i915_private_t *dev_priv = obj->dev->dev_private; 309 drm_i915_private_t *dev_priv = obj->dev->dev_private;
@@ -1083,7 +1068,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1083 else if (obj_priv->tiling_mode == I915_TILING_NONE && 1068 else if (obj_priv->tiling_mode == I915_TILING_NONE &&
1084 obj_priv->gtt_space && 1069 obj_priv->gtt_space &&
1085 obj->write_domain != I915_GEM_DOMAIN_CPU) { 1070 obj->write_domain != I915_GEM_DOMAIN_CPU) {
1086 ret = i915_gem_object_pin(obj, 0, true); 1071 ret = i915_gem_object_pin(obj, 0, true, false);
1087 if (ret) 1072 if (ret)
1088 goto out; 1073 goto out;
1089 1074
@@ -1307,11 +1292,19 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1307 /* Now bind it into the GTT if needed */ 1292 /* Now bind it into the GTT if needed */
1308 mutex_lock(&dev->struct_mutex); 1293 mutex_lock(&dev->struct_mutex);
1309 BUG_ON(obj_priv->pin_count && !obj_priv->pin_mappable); 1294 BUG_ON(obj_priv->pin_count && !obj_priv->pin_mappable);
1310 if (!i915_gem_object_cpu_accessible(obj_priv)) 1295
1311 i915_gem_object_unbind(obj); 1296 if (obj_priv->gtt_space) {
1297 if (!obj_priv->mappable ||
1298 (obj_priv->tiling_mode && !obj_priv->fenceable)) {
1299 ret = i915_gem_object_unbind(obj);
1300 if (ret)
1301 goto unlock;
1302 }
1303 }
1312 1304
1313 if (!obj_priv->gtt_space) { 1305 if (!obj_priv->gtt_space) {
1314 ret = i915_gem_object_bind_to_gtt(obj, 0, true); 1306 ret = i915_gem_object_bind_to_gtt(obj, 0,
1307 true, obj_priv->tiling_mode);
1315 if (ret) 1308 if (ret)
1316 goto unlock; 1309 goto unlock;
1317 } 1310 }
@@ -1322,7 +1315,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1322 1315
1323 if (!obj_priv->fault_mappable) { 1316 if (!obj_priv->fault_mappable) {
1324 obj_priv->fault_mappable = true; 1317 obj_priv->fault_mappable = true;
1325 i915_gem_info_update_mappable(dev_priv, obj, true); 1318 i915_gem_info_update_mappable(dev_priv, obj_priv, true);
1326 } 1319 }
1327 1320
1328 /* Need a new fence register? */ 1321 /* Need a new fence register? */
@@ -1448,7 +1441,7 @@ i915_gem_release_mmap(struct drm_gem_object *obj)
1448 1441
1449 if (obj_priv->fault_mappable) { 1442 if (obj_priv->fault_mappable) {
1450 obj_priv->fault_mappable = false; 1443 obj_priv->fault_mappable = false;
1451 i915_gem_info_update_mappable(dev_priv, obj, false); 1444 i915_gem_info_update_mappable(dev_priv, obj_priv, false);
1452 } 1445 }
1453} 1446}
1454 1447
@@ -1473,32 +1466,51 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj)
1473 * potential fence register mapping if needed. 1466 * potential fence register mapping if needed.
1474 */ 1467 */
1475static uint32_t 1468static uint32_t
1476i915_gem_get_gtt_alignment(struct drm_gem_object *obj) 1469i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv)
1477{ 1470{
1478 struct drm_device *dev = obj->dev; 1471 struct drm_device *dev = obj_priv->base.dev;
1479 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
1480 int start, i;
1481 1472
1482 /* 1473 /*
1483 * Minimum alignment is 4k (GTT page size), but might be greater 1474 * Minimum alignment is 4k (GTT page size), but might be greater
1484 * if a fence register is needed for the object. 1475 * if a fence register is needed for the object.
1485 */ 1476 */
1486 if (INTEL_INFO(dev)->gen >= 4 || obj_priv->tiling_mode == I915_TILING_NONE) 1477 if (INTEL_INFO(dev)->gen >= 4 ||
1478 obj_priv->tiling_mode == I915_TILING_NONE)
1487 return 4096; 1479 return 4096;
1488 1480
1489 /* 1481 /*
1490 * Previous chips need to be aligned to the size of the smallest 1482 * Previous chips need to be aligned to the size of the smallest
1491 * fence register that can contain the object. 1483 * fence register that can contain the object.
1492 */ 1484 */
1485 return i915_gem_get_gtt_size(obj_priv);
1486}
1487
1488static uint32_t
1489i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv)
1490{
1491 struct drm_device *dev = obj_priv->base.dev;
1492 uint32_t size;
1493
1494 /*
1495 * Minimum alignment is 4k (GTT page size), but might be greater
1496 * if a fence register is needed for the object.
1497 */
1498 if (INTEL_INFO(dev)->gen >= 4)
1499 return obj_priv->base.size;
1500
1501 /*
1502 * Previous chips need to be aligned to the size of the smallest
1503 * fence register that can contain the object.
1504 */
1493 if (INTEL_INFO(dev)->gen == 3) 1505 if (INTEL_INFO(dev)->gen == 3)
1494 start = 1024*1024; 1506 size = 1024*1024;
1495 else 1507 else
1496 start = 512*1024; 1508 size = 512*1024;
1497 1509
1498 for (i = start; i < obj->size; i <<= 1) 1510 while (size < obj_priv->base.size)
1499 ; 1511 size <<= 1;
1500 1512
1501 return i; 1513 return size;
1502} 1514}
1503 1515
1504/** 1516/**
@@ -2253,8 +2265,10 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
2253 2265
2254 i915_gem_object_put_pages_gtt(obj); 2266 i915_gem_object_put_pages_gtt(obj);
2255 2267
2256 i915_gem_info_remove_gtt(dev_priv, obj); 2268 i915_gem_info_remove_gtt(dev_priv, obj_priv);
2257 list_del_init(&obj_priv->mm_list); 2269 list_del_init(&obj_priv->mm_list);
2270 obj_priv->fenceable = true;
2271 obj_priv->mappable = true;
2258 2272
2259 drm_mm_put_block(obj_priv->gtt_space); 2273 drm_mm_put_block(obj_priv->gtt_space);
2260 obj_priv->gtt_space = NULL; 2274 obj_priv->gtt_space = NULL;
@@ -2311,16 +2325,16 @@ i915_gpu_idle(struct drm_device *dev)
2311 return 0; 2325 return 0;
2312} 2326}
2313 2327
2314static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) 2328static void sandybridge_write_fence_reg(struct drm_gem_object *obj)
2315{ 2329{
2316 struct drm_gem_object *obj = reg->obj;
2317 struct drm_device *dev = obj->dev; 2330 struct drm_device *dev = obj->dev;
2318 drm_i915_private_t *dev_priv = dev->dev_private; 2331 drm_i915_private_t *dev_priv = dev->dev_private;
2319 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 2332 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
2333 u32 size = i915_gem_get_gtt_size(obj_priv);
2320 int regnum = obj_priv->fence_reg; 2334 int regnum = obj_priv->fence_reg;
2321 uint64_t val; 2335 uint64_t val;
2322 2336
2323 val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) & 2337 val = (uint64_t)((obj_priv->gtt_offset + size - 4096) &
2324 0xfffff000) << 32; 2338 0xfffff000) << 32;
2325 val |= obj_priv->gtt_offset & 0xfffff000; 2339 val |= obj_priv->gtt_offset & 0xfffff000;
2326 val |= (uint64_t)((obj_priv->stride / 128) - 1) << 2340 val |= (uint64_t)((obj_priv->stride / 128) - 1) <<
@@ -2333,16 +2347,16 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
2333 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val); 2347 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val);
2334} 2348}
2335 2349
2336static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) 2350static void i965_write_fence_reg(struct drm_gem_object *obj)
2337{ 2351{
2338 struct drm_gem_object *obj = reg->obj;
2339 struct drm_device *dev = obj->dev; 2352 struct drm_device *dev = obj->dev;
2340 drm_i915_private_t *dev_priv = dev->dev_private; 2353 drm_i915_private_t *dev_priv = dev->dev_private;
2341 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 2354 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
2355 u32 size = i915_gem_get_gtt_size(obj_priv);
2342 int regnum = obj_priv->fence_reg; 2356 int regnum = obj_priv->fence_reg;
2343 uint64_t val; 2357 uint64_t val;
2344 2358
2345 val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) & 2359 val = (uint64_t)((obj_priv->gtt_offset + size - 4096) &
2346 0xfffff000) << 32; 2360 0xfffff000) << 32;
2347 val |= obj_priv->gtt_offset & 0xfffff000; 2361 val |= obj_priv->gtt_offset & 0xfffff000;
2348 val |= ((obj_priv->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; 2362 val |= ((obj_priv->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT;
@@ -2353,21 +2367,20 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
2353 I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val); 2367 I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val);
2354} 2368}
2355 2369
2356static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) 2370static void i915_write_fence_reg(struct drm_gem_object *obj)
2357{ 2371{
2358 struct drm_gem_object *obj = reg->obj;
2359 struct drm_device *dev = obj->dev; 2372 struct drm_device *dev = obj->dev;
2360 drm_i915_private_t *dev_priv = dev->dev_private; 2373 drm_i915_private_t *dev_priv = dev->dev_private;
2361 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 2374 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
2362 int regnum = obj_priv->fence_reg; 2375 u32 size = i915_gem_get_gtt_size(obj_priv);
2376 uint32_t fence_reg, val, pitch_val;
2363 int tile_width; 2377 int tile_width;
2364 uint32_t fence_reg, val;
2365 uint32_t pitch_val;
2366 2378
2367 if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || 2379 if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
2368 (obj_priv->gtt_offset & (obj->size - 1))) { 2380 (obj_priv->gtt_offset & (size - 1))) {
2369 WARN(1, "%s: object 0x%08x not 1M or size (0x%zx) aligned\n", 2381 WARN(1, "%s: object 0x%08x [fenceable? %d] not 1M or size (0x%08x) aligned [gtt_space offset=%lx, size=%lx]\n",
2370 __func__, obj_priv->gtt_offset, obj->size); 2382 __func__, obj_priv->gtt_offset, obj_priv->fenceable, size,
2383 obj_priv->gtt_space->start, obj_priv->gtt_space->size);
2371 return; 2384 return;
2372 } 2385 }
2373 2386
@@ -2390,23 +2403,24 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
2390 val = obj_priv->gtt_offset; 2403 val = obj_priv->gtt_offset;
2391 if (obj_priv->tiling_mode == I915_TILING_Y) 2404 if (obj_priv->tiling_mode == I915_TILING_Y)
2392 val |= 1 << I830_FENCE_TILING_Y_SHIFT; 2405 val |= 1 << I830_FENCE_TILING_Y_SHIFT;
2393 val |= I915_FENCE_SIZE_BITS(obj->size); 2406 val |= I915_FENCE_SIZE_BITS(size);
2394 val |= pitch_val << I830_FENCE_PITCH_SHIFT; 2407 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
2395 val |= I830_FENCE_REG_VALID; 2408 val |= I830_FENCE_REG_VALID;
2396 2409
2397 if (regnum < 8) 2410 fence_reg = obj_priv->fence_reg;
2398 fence_reg = FENCE_REG_830_0 + (regnum * 4); 2411 if (fence_reg < 8)
2412 fence_reg = FENCE_REG_830_0 + fence_reg * 4;
2399 else 2413 else
2400 fence_reg = FENCE_REG_945_8 + ((regnum - 8) * 4); 2414 fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4;
2401 I915_WRITE(fence_reg, val); 2415 I915_WRITE(fence_reg, val);
2402} 2416}
2403 2417
2404static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) 2418static void i830_write_fence_reg(struct drm_gem_object *obj)
2405{ 2419{
2406 struct drm_gem_object *obj = reg->obj;
2407 struct drm_device *dev = obj->dev; 2420 struct drm_device *dev = obj->dev;
2408 drm_i915_private_t *dev_priv = dev->dev_private; 2421 drm_i915_private_t *dev_priv = dev->dev_private;
2409 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 2422 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
2423 u32 size = i915_gem_get_gtt_size(obj_priv);
2410 int regnum = obj_priv->fence_reg; 2424 int regnum = obj_priv->fence_reg;
2411 uint32_t val; 2425 uint32_t val;
2412 uint32_t pitch_val; 2426 uint32_t pitch_val;
@@ -2426,7 +2440,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
2426 val = obj_priv->gtt_offset; 2440 val = obj_priv->gtt_offset;
2427 if (obj_priv->tiling_mode == I915_TILING_Y) 2441 if (obj_priv->tiling_mode == I915_TILING_Y)
2428 val |= 1 << I830_FENCE_TILING_Y_SHIFT; 2442 val |= 1 << I830_FENCE_TILING_Y_SHIFT;
2429 fence_size_bits = I830_FENCE_SIZE_BITS(obj->size); 2443 fence_size_bits = I830_FENCE_SIZE_BITS(size);
2430 WARN_ON(fence_size_bits & ~0x00000f00); 2444 WARN_ON(fence_size_bits & ~0x00000f00);
2431 val |= fence_size_bits; 2445 val |= fence_size_bits;
2432 val |= pitch_val << I830_FENCE_PITCH_SHIFT; 2446 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
@@ -2438,10 +2452,9 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
2438static int i915_find_fence_reg(struct drm_device *dev, 2452static int i915_find_fence_reg(struct drm_device *dev,
2439 bool interruptible) 2453 bool interruptible)
2440{ 2454{
2441 struct drm_i915_fence_reg *reg = NULL;
2442 struct drm_i915_gem_object *obj_priv = NULL;
2443 struct drm_i915_private *dev_priv = dev->dev_private; 2455 struct drm_i915_private *dev_priv = dev->dev_private;
2444 struct drm_gem_object *obj = NULL; 2456 struct drm_i915_fence_reg *reg;
2457 struct drm_i915_gem_object *obj_priv = NULL;
2445 int i, avail, ret; 2458 int i, avail, ret;
2446 2459
2447 /* First try to find a free reg */ 2460 /* First try to find a free reg */
@@ -2460,33 +2473,31 @@ static int i915_find_fence_reg(struct drm_device *dev,
2460 return -ENOSPC; 2473 return -ENOSPC;
2461 2474
2462 /* None available, try to steal one or wait for a user to finish */ 2475 /* None available, try to steal one or wait for a user to finish */
2463 i = I915_FENCE_REG_NONE; 2476 avail = I915_FENCE_REG_NONE;
2464 list_for_each_entry(reg, &dev_priv->mm.fence_list, 2477 list_for_each_entry(reg, &dev_priv->mm.fence_list,
2465 lru_list) { 2478 lru_list) {
2466 obj = reg->obj; 2479 obj_priv = to_intel_bo(reg->obj);
2467 obj_priv = to_intel_bo(obj);
2468
2469 if (obj_priv->pin_count) 2480 if (obj_priv->pin_count)
2470 continue; 2481 continue;
2471 2482
2472 /* found one! */ 2483 /* found one! */
2473 i = obj_priv->fence_reg; 2484 avail = obj_priv->fence_reg;
2474 break; 2485 break;
2475 } 2486 }
2476 2487
2477 BUG_ON(i == I915_FENCE_REG_NONE); 2488 BUG_ON(avail == I915_FENCE_REG_NONE);
2478 2489
2479 /* We only have a reference on obj from the active list. put_fence_reg 2490 /* We only have a reference on obj from the active list. put_fence_reg
2480 * might drop that one, causing a use-after-free in it. So hold a 2491 * might drop that one, causing a use-after-free in it. So hold a
2481 * private reference to obj like the other callers of put_fence_reg 2492 * private reference to obj like the other callers of put_fence_reg
2482 * (set_tiling ioctl) do. */ 2493 * (set_tiling ioctl) do. */
2483 drm_gem_object_reference(obj); 2494 drm_gem_object_reference(&obj_priv->base);
2484 ret = i915_gem_object_put_fence_reg(obj, interruptible); 2495 ret = i915_gem_object_put_fence_reg(&obj_priv->base, interruptible);
2485 drm_gem_object_unreference(obj); 2496 drm_gem_object_unreference(&obj_priv->base);
2486 if (ret != 0) 2497 if (ret != 0)
2487 return ret; 2498 return ret;
2488 2499
2489 return i; 2500 return avail;
2490} 2501}
2491 2502
2492/** 2503/**
@@ -2551,22 +2562,23 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj,
2551 2562
2552 switch (INTEL_INFO(dev)->gen) { 2563 switch (INTEL_INFO(dev)->gen) {
2553 case 6: 2564 case 6:
2554 sandybridge_write_fence_reg(reg); 2565 sandybridge_write_fence_reg(obj);
2555 break; 2566 break;
2556 case 5: 2567 case 5:
2557 case 4: 2568 case 4:
2558 i965_write_fence_reg(reg); 2569 i965_write_fence_reg(obj);
2559 break; 2570 break;
2560 case 3: 2571 case 3:
2561 i915_write_fence_reg(reg); 2572 i915_write_fence_reg(obj);
2562 break; 2573 break;
2563 case 2: 2574 case 2:
2564 i830_write_fence_reg(reg); 2575 i830_write_fence_reg(obj);
2565 break; 2576 break;
2566 } 2577 }
2567 2578
2568 trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, 2579 trace_i915_gem_object_get_fence(obj,
2569 obj_priv->tiling_mode); 2580 obj_priv->fence_reg,
2581 obj_priv->tiling_mode);
2570 2582
2571 return 0; 2583 return 0;
2572} 2584}
@@ -2671,13 +2683,15 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj,
2671static int 2683static int
2672i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, 2684i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
2673 unsigned alignment, 2685 unsigned alignment,
2674 bool mappable) 2686 bool mappable,
2687 bool need_fence)
2675{ 2688{
2676 struct drm_device *dev = obj->dev; 2689 struct drm_device *dev = obj->dev;
2677 drm_i915_private_t *dev_priv = dev->dev_private; 2690 drm_i915_private_t *dev_priv = dev->dev_private;
2678 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 2691 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
2679 struct drm_mm_node *free_space; 2692 struct drm_mm_node *free_space;
2680 gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; 2693 gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN;
2694 u32 size, fence_size, fence_alignment;
2681 int ret; 2695 int ret;
2682 2696
2683 if (obj_priv->madv != I915_MADV_WILLNEED) { 2697 if (obj_priv->madv != I915_MADV_WILLNEED) {
@@ -2685,13 +2699,18 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
2685 return -EINVAL; 2699 return -EINVAL;
2686 } 2700 }
2687 2701
2702 fence_size = i915_gem_get_gtt_size(obj_priv);
2703 fence_alignment = i915_gem_get_gtt_alignment(obj_priv);
2704
2688 if (alignment == 0) 2705 if (alignment == 0)
2689 alignment = i915_gem_get_gtt_alignment(obj); 2706 alignment = need_fence ? fence_alignment : 4096;
2690 if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { 2707 if (need_fence && alignment & (fence_alignment - 1)) {
2691 DRM_ERROR("Invalid object alignment requested %u\n", alignment); 2708 DRM_ERROR("Invalid object alignment requested %u\n", alignment);
2692 return -EINVAL; 2709 return -EINVAL;
2693 } 2710 }
2694 2711
2712 size = need_fence ? fence_size : obj->size;
2713
2695 /* If the object is bigger than the entire aperture, reject it early 2714 /* If the object is bigger than the entire aperture, reject it early
2696 * before evicting everything in a vain attempt to find space. 2715 * before evicting everything in a vain attempt to find space.
2697 */ 2716 */
@@ -2705,32 +2724,29 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
2705 if (mappable) 2724 if (mappable)
2706 free_space = 2725 free_space =
2707 drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, 2726 drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
2708 obj->size, alignment, 0, 2727 size, alignment, 0,
2709 dev_priv->mm.gtt_mappable_end, 2728 dev_priv->mm.gtt_mappable_end,
2710 0); 2729 0);
2711 else 2730 else
2712 free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, 2731 free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
2713 obj->size, alignment, 0); 2732 size, alignment, 0);
2714 2733
2715 if (free_space != NULL) { 2734 if (free_space != NULL) {
2716 if (mappable) 2735 if (mappable)
2717 obj_priv->gtt_space = 2736 obj_priv->gtt_space =
2718 drm_mm_get_block_range_generic(free_space, 2737 drm_mm_get_block_range_generic(free_space,
2719 obj->size, 2738 size, alignment, 0,
2720 alignment, 0,
2721 dev_priv->mm.gtt_mappable_end, 2739 dev_priv->mm.gtt_mappable_end,
2722 0); 2740 0);
2723 else 2741 else
2724 obj_priv->gtt_space = 2742 obj_priv->gtt_space =
2725 drm_mm_get_block(free_space, obj->size, 2743 drm_mm_get_block(free_space, size, alignment);
2726 alignment);
2727 } 2744 }
2728 if (obj_priv->gtt_space == NULL) { 2745 if (obj_priv->gtt_space == NULL) {
2729 /* If the gtt is empty and we're still having trouble 2746 /* If the gtt is empty and we're still having trouble
2730 * fitting our object in, we're out of memory. 2747 * fitting our object in, we're out of memory.
2731 */ 2748 */
2732 ret = i915_gem_evict_something(dev, obj->size, alignment, 2749 ret = i915_gem_evict_something(dev, size, alignment, mappable);
2733 mappable);
2734 if (ret) 2750 if (ret)
2735 return ret; 2751 return ret;
2736 2752
@@ -2744,7 +2760,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
2744 2760
2745 if (ret == -ENOMEM) { 2761 if (ret == -ENOMEM) {
2746 /* first try to clear up some space from the GTT */ 2762 /* first try to clear up some space from the GTT */
2747 ret = i915_gem_evict_something(dev, obj->size, 2763 ret = i915_gem_evict_something(dev, size,
2748 alignment, mappable); 2764 alignment, mappable);
2749 if (ret) { 2765 if (ret) {
2750 /* now try to shrink everyone else */ 2766 /* now try to shrink everyone else */
@@ -2775,8 +2791,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
2775 drm_mm_put_block(obj_priv->gtt_space); 2791 drm_mm_put_block(obj_priv->gtt_space);
2776 obj_priv->gtt_space = NULL; 2792 obj_priv->gtt_space = NULL;
2777 2793
2778 ret = i915_gem_evict_something(dev, obj->size, alignment, 2794 ret = i915_gem_evict_something(dev, size,
2779 mappable); 2795 alignment, mappable);
2780 if (ret) 2796 if (ret)
2781 return ret; 2797 return ret;
2782 2798
@@ -2787,7 +2803,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
2787 2803
2788 /* keep track of bounds object by adding it to the inactive list */ 2804 /* keep track of bounds object by adding it to the inactive list */
2789 list_add_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); 2805 list_add_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list);
2790 i915_gem_info_add_gtt(dev_priv, obj); 2806 i915_gem_info_add_gtt(dev_priv, obj_priv);
2791 2807
2792 /* Assert that the object is not currently in any GPU domain. As it 2808 /* Assert that the object is not currently in any GPU domain. As it
2793 * wasn't in the GTT, there shouldn't be any way it could have been in 2809 * wasn't in the GTT, there shouldn't be any way it could have been in
@@ -2798,6 +2814,13 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
2798 2814
2799 trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, mappable); 2815 trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, mappable);
2800 2816
2817 obj_priv->fenceable =
2818 obj_priv->gtt_space->size == fence_size &&
2819 (obj_priv->gtt_space->start & (fence_alignment -1)) == 0;
2820
2821 obj_priv->mappable =
2822 obj_priv->gtt_offset + obj->size <= dev_priv->mm.gtt_mappable_end;
2823
2801 return 0; 2824 return 0;
2802} 2825}
2803 2826
@@ -3516,9 +3539,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
3516 entry->relocation_count ? true : need_fence; 3539 entry->relocation_count ? true : need_fence;
3517 3540
3518 /* Check fence reg constraints and rebind if necessary */ 3541 /* Check fence reg constraints and rebind if necessary */
3519 if (need_fence && 3542 if ((need_fence && !obj->fenceable) ||
3520 !i915_gem_object_fence_offset_ok(&obj->base, 3543 (need_mappable && !obj->mappable)) {
3521 obj->tiling_mode)) {
3522 ret = i915_gem_object_unbind(&obj->base); 3544 ret = i915_gem_object_unbind(&obj->base);
3523 if (ret) 3545 if (ret)
3524 break; 3546 break;
@@ -3526,7 +3548,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
3526 3548
3527 ret = i915_gem_object_pin(&obj->base, 3549 ret = i915_gem_object_pin(&obj->base,
3528 entry->alignment, 3550 entry->alignment,
3529 need_mappable); 3551 need_mappable,
3552 need_fence);
3530 if (ret) 3553 if (ret)
3531 break; 3554 break;
3532 3555
@@ -4097,7 +4120,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
4097 4120
4098int 4121int
4099i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, 4122i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment,
4100 bool mappable) 4123 bool mappable, bool need_fence)
4101{ 4124{
4102 struct drm_device *dev = obj->dev; 4125 struct drm_device *dev = obj->dev;
4103 struct drm_i915_private *dev_priv = dev->dev_private; 4126 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4108,14 +4131,15 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment,
4108 WARN_ON(i915_verify_lists(dev)); 4131 WARN_ON(i915_verify_lists(dev));
4109 4132
4110 if (obj_priv->gtt_space != NULL) { 4133 if (obj_priv->gtt_space != NULL) {
4111 if (alignment == 0) 4134 if ((alignment && obj_priv->gtt_offset & (alignment - 1)) ||
4112 alignment = i915_gem_get_gtt_alignment(obj); 4135 (need_fence && !obj_priv->fenceable) ||
4113 if (obj_priv->gtt_offset & (alignment - 1) || 4136 (mappable && !obj_priv->mappable)) {
4114 (mappable && !i915_gem_object_cpu_accessible(obj_priv))) {
4115 WARN(obj_priv->pin_count, 4137 WARN(obj_priv->pin_count,
4116 "bo is already pinned with incorrect alignment:" 4138 "bo is already pinned with incorrect alignment:"
4117 " offset=%x, req.alignment=%x\n", 4139 " offset=%x, req.alignment=%x, need_fence=%d, fenceable=%d, mappable=%d, cpu_accessible=%d\n",
4118 obj_priv->gtt_offset, alignment); 4140 obj_priv->gtt_offset, alignment,
4141 need_fence, obj_priv->fenceable,
4142 mappable, obj_priv->mappable);
4119 ret = i915_gem_object_unbind(obj); 4143 ret = i915_gem_object_unbind(obj);
4120 if (ret) 4144 if (ret)
4121 return ret; 4145 return ret;
@@ -4123,13 +4147,14 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment,
4123 } 4147 }
4124 4148
4125 if (obj_priv->gtt_space == NULL) { 4149 if (obj_priv->gtt_space == NULL) {
4126 ret = i915_gem_object_bind_to_gtt(obj, alignment, mappable); 4150 ret = i915_gem_object_bind_to_gtt(obj, alignment,
4151 mappable, need_fence);
4127 if (ret) 4152 if (ret)
4128 return ret; 4153 return ret;
4129 } 4154 }
4130 4155
4131 if (obj_priv->pin_count++ == 0) { 4156 if (obj_priv->pin_count++ == 0) {
4132 i915_gem_info_add_pin(dev_priv, obj, mappable); 4157 i915_gem_info_add_pin(dev_priv, obj_priv, mappable);
4133 if (!obj_priv->active) 4158 if (!obj_priv->active)
4134 list_move_tail(&obj_priv->mm_list, 4159 list_move_tail(&obj_priv->mm_list,
4135 &dev_priv->mm.pinned_list); 4160 &dev_priv->mm.pinned_list);
@@ -4155,7 +4180,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj)
4155 if (!obj_priv->active) 4180 if (!obj_priv->active)
4156 list_move_tail(&obj_priv->mm_list, 4181 list_move_tail(&obj_priv->mm_list,
4157 &dev_priv->mm.inactive_list); 4182 &dev_priv->mm.inactive_list);
4158 i915_gem_info_remove_pin(dev_priv, obj); 4183 i915_gem_info_remove_pin(dev_priv, obj_priv);
4159 } 4184 }
4160 WARN_ON(i915_verify_lists(dev)); 4185 WARN_ON(i915_verify_lists(dev));
4161} 4186}
@@ -4196,7 +4221,8 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
4196 obj_priv->user_pin_count++; 4221 obj_priv->user_pin_count++;
4197 obj_priv->pin_filp = file_priv; 4222 obj_priv->pin_filp = file_priv;
4198 if (obj_priv->user_pin_count == 1) { 4223 if (obj_priv->user_pin_count == 1) {
4199 ret = i915_gem_object_pin(obj, args->alignment, true); 4224 ret = i915_gem_object_pin(obj, args->alignment,
4225 true, obj_priv->tiling_mode);
4200 if (ret) 4226 if (ret)
4201 goto out; 4227 goto out;
4202 } 4228 }
@@ -4389,6 +4415,8 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev,
4389 INIT_LIST_HEAD(&obj->ring_list); 4415 INIT_LIST_HEAD(&obj->ring_list);
4390 INIT_LIST_HEAD(&obj->gpu_write_list); 4416 INIT_LIST_HEAD(&obj->gpu_write_list);
4391 obj->madv = I915_MADV_WILLNEED; 4417 obj->madv = I915_MADV_WILLNEED;
4418 obj->fenceable = true;
4419 obj->mappable = true;
4392 4420
4393 return &obj->base; 4421 return &obj->base;
4394} 4422}
@@ -4508,7 +4536,7 @@ i915_gem_init_pipe_control(struct drm_device *dev)
4508 obj_priv = to_intel_bo(obj); 4536 obj_priv = to_intel_bo(obj);
4509 obj_priv->agp_type = AGP_USER_CACHED_MEMORY; 4537 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
4510 4538
4511 ret = i915_gem_object_pin(obj, 4096, true); 4539 ret = i915_gem_object_pin(obj, 4096, true, false);
4512 if (ret) 4540 if (ret)
4513 goto err_unref; 4541 goto err_unref;
4514 4542
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index af352de70be1..0597a737ebad 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -181,7 +181,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
181} 181}
182 182
183/* Check pitch constriants for all chips & tiling formats */ 183/* Check pitch constriants for all chips & tiling formats */
184bool 184static bool
185i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) 185i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
186{ 186{
187 int tile_width; 187 int tile_width;
@@ -232,25 +232,35 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
232 return true; 232 return true;
233} 233}
234 234
235bool 235/* Is the current GTT allocation valid for the change in tiling? */
236i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) 236static bool
237i915_gem_object_fence_ok(struct drm_gem_object *obj, int tiling_mode)
237{ 238{
238 struct drm_device *dev = obj->dev;
239 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 239 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
240 240 u32 size;
241 if (obj_priv->gtt_space == NULL)
242 return true;
243 241
244 if (tiling_mode == I915_TILING_NONE) 242 if (tiling_mode == I915_TILING_NONE)
245 return true; 243 return true;
246 244
247 if (INTEL_INFO(dev)->gen >= 4) 245 if (INTEL_INFO(obj->dev)->gen >= 4)
248 return true; 246 return true;
249 247
250 if (obj_priv->gtt_offset & (obj->size - 1)) 248 /*
249 * Previous chips need to be aligned to the size of the smallest
250 * fence register that can contain the object.
251 */
252 if (INTEL_INFO(obj->dev)->gen == 3)
253 size = 1024*1024;
254 else
255 size = 512*1024;
256
257 while (size < obj_priv->base.size)
258 size <<= 1;
259
260 if (obj_priv->gtt_offset & (size - 1))
251 return false; 261 return false;
252 262
253 if (IS_GEN3(dev)) { 263 if (INTEL_INFO(obj->dev)->gen == 3) {
254 if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) 264 if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK)
255 return false; 265 return false;
256 } else { 266 } else {
@@ -331,7 +341,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
331 * tiling mode. Otherwise we can just leave it alone, but 341 * tiling mode. Otherwise we can just leave it alone, but
332 * need to ensure that any fence register is cleared. 342 * need to ensure that any fence register is cleared.
333 */ 343 */
334 if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) 344 if (!i915_gem_object_fence_ok(obj, args->tiling_mode))
335 ret = i915_gem_object_unbind(obj); 345 ret = i915_gem_object_unbind(obj);
336 else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) 346 else if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
337 ret = i915_gem_object_put_fence_reg(obj, true); 347 ret = i915_gem_object_put_fence_reg(obj, true);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c9c4c707cf1a..4954af23b7c8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1461,7 +1461,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
1461 BUG(); 1461 BUG();
1462 } 1462 }
1463 1463
1464 ret = i915_gem_object_pin(obj, alignment, true); 1464 ret = i915_gem_object_pin(obj, alignment,
1465 !pipelined, obj_priv->tiling_mode);
1465 if (ret) 1466 if (ret)
1466 return ret; 1467 return ret;
1467 1468
@@ -4353,7 +4354,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
4353 /* we only need to pin inside GTT if cursor is non-phy */ 4354 /* we only need to pin inside GTT if cursor is non-phy */
4354 mutex_lock(&dev->struct_mutex); 4355 mutex_lock(&dev->struct_mutex);
4355 if (!dev_priv->info->cursor_needs_physical) { 4356 if (!dev_priv->info->cursor_needs_physical) {
4356 ret = i915_gem_object_pin(bo, PAGE_SIZE, true); 4357 ret = i915_gem_object_pin(bo, PAGE_SIZE, true, false);
4357 if (ret) { 4358 if (ret) {
4358 DRM_ERROR("failed to pin cursor bo\n"); 4359 DRM_ERROR("failed to pin cursor bo\n");
4359 goto fail_locked; 4360 goto fail_locked;
@@ -5517,7 +5518,7 @@ intel_alloc_context_page(struct drm_device *dev)
5517 } 5518 }
5518 5519
5519 mutex_lock(&dev->struct_mutex); 5520 mutex_lock(&dev->struct_mutex);
5520 ret = i915_gem_object_pin(ctx, 4096, true); 5521 ret = i915_gem_object_pin(ctx, 4096, false, false);
5521 if (ret) { 5522 if (ret) {
5522 DRM_ERROR("failed to pin power context: %d\n", ret); 5523 DRM_ERROR("failed to pin power context: %d\n", ret);
5523 goto err_unref; 5524 goto err_unref;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index beda2016eb16..e62e1b3d243f 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -781,7 +781,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
781 if (ret != 0) 781 if (ret != 0)
782 return ret; 782 return ret;
783 783
784 ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true); 784 ret = i915_gem_object_pin(new_bo, PAGE_SIZE, false, false);
785 if (ret != 0) 785 if (ret != 0)
786 return ret; 786 return ret;
787 787
@@ -1423,7 +1423,7 @@ void intel_setup_overlay(struct drm_device *dev)
1423 } 1423 }
1424 overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; 1424 overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr;
1425 } else { 1425 } else {
1426 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); 1426 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true, false);
1427 if (ret) { 1427 if (ret) {
1428 DRM_ERROR("failed to pin overlay register bo\n"); 1428 DRM_ERROR("failed to pin overlay register bo\n");
1429 goto out_free_bo; 1429 goto out_free_bo;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index e88214ef24b1..632a98e0ba5c 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -547,7 +547,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
547 obj_priv = to_intel_bo(obj); 547 obj_priv = to_intel_bo(obj);
548 obj_priv->agp_type = AGP_USER_CACHED_MEMORY; 548 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
549 549
550 ret = i915_gem_object_pin(obj, 4096, true); 550 ret = i915_gem_object_pin(obj, 4096, true, false);
551 if (ret != 0) { 551 if (ret != 0) {
552 goto err_unref; 552 goto err_unref;
553 } 553 }
@@ -603,7 +603,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
603 603
604 ring->gem_object = obj; 604 ring->gem_object = obj;
605 605
606 ret = i915_gem_object_pin(obj, PAGE_SIZE, true); 606 ret = i915_gem_object_pin(obj, PAGE_SIZE, true, false);
607 if (ret) 607 if (ret)
608 goto err_unref; 608 goto err_unref;
609 609
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 8c641bed9bbd..b20dbb2d7174 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -287,6 +287,7 @@ typedef struct drm_i915_irq_wait {
287#define I915_PARAM_HAS_EXECBUF2 9 287#define I915_PARAM_HAS_EXECBUF2 9
288#define I915_PARAM_HAS_BSD 10 288#define I915_PARAM_HAS_BSD 10
289#define I915_PARAM_HAS_BLT 11 289#define I915_PARAM_HAS_BLT 11
290#define I915_PARAM_HAS_RELAXED_FENCING 12
290 291
291typedef struct drm_i915_getparam { 292typedef struct drm_i915_getparam {
292 int param; 293 int param;