diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a20edca..3a755e4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1577,7 +1577,11 @@ void i915_gem_free_all_phys_object(struct drm_device *dev);
 void i915_gem_release(struct drm_device *dev, struct drm_file *file);
 
 uint32_t
-i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode);
+i915_gem_get_gtt_linear_size(struct drm_device *dev, uint32_t size,
+			     int tiling_mode);
+uint32_t
+i915_gem_get_gtt_physical_size(struct drm_device *dev, uint32_t size,
+			       int tiling_mode, int stride);
 uint32_t
 i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size,
 			    int tiling_mode, bool fenced);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a878b9f..548ee8b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1476,7 +1476,8 @@ i915_gem_get_tile_width(struct drm_device *dev, int tiling_mode)
 }
 
 uint32_t
-i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode)
+i915_gem_get_gtt_linear_size(struct drm_device *dev, uint32_t size,
+			     int tiling_mode)
 {
 	uint32_t gtt_size;
 
@@ -1496,6 +1497,26 @@ i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode)
 	return gtt_size;
 }
 
+uint32_t
+i915_gem_get_gtt_physical_size(struct drm_device *dev, uint32_t size,
+			       int tiling_mode, int stride)
+{
+	uint32_t linear_size;
+	int tile_y_num;
+	int tile_row_size;
+
+	if (tiling_mode == I915_TILING_NONE)
+		return size;
+
+	linear_size = i915_gem_get_gtt_linear_size(dev, size, tiling_mode);
+	tile_y_num = DIV_ROUND_UP(stride,
+				  i915_gem_get_tile_width(dev, tiling_mode));
+	tile_row_size = tile_y_num * PAGE_SIZE;
+	size = roundup(size, tile_row_size);
+
+	return max(size, linear_size);
+}
+
 /**
  * i915_gem_get_gtt_alignment - return required GTT alignment for an object
  * @obj: object to check
@@ -1519,7 +1540,7 @@ i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size,
 	 * Previous chips need to be aligned to the size of the smallest
 	 * fence register that can contain the object.
 	 */
-	return i915_gem_get_gtt_size(dev, size, tiling_mode);
+	return i915_gem_get_gtt_linear_size(dev, size, tiling_mode);
 }
 
 static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
@@ -2566,8 +2587,10 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
 	}
 
 	if (obj) {
-		u32 size = obj->gtt_space->size;
+		u32 size;
 
+		size = i915_gem_get_gtt_linear_size(dev, obj->base.size,
+						    obj->tiling_mode);
 		val = (uint64_t)((obj->gtt_offset + size - 4096) &
 				 0xfffff000) << 32;
 		val |= obj->gtt_offset & 0xfffff000;
@@ -2590,10 +2613,12 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg,
 	u32 val;
 
 	if (obj) {
-		u32 size = obj->gtt_space->size;
+		u32 size;
 		int pitch_val;
 		int tile_width;
 
+		size = i915_gem_get_gtt_linear_size(dev, obj->base.size,
+						    obj->tiling_mode);
 		WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) ||
 		     (size & -size) != size ||
 		     (obj->gtt_offset & (size - 1)),
@@ -2634,9 +2659,11 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg,
 	uint32_t val;
 
 	if (obj) {
-		u32 size = obj->gtt_space->size;
+		u32 size;
 		uint32_t pitch_val;
 
+		size = i915_gem_get_gtt_linear_size(dev, obj->base.size,
+						    obj->tiling_mode);
 		WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) ||
 		     (size & -size) != size ||
 		     (obj->gtt_offset & (size - 1)),
@@ -2929,9 +2956,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
 		return -EINVAL;
 	}
 
-	fence_size = i915_gem_get_gtt_size(dev,
-					   obj->base.size,
-					   obj->tiling_mode);
+	fence_size = i915_gem_get_gtt_physical_size(dev, obj->base.size,
+						obj->tiling_mode, obj->stride);
 	fence_alignment = i915_gem_get_gtt_alignment(dev,
 						     obj->base.size,
 						     obj->tiling_mode, true);
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 7b0a3b3..e738fcb 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -251,7 +251,8 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
 
 /* Is the current GTT allocation valid for the change in tiling? */
 static bool
-i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
+i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode,
+			 int stride)
 {
 	u32 size;
 
@@ -269,7 +270,8 @@ i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
 			return false;
 	}
 
-	size = i915_gem_get_gtt_size(obj->base.dev, obj->base.size, tiling_mode);
+	size = i915_gem_get_gtt_physical_size(obj->base.dev, obj->base.size,
+					      tiling_mode, stride);
 	if (obj->gtt_space->size != size)
 		return false;
 
@@ -355,7 +357,8 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
 		obj->map_and_fenceable =
 			obj->gtt_space == NULL ||
 			(obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end &&
-			 i915_gem_object_fence_ok(obj, args->tiling_mode));
+			 i915_gem_object_fence_ok(obj, args->tiling_mode,
+						  args->stride));
 
 		/* Rebind if we need a change of alignment */
 		if (!obj->map_and_fenceable) {
