Skip to content

Commit

Permalink
drm/i915: Apply strongly ordered RCS breadcrumb to gen8/legacy
Browse files Browse the repository at this point in the history
For legacy ringbuffer mode, we need the new ordered breadcrumb emission
tried and tested on execlists in order to avoid the dreaded "missed
interrupt" syndrome. A secondary advantage of the execlists method is
that it writes to an arbitrary address, useful if one wants to write a
breadcrumb elsewhere.

This fix is taken from commit 7c17d37 (drm/i915: Use ordered seqno
write interrupt generation on gen8+ execlists).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1461932305-14637-1-git-send-email-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Apr 29, 2016
1 parent 0e93cdd commit a58c01a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
10 changes: 3 additions & 7 deletions drivers/gpu/drm/i915/intel_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1767,11 +1767,6 @@ static void bxt_a_set_seqno(struct intel_engine_cs *engine, u32 seqno)
*/
#define WA_TAIL_DWORDS 2

static inline u32 hws_seqno_address(struct intel_engine_cs *engine)
{
return engine->status_page.gfx_addr + I915_GEM_HWS_INDEX_ADDR;
}

static int gen8_emit_request(struct drm_i915_gem_request *request)
{
struct intel_ringbuffer *ringbuf = request->ringbuf;
Expand All @@ -1787,7 +1782,7 @@ static int gen8_emit_request(struct drm_i915_gem_request *request)
intel_logical_ring_emit(ringbuf,
(MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW);
intel_logical_ring_emit(ringbuf,
hws_seqno_address(request->engine) |
intel_hws_seqno_address(request->engine) |
MI_FLUSH_DW_USE_GTT);
intel_logical_ring_emit(ringbuf, 0);
intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request));
Expand Down Expand Up @@ -1817,7 +1812,8 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request)
(PIPE_CONTROL_GLOBAL_GTT_IVB |
PIPE_CONTROL_CS_STALL |
PIPE_CONTROL_QW_WRITE));
intel_logical_ring_emit(ringbuf, hws_seqno_address(request->engine));
intel_logical_ring_emit(ringbuf,
intel_hws_seqno_address(request->engine));
intel_logical_ring_emit(ringbuf, 0);
intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request));
/* We're thrashing one dword of HWS. */
Expand Down
32 changes: 30 additions & 2 deletions drivers/gpu/drm/i915/intel_ringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,35 @@ gen6_add_request(struct drm_i915_gem_request *req)
return 0;
}

static int
gen8_render_add_request(struct drm_i915_gem_request *req)
{
struct intel_engine_cs *engine = req->engine;
int ret;

if (engine->semaphore.signal)
ret = engine->semaphore.signal(req, 8);
else
ret = intel_ring_begin(req, 8);
if (ret)
return ret;

intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(6));
intel_ring_emit(engine, (PIPE_CONTROL_GLOBAL_GTT_IVB |
PIPE_CONTROL_CS_STALL |
PIPE_CONTROL_QW_WRITE));
intel_ring_emit(engine, intel_hws_seqno_address(req->engine));
intel_ring_emit(engine, 0);
intel_ring_emit(engine, i915_gem_request_get_seqno(req));
/* We're thrashing one dword of HWS. */
intel_ring_emit(engine, 0);
intel_ring_emit(engine, MI_USER_INTERRUPT);
intel_ring_emit(engine, MI_NOOP);
__intel_ring_advance(engine);

return 0;
}

static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev,
u32 seqno)
{
Expand Down Expand Up @@ -2751,12 +2780,11 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
}

engine->init_context = intel_rcs_ctx_init;
engine->add_request = gen6_add_request;
engine->add_request = gen8_render_add_request;
engine->flush = gen8_render_ring_flush;
engine->irq_get = gen8_ring_get_irq;
engine->irq_put = gen8_ring_put_irq;
engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
engine->irq_seqno_barrier = gen6_seqno_barrier;
engine->get_seqno = ring_get_seqno;
engine->set_seqno = ring_set_seqno;
if (i915_semaphore_is_enabled(dev)) {
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/intel_ringbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,4 +489,9 @@ static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf)
*/
#define MIN_SPACE_FOR_ADD_REQUEST 336

static inline u32 intel_hws_seqno_address(struct intel_engine_cs *engine)
{
return engine->status_page.gfx_addr + I915_GEM_HWS_INDEX_ADDR;
}

#endif /* _INTEL_RINGBUFFER_H_ */

0 comments on commit a58c01a

Please sign in to comment.