#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)
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 */
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,
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);
{
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;
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;
}