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

Commit fca26bb4 authored by Mika Kuoppala's avatar Mika Kuoppala Committed by Daniel Vetter
Browse files

drm/i915: Introduce i915_gem_set_seqno()



This function can be used to set the driver's next_seqno
to arbitrary value.

i915_gem_set_seqno() will idle the gpu, retire outstanding
requests, clear the semaphore mailboxes and set the hardware
status page's seqno index.

Signed-off-by: default avatarMika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent ba1a7067
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -1479,8 +1479,8 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
	return (int32_t)(seq1 - seq2) >= 0;
	return (int32_t)(seq1 - seq2) >= 0;
}
}


extern int i915_gem_get_seqno(struct drm_device *dev, u32 *seqno);
int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno);

int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno);
int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);


+29 −3
Original line number Original line Diff line number Diff line
@@ -1926,7 +1926,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
}
}


static int
static int
i915_gem_handle_seqno_wrap(struct drm_device *dev)
i915_gem_init_seqno(struct drm_device *dev, u32 seqno)
{
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_ring_buffer *ring;
	struct intel_ring_buffer *ring;
@@ -1942,7 +1942,7 @@ i915_gem_handle_seqno_wrap(struct drm_device *dev)


	/* Finally reset hw state */
	/* Finally reset hw state */
	for_each_ring(ring, dev_priv, i) {
	for_each_ring(ring, dev_priv, i) {
		intel_ring_init_seqno(ring, 0);
		intel_ring_init_seqno(ring, seqno);


		for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++)
		for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++)
			ring->sync_seqno[j] = 0;
			ring->sync_seqno[j] = 0;
@@ -1951,6 +1951,32 @@ i915_gem_handle_seqno_wrap(struct drm_device *dev)
	return 0;
	return 0;
}
}


int i915_gem_set_seqno(struct drm_device *dev, u32 seqno)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	int ret;

	if (seqno == 0)
		return -EINVAL;

	/* HWS page needs to be set less than what we
	 * will inject to ring
	 */
	ret = i915_gem_init_seqno(dev, seqno - 1);
	if (ret)
		return ret;

	/* Carefully set the last_seqno value so that wrap
	 * detection still works
	 */
	dev_priv->next_seqno = seqno;
	dev_priv->last_seqno = seqno - 1;
	if (dev_priv->last_seqno == 0)
		dev_priv->last_seqno--;

	return 0;
}

int
int
i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
{
{
@@ -1958,7 +1984,7 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)


	/* reserve 0 for non-seqno */
	/* reserve 0 for non-seqno */
	if (dev_priv->next_seqno == 0) {
	if (dev_priv->next_seqno == 0) {
		int ret = i915_gem_handle_seqno_wrap(dev);
		int ret = i915_gem_init_seqno(dev, 0);
		if (ret)
		if (ret)
			return ret;
			return ret;