diff mbox

drm/i915: Make sure fb objects with rotated views are also fenceable

Message ID 1442022266-21065-1-git-send-email-vivek.kasireddy@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vivek Kasireddy Sept. 12, 2015, 1:44 a.m. UTC
From: Vivek Kasireddy <vivek.kasireddy@intel.com>

Currently, fb objects with rotated views are ignored while pinning. Therefore,
include the rotated view type and use the view size instead of the object's
size to determine if it is fenceable. And, look at the view and its offset 
while writing and pinning to the fence registers.

Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Matthew D Roper <matthew.d.roper@intel.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h            |  6 ++--
 drivers/gpu/drm/i915/i915_gem.c            | 13 +++++----
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  4 +--
 drivers/gpu/drm/i915/i915_gem_fence.c      | 47 ++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_display.c       |  4 +--
 5 files changed, 48 insertions(+), 26 deletions(-)

Comments

Chris Wilson Sept. 12, 2015, 7:49 a.m. UTC | #1
On Fri, Sep 11, 2015 at 06:44:26PM -0700, Vivek Kasireddy wrote:
> From: Vivek Kasireddy <vivek.kasireddy@intel.com>
> 
> Currently, fb objects with rotated views are ignored while pinning. Therefore,
> include the rotated view type and use the view size instead of the object's
> size to determine if it is fenceable. And, look at the view and its offset 
> while writing and pinning to the fence registers.
> 
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Matthew D Roper <matthew.d.roper@intel.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>

No. The fenceable decision needs only be made on the vma, which can be
separate for rotated views, partial views etc.

As usual I have such a patch...
-Chris
Tvrtko Ursulin Sept. 14, 2015, 9:08 a.m. UTC | #2
Hi,

On 09/12/2015 02:44 AM, Vivek Kasireddy wrote:
> From: Vivek Kasireddy <vivek.kasireddy@intel.com>
>
> Currently, fb objects with rotated views are ignored while pinning. Therefore,
> include the rotated view type and use the view size instead of the object's
> size to determine if it is fenceable. And, look at the view and its offset
> while writing and pinning to the fence registers.

I didn't figure out from the commit message if something is broken or?

AFAIR rotated views deliberately skip on fencing since rotated view has 
shuffled pages in memory so it would be a weird view for userspace to 
handle.

Especially this below:

>   static void i965_write_fence_reg(struct drm_device *dev, int reg,
> -				 struct drm_i915_gem_object *obj)
> +				 struct drm_i915_gem_object *obj,
> +				 const struct i915_ggtt_view *view)
>   {
>   	struct drm_i915_private *dev_priv = dev->dev_private;
>   	int fence_reg;
>   	int fence_pitch_shift;
> +	const struct i915_ggtt_view *ggtt_view = view;
>
>   	if (INTEL_INFO(dev)->gen >= 6) {
>   		fence_reg = FENCE_REG_SANDYBRIDGE_0;
> @@ -95,9 +97,13 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
>   			size = (size / row_size) * row_size;
>   		}
>
> -		val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) &
> -				 0xfffff000) << 32;
> -		val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
> +		if (!ggtt_view)
> +			ggtt_view = &i915_ggtt_view_normal;
> +
> +		val = (uint64_t)((i915_gem_obj_ggtt_offset_view((obj), ggtt_view)
> +				  + size - 4096) & 0xfffff000) << 32;
> +		val |= i915_gem_obj_ggtt_offset_view((obj), ggtt_view) & 0xfffff000;
> +

Looks like the code can be setting up a fence with a rotated view GGTT 
address which looks wrong? Is this really what is wanted and why?

Regards,

Tvrtko
Vivek Kasireddy Sept. 15, 2015, 1:38 a.m. UTC | #3
On Sat, 12 Sep 2015 08:49:08 +0100
Chris Wilson <chris@chris-wilson.co.uk> wrote:

> On Fri, Sep 11, 2015 at 06:44:26PM -0700, Vivek Kasireddy wrote:
> > From: Vivek Kasireddy <vivek.kasireddy@intel.com>
> > 
> > Currently, fb objects with rotated views are ignored while pinning.
> > Therefore, include the rotated view type and use the view size
> > instead of the object's size to determine if it is fenceable. And,
> > look at the view and its offset while writing and pinning to the
> > fence registers.
> > 
> > Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> > Cc: Matthew D Roper <matthew.d.roper@intel.com>
> > Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> 
> No. The fenceable decision needs only be made on the vma, which can be
> separate for rotated views, partial views etc.
> 
> As usual I have such a patch...
> -Chris

