aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_overlay.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-10-27 07:45:26 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-27 18:26:34 -0400
commite1f99ce6cac3b6a95551642be5ddb5d9c46bea76 (patch)
treefb5152a582fc5b6c190287d9c90d57ca415d6f9d /drivers/gpu/drm/i915/intel_overlay.c
parent78501eac34f372bfbeb4e1d9de688c13efa916f6 (diff)
drm/i915: Propagate errors from writing to ringbuffer
Preparing the ringbuffer for adding new commands can fail (a timeout whilst waiting for the GPU to catch up and free some space). So check for any potential error before overwriting HEAD with new commands, and propagate that error back to the user where possible. 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.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index afb96d25219a..78fa6a249964 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -289,6 +289,7 @@ i830_deactivate_pipe_a(struct drm_device *dev)
289static int intel_overlay_on(struct intel_overlay *overlay) 289static int intel_overlay_on(struct intel_overlay *overlay)
290{ 290{
291 struct drm_device *dev = overlay->dev; 291 struct drm_device *dev = overlay->dev;
292 struct drm_i915_private *dev_priv = dev->dev_private;
292 struct drm_i915_gem_request *request; 293 struct drm_i915_gem_request *request;
293 int pipe_a_quirk = 0; 294 int pipe_a_quirk = 0;
294 int ret; 295 int ret;
@@ -308,7 +309,12 @@ static int intel_overlay_on(struct intel_overlay *overlay)
308 goto out; 309 goto out;
309 } 310 }
310 311
311 BEGIN_LP_RING(4); 312 ret = BEGIN_LP_RING(4);
313 if (ret) {
314 kfree(request);
315 goto out;
316 }
317
312 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); 318 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
313 OUT_RING(overlay->flip_addr | OFC_UPDATE); 319 OUT_RING(overlay->flip_addr | OFC_UPDATE);
314 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 320 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
@@ -332,6 +338,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
332 struct drm_i915_gem_request *request; 338 struct drm_i915_gem_request *request;
333 u32 flip_addr = overlay->flip_addr; 339 u32 flip_addr = overlay->flip_addr;
334 u32 tmp; 340 u32 tmp;
341 int ret;
335 342
336 BUG_ON(!overlay->active); 343 BUG_ON(!overlay->active);
337 344
@@ -347,7 +354,11 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
347 if (tmp & (1 << 17)) 354 if (tmp & (1 << 17))
348 DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); 355 DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
349 356
350 BEGIN_LP_RING(2); 357 ret = BEGIN_LP_RING(2);
358 if (ret) {
359 kfree(request);
360 return ret;
361 }
351 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 362 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
352 OUT_RING(flip_addr); 363 OUT_RING(flip_addr);
353 ADVANCE_LP_RING(); 364 ADVANCE_LP_RING();
@@ -389,8 +400,10 @@ static int intel_overlay_off(struct intel_overlay *overlay,
389 bool interruptible) 400 bool interruptible)
390{ 401{
391 struct drm_device *dev = overlay->dev; 402 struct drm_device *dev = overlay->dev;
403 struct drm_i915_private *dev_priv = dev->dev_private;
392 u32 flip_addr = overlay->flip_addr; 404 u32 flip_addr = overlay->flip_addr;
393 struct drm_i915_gem_request *request; 405 struct drm_i915_gem_request *request;
406 int ret;
394 407
395 BUG_ON(!overlay->active); 408 BUG_ON(!overlay->active);
396 409
@@ -404,7 +417,11 @@ static int intel_overlay_off(struct intel_overlay *overlay,
404 * of the hw. Do it in both cases */ 417 * of the hw. Do it in both cases */
405 flip_addr |= OFC_UPDATE; 418 flip_addr |= OFC_UPDATE;
406 419
407 BEGIN_LP_RING(6); 420 ret = BEGIN_LP_RING(6);
421 if (ret) {
422 kfree(request);
423 return ret;
424 }
408 /* wait for overlay to go idle */ 425 /* wait for overlay to go idle */
409 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 426 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
410 OUT_RING(flip_addr); 427 OUT_RING(flip_addr);
@@ -467,7 +484,12 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
467 if (request == NULL) 484 if (request == NULL)
468 return -ENOMEM; 485 return -ENOMEM;
469 486
470 BEGIN_LP_RING(2); 487 ret = BEGIN_LP_RING(2);
488 if (ret) {
489 kfree(request);
490 return ret;
491 }
492
471 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 493 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
472 OUT_RING(MI_NOOP); 494 OUT_RING(MI_NOOP);
473 ADVANCE_LP_RING(); 495 ADVANCE_LP_RING();