Browse Source

drm/i915/overlay: Combine SWITCH_OFF into a single step

We can program the h/w to first wait on the flip and then switch off
without relying on s/w intervention. This removes the need for a double
step switch off, bringing much rejoicing.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Chris Wilson 15 years ago
parent
commit
8dfbc34031
2 changed files with 6 additions and 35 deletions
  1. 1 2
      drivers/gpu/drm/i915/intel_drv.h
  2. 5 33
      drivers/gpu/drm/i915/intel_overlay.c

+ 1 - 2
drivers/gpu/drm/i915/intel_drv.h

@@ -167,8 +167,7 @@ struct intel_overlay {
 #define HW_WEDGED		1
 #define NEEDS_WAIT_FOR_FLIP	2
 #define RELEASE_OLD_VID		3
-#define SWITCH_OFF_STAGE_1	4
-#define SWITCH_OFF_STAGE_2	5
+#define SWITCH_OFF		4
 };
 
 struct intel_crtc {

+ 5 - 33
drivers/gpu/drm/i915/intel_overlay.c

@@ -325,7 +325,6 @@ static int intel_overlay_off(struct intel_overlay *overlay)
 {
 	u32 flip_addr = overlay->flip_addr;
 	struct drm_device *dev = overlay->dev;
-	int ret;
 
 	BUG_ON(!overlay->active);
 
@@ -335,29 +334,18 @@ static int intel_overlay_off(struct intel_overlay *overlay)
 	 * of the hw. Do it in both cases */
 	flip_addr |= OFC_UPDATE;
 
+	BEGIN_LP_RING(6);
 	/* wait for overlay to go idle */
-	BEGIN_LP_RING(4);
 	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
 	OUT_RING(flip_addr);
 	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-	OUT_RING(MI_NOOP);
-	ADVANCE_LP_RING();
-
-	ret = intel_overlay_do_wait_request(overlay, true,
-					    SWITCH_OFF_STAGE_1);
-	if (ret)
-		return ret;
-
 	/* turn overlay off */
-	BEGIN_LP_RING(4);
 	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
 	OUT_RING(flip_addr);
 	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-	OUT_RING(MI_NOOP);
 	ADVANCE_LP_RING();
 
-	return intel_overlay_do_wait_request(overlay, true,
-					     SWITCH_OFF_STAGE_2);
+	return intel_overlay_do_wait_request(overlay, true, SWITCH_OFF);
 }
 
 static void intel_overlay_off_tail(struct intel_overlay *overlay)
@@ -383,9 +371,8 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
 					 bool interruptible)
 {
 	struct drm_device *dev = overlay->dev;
-	struct drm_gem_object *obj;
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	u32 flip_addr;
+	struct drm_gem_object *obj;
 	int ret;
 
 	if (overlay->hw_wedged == HW_WEDGED)
@@ -404,25 +391,10 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
 		overlay->old_vid_bo = NULL;
 		break;
 
-	case SWITCH_OFF_STAGE_1:
-		flip_addr = overlay->flip_addr;
-		flip_addr |= OFC_UPDATE;
-
-		BEGIN_LP_RING(4);
-		OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
-		OUT_RING(flip_addr);
-		OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-		OUT_RING(MI_NOOP);
-		ADVANCE_LP_RING();
-
-		ret = intel_overlay_do_wait_request(overlay, interruptible,
-						    SWITCH_OFF_STAGE_2);
-		if (ret)
-			return ret;
-
-	case SWITCH_OFF_STAGE_2:
+	case SWITCH_OFF:
 		intel_overlay_off_tail(overlay);
 		break;
+
 	default:
 		BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
 	}