The fenceable decision is indeed made on the vma; my patch doesn't
change that behavior. I am just fixing the warning raised here:

if (WARN_ON(!obj->map_and_fenceable))

inside i915_gem_object_get_fence(). This warning is raised because
i915_gem_object_do_pin() only looks at normal views and completely
ignores the rotated views for the associated Y-tiled fb objects
that are passed on by i915_gem_object_pin_to_display_plane().

Does your patch solve this problem in a different way?
-Vivek
>
Vivek Kasireddy Sept. 15, 2015, 2:09 a.m. UTC | #4
On Mon, 14 Sep 2015 10:08:19 +0100
Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> wrote:

> 
> Hi,
> 
> On 09/12/2015 02:44 AM, Vivek Kasireddy wrote:
> > From: Vivek Kasireddy <vivek.kasireddy@intel.com>
> >
> > Currently, fb objects with rotated views are ignored while pinning.
> > Therefore, include the rotated view type and use the view size
> > instead of the object's size to determine if it is fenceable. And,
> > look at the view and its offset while writing and pinning to the
> > fence registers.
> 
> I didn't figure out from the commit message if something is broken or?
> 
> AFAIR rotated views deliberately skip on fencing since rotated view
> has shuffled pages in memory so it would be a weird view for
> userspace to handle.

Hi Tvrtko,
I apologize for the short and ambiguous commit message. 
As I mentioned in my other reply to Chris, the reason for this patch is
because of this:
	if (WARN_ON(!obj->map_and_fenceable))
		return -EINVAL;
inside i915_find_fence_reg(). I am trying to enable 90 degree rotation
for the Weston compositor as part of which I need to allocate and flip
a Y-tiled fb obj. This fails because i915_gem_object_do_pin() ignores
the rotated view passed by i915_gem_object_pin_to_display_plane() and
hence obj->map_and_fenceable never gets set.

> 
> Especially this below:
> 
> >   static void i965_write_fence_reg(struct drm_device *dev, int reg,
> > -				 struct drm_i915_gem_object *obj)
> > +				 struct drm_i915_gem_object *obj,
> > +				 const struct i915_ggtt_view *view)
> >   {
> >   	struct drm_i915_private *dev_priv = dev->dev_private;
> >   	int fence_reg;
> >   	int fence_pitch_shift;
> > +	const struct i915_ggtt_view *ggtt_view = view;
> >
> >   	if (INTEL_INFO(dev)->gen >= 6) {
> >   		fence_reg = FENCE_REG_SANDYBRIDGE_0;
> > @@ -95,9 +97,13 @@ static void i965_write_fence_reg(struct
> > drm_device *dev, int reg, size = (size / row_size) * row_size;
> >   		}
> >
> > -		val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) +
> > size - 4096) &
> > -				 0xfffff000) << 32;
> > -		val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
> > +		if (!ggtt_view)
> > +			ggtt_view = &i915_ggtt_view_normal;
> > +
> > +		val =
> > (uint64_t)((i915_gem_obj_ggtt_offset_view((obj), ggtt_view)
> > +				  + size - 4096) & 0xfffff000) <<
> > 32;
> > +		val |= i915_gem_obj_ggtt_offset_view((obj),
> > ggtt_view) & 0xfffff000; +
> 
> Looks like the code can be setting up a fence with a rotated view
> GGTT address which looks wrong? Is this really what is wanted and why?
> 
> Regards,
> 
> Tvrtko
Well, i915_gem_obj_ggtt_offset() always calls
i915_gem_obj_ggtt_offset_view() with the default normal view type which
I suppose is incorrect right? When a rotated view is passed from
i915_gem_object_pin_to_display_plane(), i915_gem_obj_ggtt_offset_view() 
will not be able to find the associated vma.

