aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c72
1 files changed, 40 insertions, 32 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 87eebc13c0d8..c5eb26a7ee79 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -150,8 +150,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
150 */ 150 */
151 if (mode & EMIT_INVALIDATE) { 151 if (mode & EMIT_INVALIDATE) {
152 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; 152 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
153 *cs++ = i915_ggtt_offset(rq->engine->scratch) | 153 *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT;
154 PIPE_CONTROL_GLOBAL_GTT;
155 *cs++ = 0; 154 *cs++ = 0;
156 *cs++ = 0; 155 *cs++ = 0;
157 156
@@ -159,8 +158,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
159 *cs++ = MI_FLUSH; 158 *cs++ = MI_FLUSH;
160 159
161 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; 160 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
162 *cs++ = i915_ggtt_offset(rq->engine->scratch) | 161 *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT;
163 PIPE_CONTROL_GLOBAL_GTT;
164 *cs++ = 0; 162 *cs++ = 0;
165 *cs++ = 0; 163 *cs++ = 0;
166 } 164 }
@@ -212,8 +210,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
212static int 210static int
213intel_emit_post_sync_nonzero_flush(struct i915_request *rq) 211intel_emit_post_sync_nonzero_flush(struct i915_request *rq)
214{ 212{
215 u32 scratch_addr = 213 u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
216 i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
217 u32 *cs; 214 u32 *cs;
218 215
219 cs = intel_ring_begin(rq, 6); 216 cs = intel_ring_begin(rq, 6);
@@ -246,8 +243,7 @@ intel_emit_post_sync_nonzero_flush(struct i915_request *rq)
246static int 243static int
247gen6_render_ring_flush(struct i915_request *rq, u32 mode) 244gen6_render_ring_flush(struct i915_request *rq, u32 mode)
248{ 245{
249 u32 scratch_addr = 246 u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
250 i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
251 u32 *cs, flags = 0; 247 u32 *cs, flags = 0;
252 int ret; 248 int ret;
253 249
@@ -316,8 +312,7 @@ gen7_render_ring_cs_stall_wa(struct i915_request *rq)
316static int 312static int
317gen7_render_ring_flush(struct i915_request *rq, u32 mode) 313gen7_render_ring_flush(struct i915_request *rq, u32 mode)
318{ 314{
319 u32 scratch_addr = 315 u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
320 i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
321 u32 *cs, flags = 0; 316 u32 *cs, flags = 0;
322 317
323 /* 318 /*
@@ -529,6 +524,13 @@ static int init_ring_common(struct intel_engine_cs *engine)
529 524
530 intel_engine_reset_breadcrumbs(engine); 525 intel_engine_reset_breadcrumbs(engine);
531 526
527 if (HAS_LEGACY_SEMAPHORES(engine->i915)) {
528 I915_WRITE(RING_SYNC_0(engine->mmio_base), 0);
529 I915_WRITE(RING_SYNC_1(engine->mmio_base), 0);
530 if (HAS_VEBOX(dev_priv))
531 I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
532 }
533
532 /* Enforce ordering by reading HEAD register back */ 534 /* Enforce ordering by reading HEAD register back */
533 I915_READ_HEAD(engine); 535 I915_READ_HEAD(engine);
534 536
@@ -546,10 +548,11 @@ static int init_ring_common(struct intel_engine_cs *engine)
546 /* Check that the ring offsets point within the ring! */ 548 /* Check that the ring offsets point within the ring! */
547 GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head)); 549 GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head));
548 GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->tail)); 550 GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->tail));
549
550 intel_ring_update_space(ring); 551 intel_ring_update_space(ring);
552
553 /* First wake the ring up to an empty/idle ring */
551 I915_WRITE_HEAD(engine, ring->head); 554 I915_WRITE_HEAD(engine, ring->head);
552 I915_WRITE_TAIL(engine, ring->tail); 555 I915_WRITE_TAIL(engine, ring->head);
553 (void)I915_READ_TAIL(engine); 556 (void)I915_READ_TAIL(engine);
554 557
555 I915_WRITE_CTL(engine, RING_CTL_SIZE(ring->size) | RING_VALID); 558 I915_WRITE_CTL(engine, RING_CTL_SIZE(ring->size) | RING_VALID);
@@ -574,6 +577,12 @@ static int init_ring_common(struct intel_engine_cs *engine)
574 if (INTEL_GEN(dev_priv) > 2) 577 if (INTEL_GEN(dev_priv) > 2)
575 I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); 578 I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING));
576 579
580 /* Now awake, let it get started */
581 if (ring->tail != ring->head) {
582 I915_WRITE_TAIL(engine, ring->tail);
583 (void)I915_READ_TAIL(engine);
584 }
585
577 /* Papering over lost _interrupts_ immediately following the restart */ 586 /* Papering over lost _interrupts_ immediately following the restart */
578 intel_engine_wakeup(engine); 587 intel_engine_wakeup(engine);
579out: 588out:
@@ -642,7 +651,7 @@ static int intel_rcs_ctx_init(struct i915_request *rq)
642{ 651{
643 int ret; 652 int ret;
644 653
645 ret = intel_ctx_workarounds_emit(rq); 654 ret = intel_engine_emit_ctx_wa(rq);
646 if (ret != 0) 655 if (ret != 0)
647 return ret; 656 return ret;
648 657
@@ -660,8 +669,6 @@ static int init_render_ring(struct intel_engine_cs *engine)
660 if (ret) 669 if (ret)
661 return ret; 670 return ret;
662 671
663 intel_whitelist_workarounds_apply(engine);
664
665 /* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */ 672 /* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */
666 if (IS_GEN(dev_priv, 4, 6)) 673 if (IS_GEN(dev_priv, 4, 6))
667 I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH)); 674 I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH));
@@ -743,9 +750,18 @@ static void cancel_requests(struct intel_engine_cs *engine)
743 /* Mark all submitted requests as skipped. */ 750 /* Mark all submitted requests as skipped. */
744 list_for_each_entry(request, &engine->timeline.requests, link) { 751 list_for_each_entry(request, &engine->timeline.requests, link) {
745 GEM_BUG_ON(!request->global_seqno); 752 GEM_BUG_ON(!request->global_seqno);
746 if (!i915_request_completed(request)) 753
747 dma_fence_set_error(&request->fence, -EIO); 754 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
755 &request->fence.flags))
756 continue;
757
758 dma_fence_set_error(&request->fence, -EIO);
748 } 759 }
760
761 intel_write_status_page(engine,
762 I915_GEM_HWS_INDEX,
763 intel_engine_last_submit(engine));
764
749 /* Remaining _unready_ requests will be nop'ed when submitted */ 765 /* Remaining _unready_ requests will be nop'ed when submitted */
750 766
751 spin_unlock_irqrestore(&engine->timeline.lock, flags); 767 spin_unlock_irqrestore(&engine->timeline.lock, flags);
@@ -973,7 +989,7 @@ i965_emit_bb_start(struct i915_request *rq,
973} 989}
974 990
975/* Just userspace ABI convention to limit the wa batch bo to a resonable size */ 991/* Just userspace ABI convention to limit the wa batch bo to a resonable size */
976#define I830_BATCH_LIMIT (256*1024) 992#define I830_BATCH_LIMIT SZ_256K
977#define I830_TLB_ENTRIES (2) 993#define I830_TLB_ENTRIES (2)
978#define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT) 994#define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT)
979static int 995static int
@@ -981,7 +997,9 @@ i830_emit_bb_start(struct i915_request *rq,
981 u64 offset, u32 len, 997 u64 offset, u32 len,
982 unsigned int dispatch_flags) 998 unsigned int dispatch_flags)
983{ 999{
984 u32 *cs, cs_offset = i915_ggtt_offset(rq->engine->scratch); 1000 u32 *cs, cs_offset = i915_scratch_offset(rq->i915);
1001
1002 GEM_BUG_ON(rq->i915->gt.scratch->size < I830_WA_SIZE);
985 1003
986 cs = intel_ring_begin(rq, 6); 1004 cs = intel_ring_begin(rq, 6);
987 if (IS_ERR(cs)) 1005 if (IS_ERR(cs))
@@ -1438,7 +1456,6 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
1438{ 1456{
1439 struct i915_timeline *timeline; 1457 struct i915_timeline *timeline;
1440 struct intel_ring *ring; 1458 struct intel_ring *ring;
1441 unsigned int size;
1442 int err; 1459 int err;
1443 1460
1444 intel_engine_setup_common(engine); 1461 intel_engine_setup_common(engine);
@@ -1463,21 +1480,12 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
1463 GEM_BUG_ON(engine->buffer); 1480 GEM_BUG_ON(engine->buffer);
1464 engine->buffer = ring; 1481 engine->buffer = ring;
1465 1482
1466 size = PAGE_SIZE;
1467 if (HAS_BROKEN_CS_TLB(engine->i915))
1468 size = I830_WA_SIZE;
1469 err = intel_engine_create_scratch(engine, size);
1470 if (err)
1471 goto err_unpin;
1472
1473 err = intel_engine_init_common(engine); 1483 err = intel_engine_init_common(engine);
1474 if (err) 1484 if (err)
1475 goto err_scratch; 1485 goto err_unpin;
1476 1486
1477 return 0; 1487 return 0;
1478 1488
1479err_scratch:
1480 intel_engine_cleanup_scratch(engine);
1481err_unpin: 1489err_unpin:
1482 intel_ring_unpin(ring); 1490 intel_ring_unpin(ring);
1483err_ring: 1491err_ring:
@@ -1551,7 +1559,7 @@ static int flush_pd_dir(struct i915_request *rq)
1551 /* Stall until the page table load is complete */ 1559 /* Stall until the page table load is complete */
1552 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; 1560 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
1553 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine)); 1561 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
1554 *cs++ = i915_ggtt_offset(engine->scratch); 1562 *cs++ = i915_scratch_offset(rq->i915);
1555 *cs++ = MI_NOOP; 1563 *cs++ = MI_NOOP;
1556 1564
1557 intel_ring_advance(rq, cs); 1565 intel_ring_advance(rq, cs);
@@ -1660,7 +1668,7 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags)
1660 /* Insert a delay before the next switch! */ 1668 /* Insert a delay before the next switch! */
1661 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; 1669 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
1662 *cs++ = i915_mmio_reg_offset(last_reg); 1670 *cs++ = i915_mmio_reg_offset(last_reg);
1663 *cs++ = i915_ggtt_offset(engine->scratch); 1671 *cs++ = i915_scratch_offset(rq->i915);
1664 *cs++ = MI_NOOP; 1672 *cs++ = MI_NOOP;
1665 } 1673 }
1666 *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; 1674 *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;