Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5dcdbcb0 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/overlay: Pass interruptible to switch_off()



During DPMS we currently do not want the overlay code to be
interruptible, so pass that information down and only take the
uninterrruptible paths.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 106dadac
Loading
Loading
Loading
Loading
+6 −22
Original line number Diff line number Diff line
@@ -2223,33 +2223,17 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)

static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
{
	struct intel_overlay *overlay;
	int ret;

	if (!enable && intel_crtc->overlay) {
		overlay = intel_crtc->overlay;
		mutex_lock(&overlay->dev->struct_mutex);
		for (;;) {
			ret = intel_overlay_switch_off(overlay);
			if (ret == 0)
				break;
		struct intel_overlay *overlay = intel_crtc->overlay;

			ret = intel_overlay_recover_from_interrupt(overlay, 0);
			if (ret != 0) {
				/* overlay doesn't react anymore. Usually
				 * results in a black screen and an unkillable
				 * X server. */
				BUG();
				overlay->hw_wedged = HW_WEDGED;
				break;
			}
		}
		mutex_lock(&overlay->dev->struct_mutex);
		(void) intel_overlay_switch_off(overlay, false);
		mutex_unlock(&overlay->dev->struct_mutex);
	}
	/* Let userspace switch the overlay on again. In most cases userspace
	 * has to recompute where to put it anyway. */

	return;
	/* Let userspace switch the overlay on again. In most cases userspace
	 * has to recompute where to put it anyway.
	 */
}

static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
+2 −3
Original line number Diff line number Diff line
@@ -287,8 +287,7 @@ extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);

extern void intel_setup_overlay(struct drm_device *dev);
extern void intel_cleanup_overlay(struct drm_device *dev);
extern int intel_overlay_switch_off(struct intel_overlay *overlay);
extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
extern int intel_overlay_switch_off(struct intel_overlay *overlay,
				    bool interruptible);
extern int intel_overlay_put_image(struct drm_device *dev, void *data,
				   struct drm_file *file_priv);
+13 −10
Original line number Diff line number Diff line
@@ -365,7 +365,8 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
}

/* overlay needs to be disabled in OCMD reg */
static int intel_overlay_off(struct intel_overlay *overlay)
static int intel_overlay_off(struct intel_overlay *overlay,
			     bool interruptible)
{
	struct drm_device *dev = overlay->dev;
	u32 flip_addr = overlay->flip_addr;
@@ -394,7 +395,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
	ADVANCE_LP_RING();

	return intel_overlay_do_wait_request(overlay, request, true,
	return intel_overlay_do_wait_request(overlay, request, interruptible,
					     SWITCH_OFF);
}

@@ -427,7 +428,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)

/* 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,
static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
						bool interruptible)
{
	struct drm_device *dev = overlay->dev;
@@ -855,17 +856,19 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
	return ret;
}

int intel_overlay_switch_off(struct intel_overlay *overlay)
int intel_overlay_switch_off(struct intel_overlay *overlay,
			     bool interruptible)
{
	int ret;
	struct overlay_registers *regs;
	struct drm_device *dev = overlay->dev;
	int ret;

	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);
		ret = intel_overlay_recover_from_interrupt(overlay,
							   interruptible);
		if (ret != 0)
			return ret;
	}
@@ -881,7 +884,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
	regs->OCMD = 0;
	intel_overlay_unmap_regs(overlay, regs);

	ret = intel_overlay_off(overlay);
	ret = intel_overlay_off(overlay, interruptible);
	if (ret != 0)
		return ret;

@@ -1097,7 +1100,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
		mutex_lock(&dev->mode_config.mutex);
		mutex_lock(&dev->struct_mutex);

		ret = intel_overlay_switch_off(overlay);
		ret = intel_overlay_switch_off(overlay, true);

		mutex_unlock(&dev->struct_mutex);
		mutex_unlock(&dev->mode_config.mutex);
@@ -1135,7 +1138,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,

	if (overlay->crtc != crtc) {
		struct drm_display_mode *mode = &crtc->base.mode;
		ret = intel_overlay_switch_off(overlay);
		ret = intel_overlay_switch_off(overlay, true);
		if (ret != 0)
			goto out_unlock;