-Vivek
Tvrtko Ursulin Sept. 15, 2015, 9:29 a.m. UTC | #5
On 09/15/2015 03:09 AM, Vivek Kasireddy wrote:
> On Mon, 14 Sep 2015 10:08:19 +0100
> Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> wrote:
>
>>
>> Hi,
>>
>> On 09/12/2015 02:44 AM, Vivek Kasireddy wrote:
>>> From: Vivek Kasireddy <vivek.kasireddy@intel.com>
>>>
>>> Currently, fb objects with rotated views are ignored while pinning.
>>> Therefore, include the rotated view type and use the view size
>>> instead of the object's size to determine if it is fenceable. And,
>>> look at the view and its offset while writing and pinning to the
>>> fence registers.
>>
>> I didn't figure out from the commit message if something is broken or?
>>
>> AFAIR rotated views deliberately skip on fencing since rotated view
>> has shuffled pages in memory so it would be a weird view for
>> userspace to handle.
>
> Hi Tvrtko,
> I apologize for the short and ambiguous commit message.
> As I mentioned in my other reply to Chris, the reason for this patch is
> because of this:
> 	if (WARN_ON(!obj->map_and_fenceable))
> 		return -EINVAL;
> inside i915_find_fence_reg(). I am trying to enable 90 degree rotation
> for the Weston compositor as part of which I need to allocate and flip
> a Y-tiled fb obj. This fails because i915_gem_object_do_pin() ignores

The use case itself has been exercised in general and it does work.

However I suspect you are using SET_TILING on the object to set it to Y 
tiled? That would explain i915_gem_object_get_fence trying to enable 
fencing.

This indeed looks like an omission in test coverage, needs a test case 
in kms_addfb_basic/addfb25 test group.

> the rotated view passed by i915_gem_object_pin_to_display_plane() and
> hence obj->map_and_fenceable never gets set.
>
>>
>> Especially this below:
>>
>>>    static void i965_write_fence_reg(struct drm_device *dev, int reg,
>>> -				 struct drm_i915_gem_object *obj)
>>> +				 struct drm_i915_gem_object *obj,
>>> +				 const struct i915_ggtt_view *view)
>>>    {
>>>    	struct drm_i915_private *dev_priv = dev->dev_private;
>>>    	int fence_reg;
>>>    	int fence_pitch_shift;
>>> +	const struct i915_ggtt_view *ggtt_view = view;
>>>
>>>    	if (INTEL_INFO(dev)->gen >= 6) {
>>>    		fence_reg = FENCE_REG_SANDYBRIDGE_0;
>>> @@ -95,9 +97,13 @@ static void i965_write_fence_reg(struct
>>> drm_device *dev, int reg, size = (size / row_size) * row_size;
>>>    		}
>>>
>>> -		val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) +
>>> size - 4096) &
>>> -				 0xfffff000) << 32;
>>> -		val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
>>> +		if (!ggtt_view)
>>> +			ggtt_view = &i915_ggtt_view_normal;
>>> +
>>> +		val =
>>> (uint64_t)((i915_gem_obj_ggtt_offset_view((obj), ggtt_view)
>>> +				  + size - 4096) & 0xfffff000) <<
>>> 32;
>>> +		val |= i915_gem_obj_ggtt_offset_view((obj),
>>> ggtt_view) & 0xfffff000; +
>>
>> Looks like the code can be setting up a fence with a rotated view
>> GGTT address which looks wrong? Is this really what is wanted and why?
>>
>> Regards,
>>
>> Tvrtko
> Well, i915_gem_obj_ggtt_offset() always calls
> i915_gem_obj_ggtt_offset_view() with the default normal view type which
> I suppose is incorrect right? When a rotated view is passed from
> i915_gem_object_pin_to_display_plane(), i915_gem_obj_ggtt_offset_view()
> will not be able to find the associated vma.

I think it is correct since for setting up fences we do want the normal 
view. What would you do that in userspace with fenced rotated view and 
would it even work? And it wouldn't even be predictable which type of 
view you got for your mmap since it would depend on view instantiation 
ordering, no?

I think what might work is that we skip fence creation on rotated view 
pinning, and instead do it when mmap is requested, instantiating a 
normal view at that time if not present.

Regards,

