Skip to content

Commit

Permalink
drm/i915: Initialize hardware semaphore state on ring init
Browse files Browse the repository at this point in the history
Hardware status page needs to have proper seqno set
as our initial seqno can be arbitrary. If initial seqno is close
to wrap boundary on init and i915_seqno_passed() (31bit space)
refers to hw status page which contains zero, errorneous result
will be returned.

v2: clear mboxes and set hws page directly instead of going
through rings. Suggested by Chris Wilson.

v3: hws needs to be updated for all gens. Noticed by Chris
Wilson.

References: https://bugs.freedesktop.org/show_bug.cgi?id=58230
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Mika Kuoppala authored and Daniel Vetter committed Dec 19, 2012
1 parent b70ec5b commit f7e98ad
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 21 deletions.
8 changes: 3 additions & 5 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1954,9 +1954,7 @@ i915_gem_handle_seqno_wrap(struct drm_device *dev)

/* Finally reset hw state */
for_each_ring(ring, dev_priv, i) {
ret = intel_ring_handle_seqno_wrap(ring);
if (ret)
return ret;
intel_ring_init_seqno(ring, 0);

for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++)
ring->sync_seqno[j] = 0;
Expand Down Expand Up @@ -3935,6 +3933,8 @@ i915_gem_init_hw(struct drm_device *dev)

i915_gem_init_swizzling(dev);

dev_priv->next_seqno = dev_priv->last_seqno = (u32)~0 - 0x1000;

ret = intel_init_render_ring_buffer(dev);
if (ret)
return ret;
Expand All @@ -3951,8 +3951,6 @@ i915_gem_init_hw(struct drm_device *dev)
goto cleanup_bsd_ring;
}

dev_priv->next_seqno = (u32)-1 - 0x1000;

/*
* XXX: There was some w/a described somewhere suggesting loading
* contexts before PPGTT.
Expand Down
24 changes: 9 additions & 15 deletions drivers/gpu/drm/i915/intel_ringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
if (IS_I830(ring->dev) || IS_845G(ring->dev))
ring->effective_size -= 128;

intel_ring_init_seqno(ring, dev_priv->last_seqno);

return 0;

err_unmap:
Expand Down Expand Up @@ -1431,26 +1433,18 @@ int intel_ring_begin(struct intel_ring_buffer *ring,
return __intel_ring_begin(ring, num_dwords * sizeof(uint32_t));
}

int intel_ring_handle_seqno_wrap(struct intel_ring_buffer *ring)
void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno)
{
int ret;
struct drm_i915_private *dev_priv = ring->dev->dev_private;

BUG_ON(ring->outstanding_lazy_request);

if (INTEL_INFO(ring->dev)->gen < 6)
return 0;

ret = __intel_ring_begin(ring, 6 * sizeof(uint32_t));
if (ret)
return ret;

/* Leaving a stale, pre-wrap seqno behind in the mboxes will result in
* post-wrap semaphore waits completing immediately. Clear them. */
update_mboxes(ring, ring->signal_mbox[0]);
update_mboxes(ring, ring->signal_mbox[1]);
intel_ring_advance(ring);
if (INTEL_INFO(ring->dev)->gen >= 6) {
I915_WRITE(RING_SYNC_0(ring->mmio_base), 0);
I915_WRITE(RING_SYNC_1(ring->mmio_base), 0);
}

return 0;
ring->set_seqno(ring, seqno);
}

void intel_ring_advance(struct intel_ring_buffer *ring)
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/intel_ringbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring,
}
void intel_ring_advance(struct intel_ring_buffer *ring);
int __must_check intel_ring_idle(struct intel_ring_buffer *ring);
int __must_check intel_ring_handle_seqno_wrap(struct intel_ring_buffer *ring);
void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno);
int intel_ring_flush_all_caches(struct intel_ring_buffer *ring);
int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring);

Expand Down

0 comments on commit f7e98ad

Please sign in to comment.