aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_overlay.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-02-21 09:43:56 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2011-02-22 10:56:25 -0500
commitce453d81cb0397aa7d5148984f51907e14072d74 (patch)
tree28545a19bf61f047671d17c96d33643a83f3c43c /drivers/gpu/drm/i915/intel_overlay.c
parent8408c282f0cf34ee166df5f842f2861d245407fd (diff)
drm/i915: Use a device flag for non-interruptible phases
The code paths for modesetting are growing in complexity as we may need to move the buffers around in order to fit the scanout in the aperture. Therefore we face a choice as to whether to thread the interruptible status through the entire pinning and unbinding code paths or to add a flag to the device when we may not be interrupted by a signal. This does the latter and so fixes a few instances of modesetting failures under stress. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_overlay.c')
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 50bc865139aa..a670c006982e 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -213,7 +213,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
213 213
214static int intel_overlay_do_wait_request(struct intel_overlay *overlay, 214static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
215 struct drm_i915_gem_request *request, 215 struct drm_i915_gem_request *request,
216 bool interruptible,
217 void (*tail)(struct intel_overlay *)) 216 void (*tail)(struct intel_overlay *))
218{ 217{
219 struct drm_device *dev = overlay->dev; 218 struct drm_device *dev = overlay->dev;
@@ -228,8 +227,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
228 } 227 }
229 overlay->last_flip_req = request->seqno; 228 overlay->last_flip_req = request->seqno;
230 overlay->flip_tail = tail; 229 overlay->flip_tail = tail;
231 ret = i915_wait_request(LP_RING(dev_priv), 230 ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req);
232 overlay->last_flip_req, true);
233 if (ret) 231 if (ret)
234 return ret; 232 return ret;
235 233
@@ -321,7 +319,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
321 OUT_RING(MI_NOOP); 319 OUT_RING(MI_NOOP);
322 ADVANCE_LP_RING(); 320 ADVANCE_LP_RING();
323 321
324 ret = intel_overlay_do_wait_request(overlay, request, true, NULL); 322 ret = intel_overlay_do_wait_request(overlay, request, NULL);
325out: 323out:
326 if (pipe_a_quirk) 324 if (pipe_a_quirk)
327 i830_deactivate_pipe_a(dev); 325 i830_deactivate_pipe_a(dev);
@@ -400,8 +398,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
400} 398}
401 399
402/* overlay needs to be disabled in OCMD reg */ 400/* overlay needs to be disabled in OCMD reg */
403static int intel_overlay_off(struct intel_overlay *overlay, 401static int intel_overlay_off(struct intel_overlay *overlay)
404 bool interruptible)
405{ 402{
406 struct drm_device *dev = overlay->dev; 403 struct drm_device *dev = overlay->dev;
407 struct drm_i915_private *dev_priv = dev->dev_private; 404 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -436,14 +433,13 @@ static int intel_overlay_off(struct intel_overlay *overlay,
436 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 433 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
437 ADVANCE_LP_RING(); 434 ADVANCE_LP_RING();
438 435
439 return intel_overlay_do_wait_request(overlay, request, interruptible, 436 return intel_overlay_do_wait_request(overlay, request,
440 intel_overlay_off_tail); 437 intel_overlay_off_tail);
441} 438}
442 439
443/* recover from an interruption due to a signal 440/* recover from an interruption due to a signal
444 * We have to be careful not to repeat work forever an make forward progess. */ 441 * We have to be careful not to repeat work forever an make forward progess. */
445static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, 442static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
446 bool interruptible)
447{ 443{
448 struct drm_device *dev = overlay->dev; 444 struct drm_device *dev = overlay->dev;
449 drm_i915_private_t *dev_priv = dev->dev_private; 445 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -452,8 +448,7 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
452 if (overlay->last_flip_req == 0) 448 if (overlay->last_flip_req == 0)
453 return 0; 449 return 0;
454 450
455 ret = i915_wait_request(LP_RING(dev_priv), 451 ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req);
456 overlay->last_flip_req, interruptible);
457 if (ret) 452 if (ret)
458 return ret; 453 return ret;
459 454
@@ -498,7 +493,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
498 OUT_RING(MI_NOOP); 493 OUT_RING(MI_NOOP);
499 ADVANCE_LP_RING(); 494 ADVANCE_LP_RING();
500 495
501 ret = intel_overlay_do_wait_request(overlay, request, true, 496 ret = intel_overlay_do_wait_request(overlay, request,
502 intel_overlay_release_old_vid_tail); 497 intel_overlay_release_old_vid_tail);
503 if (ret) 498 if (ret)
504 return ret; 499 return ret;
@@ -867,8 +862,7 @@ out_unpin:
867 return ret; 862 return ret;
868} 863}
869 864
870int intel_overlay_switch_off(struct intel_overlay *overlay, 865int intel_overlay_switch_off(struct intel_overlay *overlay)
871 bool interruptible)
872{ 866{
873 struct overlay_registers *regs; 867 struct overlay_registers *regs;
874 struct drm_device *dev = overlay->dev; 868 struct drm_device *dev = overlay->dev;
@@ -877,7 +871,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay,
877 BUG_ON(!mutex_is_locked(&dev->struct_mutex)); 871 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
878 BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); 872 BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
879 873
880 ret = intel_overlay_recover_from_interrupt(overlay, interruptible); 874 ret = intel_overlay_recover_from_interrupt(overlay);
881 if (ret != 0) 875 if (ret != 0)
882 return ret; 876 return ret;
883 877
@@ -892,7 +886,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay,
892 regs->OCMD = 0; 886 regs->OCMD = 0;
893 intel_overlay_unmap_regs(overlay, regs); 887 intel_overlay_unmap_regs(overlay, regs);
894 888
895 ret = intel_overlay_off(overlay, interruptible); 889 ret = intel_overlay_off(overlay);
896 if (ret != 0) 890 if (ret != 0)
897 return ret; 891 return ret;
898 892
@@ -1134,7 +1128,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1134 mutex_lock(&dev->mode_config.mutex); 1128 mutex_lock(&dev->mode_config.mutex);
1135 mutex_lock(&dev->struct_mutex); 1129 mutex_lock(&dev->struct_mutex);
1136 1130
1137 ret = intel_overlay_switch_off(overlay, true); 1131 ret = intel_overlay_switch_off(overlay);
1138 1132
1139 mutex_unlock(&dev->struct_mutex); 1133 mutex_unlock(&dev->struct_mutex);
1140 mutex_unlock(&dev->mode_config.mutex); 1134 mutex_unlock(&dev->mode_config.mutex);
@@ -1170,13 +1164,13 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1170 goto out_unlock; 1164 goto out_unlock;
1171 } 1165 }
1172 1166
1173 ret = intel_overlay_recover_from_interrupt(overlay, true); 1167 ret = intel_overlay_recover_from_interrupt(overlay);
1174 if (ret != 0) 1168 if (ret != 0)
1175 goto out_unlock; 1169 goto out_unlock;
1176 1170
1177 if (overlay->crtc != crtc) { 1171 if (overlay->crtc != crtc) {
1178 struct drm_display_mode *mode = &crtc->base.mode; 1172 struct drm_display_mode *mode = &crtc->base.mode;
1179 ret = intel_overlay_switch_off(overlay, true); 1173 ret = intel_overlay_switch_off(overlay);
1180 if (ret != 0) 1174 if (ret != 0)
1181 goto out_unlock; 1175 goto out_unlock;
1182 1176