Tvrtko
Vivek Kasireddy Sept. 16, 2015, 1:38 a.m. UTC | #6
Hi Tvrtko,
On Tue, 15 Sep 2015 10:29:27 +0100
Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> wrote:

> 
> On 09/15/2015 03:09 AM, Vivek Kasireddy wrote:
> > On Mon, 14 Sep 2015 10:08:19 +0100
> > Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> wrote:
> >
> >>
> >> Hi,
> >>
> >> On 09/12/2015 02:44 AM, Vivek Kasireddy wrote:
> >>> From: Vivek Kasireddy <vivek.kasireddy@intel.com>
> >>>
> >>> Currently, fb objects with rotated views are ignored while
> >>> pinning. Therefore, include the rotated view type and use the
> >>> view size instead of the object's size to determine if it is
> >>> fenceable. And, look at the view and its offset while writing and
> >>> pinning to the fence registers.
> >>
> >> I didn't figure out from the commit message if something is broken
> >> or?
> >>
> >> AFAIR rotated views deliberately skip on fencing since rotated view
> >> has shuffled pages in memory so it would be a weird view for
> >> userspace to handle.
> >
> > Hi Tvrtko,
> > I apologize for the short and ambiguous commit message.
> > As I mentioned in my other reply to Chris, the reason for this
> > patch is because of this:
> > 	if (WARN_ON(!obj->map_and_fenceable))
> > 		return -EINVAL;
> > inside i915_find_fence_reg(). I am trying to enable 90 degree
> > rotation for the Weston compositor as part of which I need to
> > allocate and flip a Y-tiled fb obj. This fails because
> > i915_gem_object_do_pin() ignores
> 
> The use case itself has been exercised in general and it does work.
> 
> However I suspect you are using SET_TILING on the object to set it to
> Y tiled? That would explain i915_gem_object_get_fence trying to
> enable fencing.

Yes, I am using SET_TILING to set Y-tiling on the fb obj. 

> 
> This indeed looks like an omission in test coverage, needs a test
> case in kms_addfb_basic/addfb25 test group.
> 
> > the rotated view passed by i915_gem_object_pin_to_display_plane()
> > and hence obj->map_and_fenceable never gets set.
> >
> >>
> >> Especially this below:
> >>
> >>>    static void i965_write_fence_reg(struct drm_device *dev, int
> >>> reg,
> >>> -				 struct drm_i915_gem_object *obj)
> >>> +				 struct drm_i915_gem_object *obj,
> >>> +				 const struct i915_ggtt_view
> >>> *view) {
> >>>    	struct drm_i915_private *dev_priv = dev->dev_private;
> >>>    	int fence_reg;
> >>>    	int fence_pitch_shift;
> >>> +	const struct i915_ggtt_view *ggtt_view = view;
> >>>
> >>>    	if (INTEL_INFO(dev)->gen >= 6) {
> >>>    		fence_reg = FENCE_REG_SANDYBRIDGE_0;
> >>> @@ -95,9 +97,13 @@ static void i965_write_fence_reg(struct
> >>> drm_device *dev, int reg, size = (size / row_size) * row_size;
> >>>    		}
> >>>
> >>> -		val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) +
> >>> size - 4096) &
> >>> -				 0xfffff000) << 32;
> >>> -		val |= i915_gem_obj_ggtt_offset(obj) &
> >>> 0xfffff000;
> >>> +		if (!ggtt_view)
> >>> +			ggtt_view = &i915_ggtt_view_normal;
> >>> +
> >>> +		val =
> >>> (uint64_t)((i915_gem_obj_ggtt_offset_view((obj), ggtt_view)
> >>> +				  + size - 4096) & 0xfffff000) <<
> >>> 32;
> >>> +		val |= i915_gem_obj_ggtt_offset_view((obj),
> >>> ggtt_view) & 0xfffff000; +
> >>
> >> Looks like the code can be setting up a fence with a rotated view
> >> GGTT address which looks wrong? Is this really what is wanted and
> >> why?
> >>
> >> Regards,
> >>
> >> Tvrtko
> > Well, i915_gem_obj_ggtt_offset() always calls
> > i915_gem_obj_ggtt_offset_view() with the default normal view type
> > which I suppose is incorrect right? When a rotated view is passed
> > from i915_gem_object_pin_to_display_plane(),
> > i915_gem_obj_ggtt_offset_view() will not be able to find the
> > associated vma.
> 
> I think it is correct since for setting up fences we do want the
> normal view. What would you do that in userspace with fenced rotated
> view and would it even work? And it wouldn't even be predictable
> which type of view you got for your mmap since it would depend on
> view instantiation ordering, no?
> 
> I think what might work is that we skip fence creation on rotated
> view pinning, and instead do it when mmap is requested, instantiating
> a normal view at that time if not present.

