@@ -1091,6 +1091,7 @@ static bool intel_plane_uses_fence(const struct intel_plane_state *plane_state)
10911091
10921092struct i915_vma *
10931093intel_pin_and_fence_fb_obj (struct drm_framebuffer * fb ,
1094+ bool phys_cursor ,
10941095 const struct i915_ggtt_view * view ,
10951096 bool uses_fence ,
10961097 unsigned long * out_flags )
@@ -1099,14 +1100,19 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
10991100 struct drm_i915_private * dev_priv = to_i915 (dev );
11001101 struct drm_i915_gem_object * obj = intel_fb_obj (fb );
11011102 intel_wakeref_t wakeref ;
1103+ struct i915_gem_ww_ctx ww ;
11021104 struct i915_vma * vma ;
11031105 unsigned int pinctl ;
11041106 u32 alignment ;
1107+ int ret ;
11051108
11061109 if (drm_WARN_ON (dev , !i915_gem_object_is_framebuffer (obj )))
11071110 return ERR_PTR (- EINVAL );
11081111
1109- alignment = intel_surf_alignment (fb , 0 );
1112+ if (phys_cursor )
1113+ alignment = intel_cursor_alignment (dev_priv );
1114+ else
1115+ alignment = intel_surf_alignment (fb , 0 );
11101116 if (drm_WARN_ON (dev , alignment && !is_power_of_2 (alignment )))
11111117 return ERR_PTR (- EINVAL );
11121118
@@ -1141,14 +1147,26 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
11411147 if (HAS_GMCH (dev_priv ))
11421148 pinctl |= PIN_MAPPABLE ;
11431149
1144- vma = i915_gem_object_pin_to_display_plane (obj ,
1145- alignment , view , pinctl );
1146- if (IS_ERR (vma ))
1150+ i915_gem_ww_ctx_init (& ww , true);
1151+ retry :
1152+ ret = i915_gem_object_lock (obj , & ww );
1153+ if (!ret && phys_cursor )
1154+ ret = i915_gem_object_attach_phys (obj , alignment );
1155+ if (!ret )
1156+ ret = i915_gem_object_pin_pages (obj );
1157+ if (ret )
11471158 goto err ;
11481159
1149- if (uses_fence && i915_vma_is_map_and_fenceable (vma )) {
1150- int ret ;
1160+ if (!ret ) {
1161+ vma = i915_gem_object_pin_to_display_plane (obj , & ww , alignment ,
1162+ view , pinctl );
1163+ if (IS_ERR (vma )) {
1164+ ret = PTR_ERR (vma );
1165+ goto err_unpin ;
1166+ }
1167+ }
11511168
1169+ if (uses_fence && i915_vma_is_map_and_fenceable (vma )) {
11521170 /*
11531171 * Install a fence for tiled scan-out. Pre-i965 always needs a
11541172 * fence, whereas 965+ only requires a fence if using
@@ -1169,16 +1187,28 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
11691187 ret = i915_vma_pin_fence (vma );
11701188 if (ret != 0 && INTEL_GEN (dev_priv ) < 4 ) {
11711189 i915_vma_unpin (vma );
1172- vma = ERR_PTR (ret );
1173- goto err ;
1190+ goto err_unpin ;
11741191 }
1192+ ret = 0 ;
11751193
1176- if (ret == 0 && vma -> fence )
1194+ if (vma -> fence )
11771195 * out_flags |= PLANE_HAS_FENCE ;
11781196 }
11791197
11801198 i915_vma_get (vma );
1199+
1200+ err_unpin :
1201+ i915_gem_object_unpin_pages (obj );
11811202err :
1203+ if (ret == - EDEADLK ) {
1204+ ret = i915_gem_ww_ctx_backoff (& ww );
1205+ if (!ret )
1206+ goto retry ;
1207+ }
1208+ i915_gem_ww_ctx_fini (& ww );
1209+ if (ret )
1210+ vma = ERR_PTR (ret );
1211+
11821212 atomic_dec (& dev_priv -> gpu_error .pending_fb_pin );
11831213 intel_runtime_pm_put (& dev_priv -> runtime_pm , wakeref );
11841214 return vma ;
@@ -11333,19 +11363,11 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state)
1133311363 struct drm_i915_private * dev_priv = to_i915 (plane -> base .dev );
1133411364 struct drm_framebuffer * fb = plane_state -> hw .fb ;
1133511365 struct i915_vma * vma ;
11366+ bool phys_cursor =
11367+ plane -> id == PLANE_CURSOR &&
11368+ INTEL_INFO (dev_priv )-> display .cursor_needs_physical ;
1133611369
11337- if (plane -> id == PLANE_CURSOR &&
11338- INTEL_INFO (dev_priv )-> display .cursor_needs_physical ) {
11339- struct drm_i915_gem_object * obj = intel_fb_obj (fb );
11340- const int align = intel_cursor_alignment (dev_priv );
11341- int err ;
11342-
11343- err = i915_gem_object_attach_phys (obj , align );
11344- if (err )
11345- return err ;
11346- }
11347-
11348- vma = intel_pin_and_fence_fb_obj (fb ,
11370+ vma = intel_pin_and_fence_fb_obj (fb , phys_cursor ,
1134911371 & plane_state -> view ,
1135011372 intel_plane_uses_fence (plane_state ),
1135111373 & plane_state -> flags );
@@ -11437,13 +11459,8 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
1143711459 if (!obj )
1143811460 return 0 ;
1143911461
11440- ret = i915_gem_object_pin_pages (obj );
11441- if (ret )
11442- return ret ;
1144311462
1144411463 ret = intel_plane_pin_fb (new_plane_state );
11445-
11446- i915_gem_object_unpin_pages (obj );
1144711464 if (ret )
1144811465 return ret ;
1144911466
0 commit comments