diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 72 |
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) | |||
212 | static int | 210 | static int |
213 | intel_emit_post_sync_nonzero_flush(struct i915_request *rq) | 211 | intel_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) | |||
246 | static int | 243 | static int |
247 | gen6_render_ring_flush(struct i915_request *rq, u32 mode) | 244 | gen6_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) | |||
316 | static int | 312 | static int |
317 | gen7_render_ring_flush(struct i915_request *rq, u32 mode) | 313 | gen7_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); |
579 | out: | 588 | out: |
@@ -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) |
979 | static int | 995 | static 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 | ||
1479 | err_scratch: | ||
1480 | intel_engine_cleanup_scratch(engine); | ||
1481 | err_unpin: | 1489 | err_unpin: |
1482 | intel_ring_unpin(ring); | 1490 | intel_ring_unpin(ring); |
1483 | err_ring: | 1491 | err_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; |