Skipping fence installation for fb objects with rotated views seems to
fix the issue I am seeing. I'll send out a new patch that just does
this.


Thanks,
Vivek

> 
> Regards,
> 
> Tvrtko
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index df37e88..9bd8d11 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3101,10 +3101,12 @@  i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
 }
 
 /* i915_gem_fence.c */
-int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
+int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
+				      const struct i915_ggtt_view *view);
 int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
 
-bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj);
+bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj,
+				     const struct i915_ggtt_view *view);
 void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj);
 
 void i915_gem_restore_fences(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 41263cd..c0c3441 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1789,7 +1789,7 @@  int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 	if (ret)
 		goto unpin;
 
-	ret = i915_gem_object_get_fence(obj);
+	ret = i915_gem_object_get_fence(obj, NULL);
 	if (ret)
 		goto unpin;
 
@@ -4054,16 +4054,19 @@  i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
 			return ret;
 	}
 
-	if (ggtt_view && ggtt_view->type == I915_GGTT_VIEW_NORMAL &&
+	if (ggtt_view && (ggtt_view->type == I915_GGTT_VIEW_NORMAL ||
+	    ggtt_view->type == I915_GGTT_VIEW_ROTATED) &&
 	    (bound ^ vma->bound) & GLOBAL_BIND) {
 		bool mappable, fenceable;
-		u32 fence_size, fence_alignment;
+		u32 fence_size, fence_alignment, view_size;
+
+		view_size = i915_ggtt_view_size(obj, ggtt_view);
 
 		fence_size = i915_gem_get_gtt_size(obj->base.dev,
-						   obj->base.size,
+						   view_size,
 						   obj->tiling_mode);
 		fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
-							     obj->base.size,
+							     view_size,
 							     obj->tiling_mode,
 							     true);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index a953d49..1566f88 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -608,11 +608,11 @@  i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
 	entry->flags |= __EXEC_OBJECT_HAS_PIN;
 
 	if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
-		ret = i915_gem_object_get_fence(obj);
+		ret = i915_gem_object_get_fence(obj, NULL);
 		if (ret)
 			return ret;
 
-		if (i915_gem_object_pin_fence(obj))
+		if (i915_gem_object_pin_fence(obj, NULL))
 			entry->flags |= __EXEC_OBJECT_HAS_FENCE;
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
index 6077dff..336ebee 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence.c
@@ -56,11 +56,13 @@ 
  */
 
 static void i965_write_fence_reg(struct drm_device *dev, int reg,
-				 struct drm_i915_gem_object *obj)
+				 struct drm_i915_gem_object *obj,
+				 const struct i915_ggtt_view *view)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int fence_reg;
 	int fence_pitch_shift;
+	const struct i915_ggtt_view *ggtt_view = view;
 
 	if (INTEL_INFO(dev)->gen >= 6) {
 		fence_reg = FENCE_REG_SANDYBRIDGE_0;
@@ -95,9 +97,13 @@  static void i965_write_fence_reg(struct drm_device *dev, int reg,
 			size = (size / row_size) * row_size;
 		}
 
-		val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) &
-				 0xfffff000) << 32;
-		val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
+		if (!ggtt_view)
+			ggtt_view = &i915_ggtt_view_normal;
+
+		val = (uint64_t)((i915_gem_obj_ggtt_offset_view((obj), ggtt_view)
+				  + size - 4096) & 0xfffff000) << 32;
+		val |= i915_gem_obj_ggtt_offset_view((obj), ggtt_view) & 0xfffff000;
+
 		val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift;
 		if (obj->tiling_mode == I915_TILING_Y)
 			val |= 1 << I965_FENCE_TILING_Y_SHIFT;
