]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/gpu/drm/i915/intel_overlay.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[mv-sheeva.git] / drivers / gpu / drm / i915 / intel_overlay.c
index 972d715245be2ffecdd18290d569391890b36a33..2639591c72e97c74be2e6c4783b3be38f673ff04 100644 (file)
@@ -172,7 +172,7 @@ struct overlay_registers {
 #define OFC_UPDATE             0x1
 
 #define OVERLAY_NONPHYSICAL(dev) (IS_G33(dev) || IS_I965G(dev))
-#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IGDNG(dev))
+#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev))
 
 
 static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
@@ -286,16 +286,15 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay)
        RING_LOCALS;
 
        if (overlay->last_flip_req != 0) {
-               ret = i915_do_wait_request(dev, overlay->last_flip_req, 0);
-               if (ret != 0)
-                       return ret;
-
-               overlay->last_flip_req = 0;
+               ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+               if (ret == 0) {
+                       overlay->last_flip_req = 0;
 
-               tmp = I915_READ(ISR);
+                       tmp = I915_READ(ISR);
 
-               if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT))
-                       return 0;
+                       if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT))
+                               return 0;
+               }
        }
 
        /* synchronous slowpath */
@@ -376,12 +375,28 @@ static int intel_overlay_off(struct intel_overlay *overlay)
        if (ret != 0)
                return ret;
 
-       overlay->active = 0;
        overlay->hw_wedged = 0;
        overlay->last_flip_req = 0;
        return ret;
 }
 
+static void intel_overlay_off_tail(struct intel_overlay *overlay)
+{
+       struct drm_gem_object *obj;
+
+       /* never have the overlay hw on without showing a frame */
+       BUG_ON(!overlay->vid_bo);
+       obj = overlay->vid_bo->obj;
+
+       i915_gem_object_unpin(obj);
+       drm_gem_object_unreference(obj);
+       overlay->vid_bo = NULL;
+
+       overlay->crtc->overlay = NULL;
+       overlay->crtc = NULL;
+       overlay->active = 0;
+}
+
 /* recover from an interruption due to a signal
  * We have to be careful not to repeat work forever an make forward progess. */
 int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
@@ -439,19 +454,7 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
                                return ret;
 
                case SWITCH_OFF_STAGE_2:
-                       printk("switch off 2\n");
-
-                       BUG_ON(!overlay->vid_bo);
-                       obj = overlay->vid_bo->obj;
-
-                       i915_gem_object_unpin(obj);
-                       drm_gem_object_unreference(obj);
-                       overlay->vid_bo = NULL;
-
-                       overlay->crtc->overlay = NULL;
-                       overlay->crtc = NULL;
-
-                       overlay->active = 0;
+                       intel_overlay_off_tail(overlay);
                        break;
                default:
                        BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
@@ -834,18 +837,20 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
 {
        int ret;
        struct overlay_registers *regs;
-       struct drm_gem_object *obj;
        struct drm_device *dev = overlay->dev;
 
        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
        BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 
+       if (overlay->hw_wedged) {
+               ret = intel_overlay_recover_from_interrupt(overlay, 1);
+               if (ret != 0)
+                       return ret;
+       }
+
        if (!overlay->active)
                return 0;
 
-       if (overlay->hw_wedged)
-               return -EBUSY;
-
        ret = intel_overlay_release_old_vid(overlay);
        if (ret != 0)
                return ret;
@@ -858,16 +863,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
        if (ret != 0)
                return ret;
 
-       /* never have the overlay hw on without showing a frame */
-       BUG_ON(!overlay->vid_bo);
-       obj = overlay->vid_bo->obj;
-
-       i915_gem_object_unpin(obj);
-       drm_gem_object_unreference(obj);
-       overlay->vid_bo = NULL;
-
-       overlay->crtc->overlay = NULL;
-       overlay->crtc = NULL;
+       intel_overlay_off_tail(overlay);
 
        return 0;
 }