diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 80 |
1 files changed, 44 insertions, 36 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2fb3a364c390..dd996103d495 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -443,6 +443,34 @@ static void gen6_xcs_emit_breadcrumb(struct i915_request *rq, u32 *cs) | |||
443 | } | 443 | } |
444 | static const int gen6_xcs_emit_breadcrumb_sz = 4; | 444 | static const int gen6_xcs_emit_breadcrumb_sz = 4; |
445 | 445 | ||
446 | #define GEN7_XCS_WA 32 | ||
447 | static void gen7_xcs_emit_breadcrumb(struct i915_request *rq, u32 *cs) | ||
448 | { | ||
449 | int i; | ||
450 | |||
451 | *cs++ = MI_FLUSH_DW | MI_FLUSH_DW_OP_STOREDW; | ||
452 | *cs++ = intel_hws_seqno_address(rq->engine) | MI_FLUSH_DW_USE_GTT; | ||
453 | *cs++ = rq->global_seqno; | ||
454 | |||
455 | for (i = 0; i < GEN7_XCS_WA; i++) { | ||
456 | *cs++ = MI_STORE_DWORD_INDEX; | ||
457 | *cs++ = I915_GEM_HWS_INDEX_ADDR; | ||
458 | *cs++ = rq->global_seqno; | ||
459 | } | ||
460 | |||
461 | *cs++ = MI_FLUSH_DW; | ||
462 | *cs++ = 0; | ||
463 | *cs++ = 0; | ||
464 | |||
465 | *cs++ = MI_USER_INTERRUPT; | ||
466 | *cs++ = MI_NOOP; | ||
467 | |||
468 | rq->tail = intel_ring_offset(rq, cs); | ||
469 | assert_ring_tail_valid(rq->ring, rq->tail); | ||
470 | } | ||
471 | static const int gen7_xcs_emit_breadcrumb_sz = 8 + GEN7_XCS_WA * 3; | ||
472 | #undef GEN7_XCS_WA | ||
473 | |||
446 | static void set_hwstam(struct intel_engine_cs *engine, u32 mask) | 474 | static void set_hwstam(struct intel_engine_cs *engine, u32 mask) |
447 | { | 475 | { |
448 | /* | 476 | /* |
@@ -875,31 +903,6 @@ gen5_seqno_barrier(struct intel_engine_cs *engine) | |||
875 | } | 903 | } |
876 | 904 | ||
877 | static void | 905 | static void |
878 | gen6_seqno_barrier(struct intel_engine_cs *engine) | ||
879 | { | ||
880 | struct drm_i915_private *dev_priv = engine->i915; | ||
881 | |||
882 | /* Workaround to force correct ordering between irq and seqno writes on | ||
883 | * ivb (and maybe also on snb) by reading from a CS register (like | ||
884 | * ACTHD) before reading the status page. | ||
885 | * | ||
886 | * Note that this effectively stalls the read by the time it takes to | ||
887 | * do a memory transaction, which more or less ensures that the write | ||
888 | * from the GPU has sufficient time to invalidate the CPU cacheline. | ||
889 | * Alternatively we could delay the interrupt from the CS ring to give | ||
890 | * the write time to land, but that would incur a delay after every | ||
891 | * batch i.e. much more frequent than a delay when waiting for the | ||
892 | * interrupt (with the same net latency). | ||
893 | * | ||
894 | * Also note that to prevent whole machine hangs on gen7, we have to | ||
895 | * take the spinlock to guard against concurrent cacheline access. | ||
896 | */ | ||
897 | spin_lock_irq(&dev_priv->uncore.lock); | ||
898 | POSTING_READ_FW(RING_ACTHD(engine->mmio_base)); | ||
899 | spin_unlock_irq(&dev_priv->uncore.lock); | ||
900 | } | ||
901 | |||
902 | static void | ||
903 | gen5_irq_enable(struct intel_engine_cs *engine) | 906 | gen5_irq_enable(struct intel_engine_cs *engine) |
904 | { | 907 | { |
905 | gen5_enable_gt_irq(engine->i915, engine->irq_enable_mask); | 908 | gen5_enable_gt_irq(engine->i915, engine->irq_enable_mask); |
@@ -2258,10 +2261,13 @@ int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine) | |||
2258 | engine->emit_flush = gen6_bsd_ring_flush; | 2261 | engine->emit_flush = gen6_bsd_ring_flush; |
2259 | engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; | 2262 | engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; |
2260 | 2263 | ||
2261 | engine->emit_breadcrumb = gen6_xcs_emit_breadcrumb; | 2264 | if (IS_GEN(dev_priv, 6)) { |
2262 | engine->emit_breadcrumb_sz = gen6_xcs_emit_breadcrumb_sz; | 2265 | engine->emit_breadcrumb = gen6_xcs_emit_breadcrumb; |
2263 | if (!IS_GEN(dev_priv, 6)) | 2266 | engine->emit_breadcrumb_sz = gen6_xcs_emit_breadcrumb_sz; |
2264 | engine->irq_seqno_barrier = gen6_seqno_barrier; | 2267 | } else { |
2268 | engine->emit_breadcrumb = gen7_xcs_emit_breadcrumb; | ||
2269 | engine->emit_breadcrumb_sz = gen7_xcs_emit_breadcrumb_sz; | ||
2270 | } | ||
2265 | } else { | 2271 | } else { |
2266 | engine->emit_flush = bsd_ring_flush; | 2272 | engine->emit_flush = bsd_ring_flush; |
2267 | if (IS_GEN(dev_priv, 5)) | 2273 | if (IS_GEN(dev_priv, 5)) |
@@ -2284,10 +2290,13 @@ int intel_init_blt_ring_buffer(struct intel_engine_cs *engine) | |||
2284 | engine->emit_flush = gen6_ring_flush; | 2290 | engine->emit_flush = gen6_ring_flush; |
2285 | engine->irq_enable_mask = GT_BLT_USER_INTERRUPT; | 2291 | engine->irq_enable_mask = GT_BLT_USER_INTERRUPT; |
2286 | 2292 | ||
2287 | engine->emit_breadcrumb = gen6_xcs_emit_breadcrumb; | 2293 | if (IS_GEN(dev_priv, 6)) { |
2288 | engine->emit_breadcrumb_sz = gen6_xcs_emit_breadcrumb_sz; | 2294 | engine->emit_breadcrumb = gen6_xcs_emit_breadcrumb; |
2289 | if (!IS_GEN(dev_priv, 6)) | 2295 | engine->emit_breadcrumb_sz = gen6_xcs_emit_breadcrumb_sz; |
2290 | engine->irq_seqno_barrier = gen6_seqno_barrier; | 2296 | } else { |
2297 | engine->emit_breadcrumb = gen7_xcs_emit_breadcrumb; | ||
2298 | engine->emit_breadcrumb_sz = gen7_xcs_emit_breadcrumb_sz; | ||
2299 | } | ||
2291 | 2300 | ||
2292 | return intel_init_ring_buffer(engine); | 2301 | return intel_init_ring_buffer(engine); |
2293 | } | 2302 | } |
@@ -2305,9 +2314,8 @@ int intel_init_vebox_ring_buffer(struct intel_engine_cs *engine) | |||
2305 | engine->irq_enable = hsw_vebox_irq_enable; | 2314 | engine->irq_enable = hsw_vebox_irq_enable; |
2306 | engine->irq_disable = hsw_vebox_irq_disable; | 2315 | engine->irq_disable = hsw_vebox_irq_disable; |
2307 | 2316 | ||
2308 | engine->emit_breadcrumb = gen6_xcs_emit_breadcrumb; | 2317 | engine->emit_breadcrumb = gen7_xcs_emit_breadcrumb; |
2309 | engine->emit_breadcrumb_sz = gen6_xcs_emit_breadcrumb_sz; | 2318 | engine->emit_breadcrumb_sz = gen7_xcs_emit_breadcrumb_sz; |
2310 | engine->irq_seqno_barrier = gen6_seqno_barrier; | ||
2311 | 2319 | ||
2312 | return intel_init_ring_buffer(engine); | 2320 | return intel_init_ring_buffer(engine); |
2313 | } | 2321 | } |