@@ -196,7 +202,8 @@  inline static bool i915_gem_object_needs_mb(struct drm_i915_gem_object *obj)
 }
 
 static void i915_gem_write_fence(struct drm_device *dev, int reg,
-				 struct drm_i915_gem_object *obj)
+				 struct drm_i915_gem_object *obj,
+				 const struct i915_ggtt_view *view)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -215,7 +222,7 @@  static void i915_gem_write_fence(struct drm_device *dev, int reg,
 	else if (IS_GEN3(dev))
 		i915_write_fence_reg(dev, reg, obj);
 	else if (INTEL_INFO(dev)->gen >= 4)
-		i965_write_fence_reg(dev, reg, obj);
+		i965_write_fence_reg(dev, reg, obj, view);
 
 	/* And similarly be paranoid that no direct access to this region
 	 * is reordered to before the fence is installed.
@@ -232,12 +239,13 @@  static inline int fence_number(struct drm_i915_private *dev_priv,
 
 static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
 					 struct drm_i915_fence_reg *fence,
-					 bool enable)
+					 bool enable,
+					 const struct i915_ggtt_view *view)
 {
 	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
 	int reg = fence_number(dev_priv, fence);
 
-	i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
+	i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL, view);
 
 	if (enable) {
 		obj->fence_reg = reg;
@@ -308,7 +316,7 @@  i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
 		return -EBUSY;
 
 	i915_gem_object_fence_lost(obj);
-	i915_gem_object_update_fence(obj, fence, false);
+	i915_gem_object_update_fence(obj, fence, false, NULL);
 
 	return 0;
 }
@@ -369,7 +377,8 @@  deadlock:
  * 0 on success, negative error code on failure.
  */
 int
-i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
+i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
+				const struct i915_ggtt_view *view)
 {
 	struct drm_device *dev = obj->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -414,7 +423,7 @@  i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
 	} else
 		return 0;
 
-	i915_gem_object_update_fence(obj, reg, enable);
+	i915_gem_object_update_fence(obj, reg, enable, view);
 
 	return 0;
 }
@@ -435,11 +444,18 @@  i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
  * True if the object has a fence, false otherwise.
  */
 bool
-i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
+i915_gem_object_pin_fence(struct drm_i915_gem_object *obj,
+				const struct i915_ggtt_view *view)
 {
 	if (obj->fence_reg != I915_FENCE_REG_NONE) {
 		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
-		struct i915_vma *ggtt_vma = i915_gem_obj_to_ggtt(obj);
+		const struct i915_vma *ggtt_vma;
+
+		if (view)
+			ggtt_vma = i915_gem_obj_to_ggtt_view(obj, view);
+		else
+			ggtt_vma = i915_gem_obj_to_ggtt_view(obj,
+					&i915_ggtt_view_normal);
 
 		WARN_ON(!ggtt_vma ||
 			dev_priv->fence_regs[obj->fence_reg].pin_count >
@@ -489,9 +505,10 @@  void i915_gem_restore_fences(struct drm_device *dev)
 		 */
 		if (reg->obj) {
 			i915_gem_object_update_fence(reg->obj, reg,
-						     reg->obj->tiling_mode);
+						     reg->obj->tiling_mode,
+						     NULL);
 		} else {
-			i915_gem_write_fence(dev, i, NULL);
+			i915_gem_write_fence(dev, i, NULL, NULL);
 		}
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 52fb3f2..b77074f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2357,7 +2357,7 @@  intel_pin_and_fence_fb_obj(struct drm_plane *plane,
 	 * framebuffer compression.  For simplicity, we always install
 	 * a fence as the cost is not that onerous.
 	 */
-	ret = i915_gem_object_get_fence(obj);
+	ret = i915_gem_object_get_fence(obj, &view);
 	if (ret == -EDEADLK) {
 		/*
 		 * -EDEADLK means there are no free fences
@@ -2372,7 +2372,7 @@  intel_pin_and_fence_fb_obj(struct drm_plane *plane,
 	} else if (ret)
 		goto err_unpin;
 
-	i915_gem_object_pin_fence(obj);
+	i915_gem_object_pin_fence(obj, &view);
 
 	dev_priv->mm.interruptible = true;
 	intel_runtime_pm_put(dev_priv);