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

Commit 0d9bdd88 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Convert intel_overlay to request tracking

intel_overlay already tracks its last flip request, along with action to
take after its completion. Refactor intel_overlay to reuse the common
i915_gem_active tracker.

v2: Now using i915_gem_retire_fn typedef

References: https://bugs.freedesktop.org/show_bug.cgi?id=93730
References: https://bugs.freedesktop.org/show_bug.cgi?id=96851


Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470293567-10811-18-git-send-email-chris@chris-wilson.co.uk
parent 675d9ad7
Loading
Loading
Loading
Loading
+34 −48
Original line number Original line Diff line number Diff line
@@ -183,8 +183,7 @@ struct intel_overlay {
	u32 flip_addr;
	u32 flip_addr;
	struct drm_i915_gem_object *reg_bo;
	struct drm_i915_gem_object *reg_bo;
	/* flip handling */
	/* flip handling */
	struct drm_i915_gem_request *last_flip_req;
	struct i915_gem_active last_flip;
	void (*flip_tail)(struct intel_overlay *);
};
};


static struct overlay_registers __iomem *
static struct overlay_registers __iomem *
@@ -210,23 +209,24 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
		io_mapping_unmap(regs);
		io_mapping_unmap(regs);
}
}


static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
static void intel_overlay_submit_request(struct intel_overlay *overlay,
					 struct drm_i915_gem_request *req,
					 struct drm_i915_gem_request *req,
					 void (*tail)(struct intel_overlay *))
					 i915_gem_retire_fn retire)
{
{
	int ret;
	GEM_BUG_ON(i915_gem_active_peek(&overlay->last_flip,

					&overlay->i915->drm.struct_mutex));
	WARN_ON(overlay->last_flip_req);
	overlay->last_flip.retire = retire;
	i915_gem_request_assign(&overlay->last_flip_req, req);
	i915_gem_active_set(&overlay->last_flip, req);
	i915_add_request(req);
	i915_add_request(req);
}


	overlay->flip_tail = tail;
static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
	ret = i915_wait_request(overlay->last_flip_req);
					 struct drm_i915_gem_request *req,
	if (ret)
					 i915_gem_retire_fn retire)
		return ret;
{

	intel_overlay_submit_request(overlay, req, retire);
	i915_gem_request_assign(&overlay->last_flip_req, NULL);
	return i915_gem_active_retire(&overlay->last_flip,
	return 0;
				      &overlay->i915->drm.struct_mutex);
}
}


static struct drm_i915_gem_request *alloc_request(struct intel_overlay *overlay)
static struct drm_i915_gem_request *alloc_request(struct intel_overlay *overlay)
@@ -306,25 +306,32 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
	intel_ring_emit(ring, flip_addr);
	intel_ring_emit(ring, flip_addr);
	intel_ring_advance(ring);
	intel_ring_advance(ring);


	WARN_ON(overlay->last_flip_req);
	intel_overlay_submit_request(overlay, req, NULL);
	i915_gem_request_assign(&overlay->last_flip_req, req);
	i915_add_request(req);


	return 0;
	return 0;
}
}


static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
					       struct drm_i915_gem_request *req)
{
{
	struct intel_overlay *overlay =
		container_of(active, typeof(*overlay), last_flip);
	struct drm_i915_gem_object *obj = overlay->old_vid_bo;
	struct drm_i915_gem_object *obj = overlay->old_vid_bo;


	i915_gem_track_fb(obj, NULL,
			  INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));

	i915_gem_object_ggtt_unpin(obj);
	i915_gem_object_ggtt_unpin(obj);
	i915_gem_object_put(obj);
	i915_gem_object_put(obj);


	overlay->old_vid_bo = NULL;
	overlay->old_vid_bo = NULL;
}
}


static void intel_overlay_off_tail(struct intel_overlay *overlay)
static void intel_overlay_off_tail(struct i915_gem_active *active,
				   struct drm_i915_gem_request *req)
{
{
	struct intel_overlay *overlay =
		container_of(active, typeof(*overlay), last_flip);
	struct drm_i915_gem_object *obj = overlay->vid_bo;
	struct drm_i915_gem_object *obj = overlay->vid_bo;


	/* never have the overlay hw on without showing a frame */
	/* never have the overlay hw on without showing a frame */
@@ -387,27 +394,16 @@ static int intel_overlay_off(struct intel_overlay *overlay)
	}
	}
	intel_ring_advance(ring);
	intel_ring_advance(ring);


	return intel_overlay_do_wait_request(overlay, req, intel_overlay_off_tail);
	return intel_overlay_do_wait_request(overlay, req,
					     intel_overlay_off_tail);
}
}


/* recover from an interruption due to a signal
/* recover from an interruption due to a signal
 * We have to be careful not to repeat work forever an make forward progess. */
 * We have to be careful not to repeat work forever an make forward progess. */
static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
{
{
	int ret;
	return i915_gem_active_retire(&overlay->last_flip,

				      &overlay->i915->drm.struct_mutex);
	if (overlay->last_flip_req == NULL)
		return 0;

	ret = i915_wait_request(overlay->last_flip_req);
	if (ret)
		return ret;

	if (overlay->flip_tail)
		overlay->flip_tail(overlay);

	i915_gem_request_assign(&overlay->last_flip_req, NULL);
	return 0;
}
}


/* Wait for pending overlay flip and release old frame.
/* Wait for pending overlay flip and release old frame.
@@ -452,13 +448,9 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
						    intel_overlay_release_old_vid_tail);
						    intel_overlay_release_old_vid_tail);
		if (ret)
		if (ret)
			return ret;
			return ret;
	}
	} else

		intel_overlay_release_old_vid_tail(&overlay->last_flip, NULL);
	intel_overlay_release_old_vid_tail(overlay);



	i915_gem_track_fb(overlay->old_vid_bo, NULL,
			  INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
	return 0;
	return 0;
}
}


@@ -471,7 +463,6 @@ void intel_overlay_reset(struct drm_i915_private *dev_priv)


	intel_overlay_release_old_vid(overlay);
	intel_overlay_release_old_vid(overlay);


	overlay->last_flip_req = NULL;
	overlay->old_xscale = 0;
	overlay->old_xscale = 0;
	overlay->old_yscale = 0;
	overlay->old_yscale = 0;
	overlay->crtc = NULL;
	overlay->crtc = NULL;
@@ -882,12 +873,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
	iowrite32(0, &regs->OCMD);
	iowrite32(0, &regs->OCMD);
	intel_overlay_unmap_regs(overlay, regs);
	intel_overlay_unmap_regs(overlay, regs);


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

	intel_overlay_off_tail(overlay);
	return 0;
}
}


static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,