diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_lrc.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_lrc.c | 181 |
1 files changed, 110 insertions, 71 deletions
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index d36e25607435..be6c39adebdf 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
@@ -136,6 +136,7 @@ | |||
136 | #include <drm/drmP.h> | 136 | #include <drm/drmP.h> |
137 | #include <drm/i915_drm.h> | 137 | #include <drm/i915_drm.h> |
138 | #include "i915_drv.h" | 138 | #include "i915_drv.h" |
139 | #include "i915_gem_render_state.h" | ||
139 | #include "intel_mocs.h" | 140 | #include "intel_mocs.h" |
140 | 141 | ||
141 | #define RING_EXECLIST_QFULL (1 << 0x2) | 142 | #define RING_EXECLIST_QFULL (1 << 0x2) |
@@ -354,7 +355,7 @@ static void unwind_wa_tail(struct drm_i915_gem_request *rq) | |||
354 | assert_ring_tail_valid(rq->ring, rq->tail); | 355 | assert_ring_tail_valid(rq->ring, rq->tail); |
355 | } | 356 | } |
356 | 357 | ||
357 | static void unwind_incomplete_requests(struct intel_engine_cs *engine) | 358 | static void __unwind_incomplete_requests(struct intel_engine_cs *engine) |
358 | { | 359 | { |
359 | struct drm_i915_gem_request *rq, *rn; | 360 | struct drm_i915_gem_request *rq, *rn; |
360 | struct i915_priolist *uninitialized_var(p); | 361 | struct i915_priolist *uninitialized_var(p); |
@@ -385,6 +386,17 @@ static void unwind_incomplete_requests(struct intel_engine_cs *engine) | |||
385 | } | 386 | } |
386 | } | 387 | } |
387 | 388 | ||
389 | void | ||
390 | execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists) | ||
391 | { | ||
392 | struct intel_engine_cs *engine = | ||
393 | container_of(execlists, typeof(*engine), execlists); | ||
394 | |||
395 | spin_lock_irq(&engine->timeline->lock); | ||
396 | __unwind_incomplete_requests(engine); | ||
397 | spin_unlock_irq(&engine->timeline->lock); | ||
398 | } | ||
399 | |||
388 | static inline void | 400 | static inline void |
389 | execlists_context_status_change(struct drm_i915_gem_request *rq, | 401 | execlists_context_status_change(struct drm_i915_gem_request *rq, |
390 | unsigned long status) | 402 | unsigned long status) |
@@ -455,6 +467,11 @@ static void execlists_submit_ports(struct intel_engine_cs *engine) | |||
455 | port_set(&port[n], port_pack(rq, count)); | 467 | port_set(&port[n], port_pack(rq, count)); |
456 | desc = execlists_update_context(rq); | 468 | desc = execlists_update_context(rq); |
457 | GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc)); | 469 | GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc)); |
470 | |||
471 | GEM_TRACE("%s in[%d]: ctx=%d.%d, seqno=%x\n", | ||
472 | engine->name, n, | ||
473 | rq->ctx->hw_id, count, | ||
474 | rq->global_seqno); | ||
458 | } else { | 475 | } else { |
459 | GEM_BUG_ON(!n); | 476 | GEM_BUG_ON(!n); |
460 | desc = 0; | 477 | desc = 0; |
@@ -509,17 +526,13 @@ static void inject_preempt_context(struct intel_engine_cs *engine) | |||
509 | ce->ring->tail &= (ce->ring->size - 1); | 526 | ce->ring->tail &= (ce->ring->size - 1); |
510 | ce->lrc_reg_state[CTX_RING_TAIL+1] = ce->ring->tail; | 527 | ce->lrc_reg_state[CTX_RING_TAIL+1] = ce->ring->tail; |
511 | 528 | ||
529 | GEM_TRACE("\n"); | ||
512 | for (n = execlists_num_ports(&engine->execlists); --n; ) | 530 | for (n = execlists_num_ports(&engine->execlists); --n; ) |
513 | elsp_write(0, elsp); | 531 | elsp_write(0, elsp); |
514 | 532 | ||
515 | elsp_write(ce->lrc_desc, elsp); | 533 | elsp_write(ce->lrc_desc, elsp); |
516 | } | 534 | } |
517 | 535 | ||
518 | static bool can_preempt(struct intel_engine_cs *engine) | ||
519 | { | ||
520 | return INTEL_INFO(engine->i915)->has_logical_ring_preemption; | ||
521 | } | ||
522 | |||
523 | static void execlists_dequeue(struct intel_engine_cs *engine) | 536 | static void execlists_dequeue(struct intel_engine_cs *engine) |
524 | { | 537 | { |
525 | struct intel_engine_execlists * const execlists = &engine->execlists; | 538 | struct intel_engine_execlists * const execlists = &engine->execlists; |
@@ -567,7 +580,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) | |||
567 | if (port_count(&port[0]) > 1) | 580 | if (port_count(&port[0]) > 1) |
568 | goto unlock; | 581 | goto unlock; |
569 | 582 | ||
570 | if (can_preempt(engine) && | 583 | if (HAS_LOGICAL_RING_PREEMPTION(engine->i915) && |
571 | rb_entry(rb, struct i915_priolist, node)->priority > | 584 | rb_entry(rb, struct i915_priolist, node)->priority > |
572 | max(last->priotree.priority, 0)) { | 585 | max(last->priotree.priority, 0)) { |
573 | /* | 586 | /* |
@@ -690,8 +703,8 @@ unlock: | |||
690 | } | 703 | } |
691 | } | 704 | } |
692 | 705 | ||
693 | static void | 706 | void |
694 | execlist_cancel_port_requests(struct intel_engine_execlists *execlists) | 707 | execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) |
695 | { | 708 | { |
696 | struct execlist_port *port = execlists->port; | 709 | struct execlist_port *port = execlists->port; |
697 | unsigned int num_ports = execlists_num_ports(execlists); | 710 | unsigned int num_ports = execlists_num_ports(execlists); |
@@ -718,7 +731,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) | |||
718 | spin_lock_irqsave(&engine->timeline->lock, flags); | 731 | spin_lock_irqsave(&engine->timeline->lock, flags); |
719 | 732 | ||
720 | /* Cancel the requests on the HW and clear the ELSP tracker. */ | 733 | /* Cancel the requests on the HW and clear the ELSP tracker. */ |
721 | execlist_cancel_port_requests(execlists); | 734 | execlists_cancel_port_requests(execlists); |
722 | 735 | ||
723 | /* Mark all executing requests as skipped. */ | 736 | /* Mark all executing requests as skipped. */ |
724 | list_for_each_entry(rq, &engine->timeline->requests, link) { | 737 | list_for_each_entry(rq, &engine->timeline->requests, link) { |
@@ -768,7 +781,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) | |||
768 | * Check the unread Context Status Buffers and manage the submission of new | 781 | * Check the unread Context Status Buffers and manage the submission of new |
769 | * contexts to the ELSP accordingly. | 782 | * contexts to the ELSP accordingly. |
770 | */ | 783 | */ |
771 | static void intel_lrc_irq_handler(unsigned long data) | 784 | static void execlists_submission_tasklet(unsigned long data) |
772 | { | 785 | { |
773 | struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; | 786 | struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; |
774 | struct intel_engine_execlists * const execlists = &engine->execlists; | 787 | struct intel_engine_execlists * const execlists = &engine->execlists; |
@@ -826,6 +839,10 @@ static void intel_lrc_irq_handler(unsigned long data) | |||
826 | head = execlists->csb_head; | 839 | head = execlists->csb_head; |
827 | tail = READ_ONCE(buf[write_idx]); | 840 | tail = READ_ONCE(buf[write_idx]); |
828 | } | 841 | } |
842 | GEM_TRACE("%s cs-irq head=%d [%d], tail=%d [%d]\n", | ||
843 | engine->name, | ||
844 | head, GEN8_CSB_READ_PTR(readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)))), | ||
845 | tail, GEN8_CSB_WRITE_PTR(readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))))); | ||
829 | 846 | ||
830 | while (head != tail) { | 847 | while (head != tail) { |
831 | struct drm_i915_gem_request *rq; | 848 | struct drm_i915_gem_request *rq; |
@@ -853,16 +870,16 @@ static void intel_lrc_irq_handler(unsigned long data) | |||
853 | */ | 870 | */ |
854 | 871 | ||
855 | status = READ_ONCE(buf[2 * head]); /* maybe mmio! */ | 872 | status = READ_ONCE(buf[2 * head]); /* maybe mmio! */ |
873 | GEM_TRACE("%s csb[%dd]: status=0x%08x:0x%08x\n", | ||
874 | engine->name, head, | ||
875 | status, buf[2*head + 1]); | ||
856 | if (!(status & GEN8_CTX_STATUS_COMPLETED_MASK)) | 876 | if (!(status & GEN8_CTX_STATUS_COMPLETED_MASK)) |
857 | continue; | 877 | continue; |
858 | 878 | ||
859 | if (status & GEN8_CTX_STATUS_ACTIVE_IDLE && | 879 | if (status & GEN8_CTX_STATUS_ACTIVE_IDLE && |
860 | buf[2*head + 1] == PREEMPT_ID) { | 880 | buf[2*head + 1] == PREEMPT_ID) { |
861 | execlist_cancel_port_requests(execlists); | 881 | execlists_cancel_port_requests(execlists); |
862 | 882 | execlists_unwind_incomplete_requests(execlists); | |
863 | spin_lock_irq(&engine->timeline->lock); | ||
864 | unwind_incomplete_requests(engine); | ||
865 | spin_unlock_irq(&engine->timeline->lock); | ||
866 | 883 | ||
867 | GEM_BUG_ON(!execlists_is_active(execlists, | 884 | GEM_BUG_ON(!execlists_is_active(execlists, |
868 | EXECLISTS_ACTIVE_PREEMPT)); | 885 | EXECLISTS_ACTIVE_PREEMPT)); |
@@ -883,6 +900,10 @@ static void intel_lrc_irq_handler(unsigned long data) | |||
883 | GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id); | 900 | GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id); |
884 | 901 | ||
885 | rq = port_unpack(port, &count); | 902 | rq = port_unpack(port, &count); |
903 | GEM_TRACE("%s out[0]: ctx=%d.%d, seqno=%x\n", | ||
904 | engine->name, | ||
905 | rq->ctx->hw_id, count, | ||
906 | rq->global_seqno); | ||
886 | GEM_BUG_ON(count == 0); | 907 | GEM_BUG_ON(count == 0); |
887 | if (--count == 0) { | 908 | if (--count == 0) { |
888 | GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED); | 909 | GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED); |
@@ -926,7 +947,7 @@ static void insert_request(struct intel_engine_cs *engine, | |||
926 | 947 | ||
927 | list_add_tail(&pt->link, &ptr_mask_bits(p, 1)->requests); | 948 | list_add_tail(&pt->link, &ptr_mask_bits(p, 1)->requests); |
928 | if (ptr_unmask_bits(p, 1)) | 949 | if (ptr_unmask_bits(p, 1)) |
929 | tasklet_hi_schedule(&engine->execlists.irq_tasklet); | 950 | tasklet_hi_schedule(&engine->execlists.tasklet); |
930 | } | 951 | } |
931 | 952 | ||
932 | static void execlists_submit_request(struct drm_i915_gem_request *request) | 953 | static void execlists_submit_request(struct drm_i915_gem_request *request) |
@@ -1057,12 +1078,34 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) | |||
1057 | spin_unlock_irq(&engine->timeline->lock); | 1078 | spin_unlock_irq(&engine->timeline->lock); |
1058 | } | 1079 | } |
1059 | 1080 | ||
1081 | static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma) | ||
1082 | { | ||
1083 | unsigned int flags; | ||
1084 | int err; | ||
1085 | |||
1086 | /* | ||
1087 | * Clear this page out of any CPU caches for coherent swap-in/out. | ||
1088 | * We only want to do this on the first bind so that we do not stall | ||
1089 | * on an active context (which by nature is already on the GPU). | ||
1090 | */ | ||
1091 | if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { | ||
1092 | err = i915_gem_object_set_to_gtt_domain(vma->obj, true); | ||
1093 | if (err) | ||
1094 | return err; | ||
1095 | } | ||
1096 | |||
1097 | flags = PIN_GLOBAL | PIN_HIGH; | ||
1098 | if (ctx->ggtt_offset_bias) | ||
1099 | flags |= PIN_OFFSET_BIAS | ctx->ggtt_offset_bias; | ||
1100 | |||
1101 | return i915_vma_pin(vma, 0, GEN8_LR_CONTEXT_ALIGN, flags); | ||
1102 | } | ||
1103 | |||
1060 | static struct intel_ring * | 1104 | static struct intel_ring * |
1061 | execlists_context_pin(struct intel_engine_cs *engine, | 1105 | execlists_context_pin(struct intel_engine_cs *engine, |
1062 | struct i915_gem_context *ctx) | 1106 | struct i915_gem_context *ctx) |
1063 | { | 1107 | { |
1064 | struct intel_context *ce = &ctx->engine[engine->id]; | 1108 | struct intel_context *ce = &ctx->engine[engine->id]; |
1065 | unsigned int flags; | ||
1066 | void *vaddr; | 1109 | void *vaddr; |
1067 | int ret; | 1110 | int ret; |
1068 | 1111 | ||
@@ -1079,11 +1122,7 @@ execlists_context_pin(struct intel_engine_cs *engine, | |||
1079 | } | 1122 | } |
1080 | GEM_BUG_ON(!ce->state); | 1123 | GEM_BUG_ON(!ce->state); |
1081 | 1124 | ||
1082 | flags = PIN_GLOBAL | PIN_HIGH; | 1125 | ret = __context_pin(ctx, ce->state); |
1083 | if (ctx->ggtt_offset_bias) | ||
1084 | flags |= PIN_OFFSET_BIAS | ctx->ggtt_offset_bias; | ||
1085 | |||
1086 | ret = i915_vma_pin(ce->state, 0, GEN8_LR_CONTEXT_ALIGN, flags); | ||
1087 | if (ret) | 1126 | if (ret) |
1088 | goto err; | 1127 | goto err; |
1089 | 1128 | ||
@@ -1103,9 +1142,7 @@ execlists_context_pin(struct intel_engine_cs *engine, | |||
1103 | ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = | 1142 | ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = |
1104 | i915_ggtt_offset(ce->ring->vma); | 1143 | i915_ggtt_offset(ce->ring->vma); |
1105 | 1144 | ||
1106 | ce->state->obj->mm.dirty = true; | ||
1107 | ce->state->obj->pin_global++; | 1145 | ce->state->obj->pin_global++; |
1108 | |||
1109 | i915_gem_context_get(ctx); | 1146 | i915_gem_context_get(ctx); |
1110 | out: | 1147 | out: |
1111 | return ce->ring; | 1148 | return ce->ring; |
@@ -1143,7 +1180,6 @@ static int execlists_request_alloc(struct drm_i915_gem_request *request) | |||
1143 | { | 1180 | { |
1144 | struct intel_engine_cs *engine = request->engine; | 1181 | struct intel_engine_cs *engine = request->engine; |
1145 | struct intel_context *ce = &request->ctx->engine[engine->id]; | 1182 | struct intel_context *ce = &request->ctx->engine[engine->id]; |
1146 | u32 *cs; | ||
1147 | int ret; | 1183 | int ret; |
1148 | 1184 | ||
1149 | GEM_BUG_ON(!ce->pin_count); | 1185 | GEM_BUG_ON(!ce->pin_count); |
@@ -1154,17 +1190,9 @@ static int execlists_request_alloc(struct drm_i915_gem_request *request) | |||
1154 | */ | 1190 | */ |
1155 | request->reserved_space += EXECLISTS_REQUEST_SIZE; | 1191 | request->reserved_space += EXECLISTS_REQUEST_SIZE; |
1156 | 1192 | ||
1157 | cs = intel_ring_begin(request, 0); | 1193 | ret = intel_ring_wait_for_space(request->ring, request->reserved_space); |
1158 | if (IS_ERR(cs)) | 1194 | if (ret) |
1159 | return PTR_ERR(cs); | 1195 | return ret; |
1160 | |||
1161 | if (!ce->initialised) { | ||
1162 | ret = engine->init_context(request); | ||
1163 | if (ret) | ||
1164 | return ret; | ||
1165 | |||
1166 | ce->initialised = true; | ||
1167 | } | ||
1168 | 1196 | ||
1169 | /* Note that after this point, we have committed to using | 1197 | /* Note that after this point, we have committed to using |
1170 | * this request as it is being used to both track the | 1198 | * this request as it is being used to both track the |
@@ -1474,8 +1502,8 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) | |||
1474 | execlists->active = 0; | 1502 | execlists->active = 0; |
1475 | 1503 | ||
1476 | /* After a GPU reset, we may have requests to replay */ | 1504 | /* After a GPU reset, we may have requests to replay */ |
1477 | if (!i915_modparams.enable_guc_submission && execlists->first) | 1505 | if (execlists->first) |
1478 | tasklet_schedule(&execlists->irq_tasklet); | 1506 | tasklet_schedule(&execlists->tasklet); |
1479 | 1507 | ||
1480 | return 0; | 1508 | return 0; |
1481 | } | 1509 | } |
@@ -1531,10 +1559,10 @@ static void reset_common_ring(struct intel_engine_cs *engine, | |||
1531 | * guessing the missed context-switch events by looking at what | 1559 | * guessing the missed context-switch events by looking at what |
1532 | * requests were completed. | 1560 | * requests were completed. |
1533 | */ | 1561 | */ |
1534 | execlist_cancel_port_requests(execlists); | 1562 | execlists_cancel_port_requests(execlists); |
1535 | 1563 | ||
1536 | /* Push back any incomplete requests for replay after the reset. */ | 1564 | /* Push back any incomplete requests for replay after the reset. */ |
1537 | unwind_incomplete_requests(engine); | 1565 | __unwind_incomplete_requests(engine); |
1538 | 1566 | ||
1539 | spin_unlock_irqrestore(&engine->timeline->lock, flags); | 1567 | spin_unlock_irqrestore(&engine->timeline->lock, flags); |
1540 | 1568 | ||
@@ -1794,10 +1822,8 @@ static void gen8_emit_breadcrumb(struct drm_i915_gem_request *request, u32 *cs) | |||
1794 | /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */ | 1822 | /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */ |
1795 | BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5)); | 1823 | BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5)); |
1796 | 1824 | ||
1797 | *cs++ = (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW; | 1825 | cs = gen8_emit_ggtt_write(cs, request->global_seqno, |
1798 | *cs++ = intel_hws_seqno_address(request->engine) | MI_FLUSH_DW_USE_GTT; | 1826 | intel_hws_seqno_address(request->engine)); |
1799 | *cs++ = 0; | ||
1800 | *cs++ = request->global_seqno; | ||
1801 | *cs++ = MI_USER_INTERRUPT; | 1827 | *cs++ = MI_USER_INTERRUPT; |
1802 | *cs++ = MI_NOOP; | 1828 | *cs++ = MI_NOOP; |
1803 | request->tail = intel_ring_offset(request, cs); | 1829 | request->tail = intel_ring_offset(request, cs); |
@@ -1807,24 +1833,14 @@ static void gen8_emit_breadcrumb(struct drm_i915_gem_request *request, u32 *cs) | |||
1807 | } | 1833 | } |
1808 | static const int gen8_emit_breadcrumb_sz = 6 + WA_TAIL_DWORDS; | 1834 | static const int gen8_emit_breadcrumb_sz = 6 + WA_TAIL_DWORDS; |
1809 | 1835 | ||
1810 | static void gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request, | 1836 | static void gen8_emit_breadcrumb_rcs(struct drm_i915_gem_request *request, |
1811 | u32 *cs) | 1837 | u32 *cs) |
1812 | { | 1838 | { |
1813 | /* We're using qword write, seqno should be aligned to 8 bytes. */ | 1839 | /* We're using qword write, seqno should be aligned to 8 bytes. */ |
1814 | BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1); | 1840 | BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1); |
1815 | 1841 | ||
1816 | /* w/a for post sync ops following a GPGPU operation we | 1842 | cs = gen8_emit_ggtt_write_rcs(cs, request->global_seqno, |
1817 | * need a prior CS_STALL, which is emitted by the flush | 1843 | intel_hws_seqno_address(request->engine)); |
1818 | * following the batch. | ||
1819 | */ | ||
1820 | *cs++ = GFX_OP_PIPE_CONTROL(6); | ||
1821 | *cs++ = PIPE_CONTROL_GLOBAL_GTT_IVB | PIPE_CONTROL_CS_STALL | | ||
1822 | PIPE_CONTROL_QW_WRITE; | ||
1823 | *cs++ = intel_hws_seqno_address(request->engine); | ||
1824 | *cs++ = 0; | ||
1825 | *cs++ = request->global_seqno; | ||
1826 | /* We're thrashing one dword of HWS. */ | ||
1827 | *cs++ = 0; | ||
1828 | *cs++ = MI_USER_INTERRUPT; | 1844 | *cs++ = MI_USER_INTERRUPT; |
1829 | *cs++ = MI_NOOP; | 1845 | *cs++ = MI_NOOP; |
1830 | request->tail = intel_ring_offset(request, cs); | 1846 | request->tail = intel_ring_offset(request, cs); |
@@ -1832,7 +1848,7 @@ static void gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request, | |||
1832 | 1848 | ||
1833 | gen8_emit_wa_tail(request, cs); | 1849 | gen8_emit_wa_tail(request, cs); |
1834 | } | 1850 | } |
1835 | static const int gen8_emit_breadcrumb_render_sz = 8 + WA_TAIL_DWORDS; | 1851 | static const int gen8_emit_breadcrumb_rcs_sz = 8 + WA_TAIL_DWORDS; |
1836 | 1852 | ||
1837 | static int gen8_init_rcs_context(struct drm_i915_gem_request *req) | 1853 | static int gen8_init_rcs_context(struct drm_i915_gem_request *req) |
1838 | { | 1854 | { |
@@ -1865,8 +1881,9 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) | |||
1865 | * Tasklet cannot be active at this point due intel_mark_active/idle | 1881 | * Tasklet cannot be active at this point due intel_mark_active/idle |
1866 | * so this is just for documentation. | 1882 | * so this is just for documentation. |
1867 | */ | 1883 | */ |
1868 | if (WARN_ON(test_bit(TASKLET_STATE_SCHED, &engine->execlists.irq_tasklet.state))) | 1884 | if (WARN_ON(test_bit(TASKLET_STATE_SCHED, |
1869 | tasklet_kill(&engine->execlists.irq_tasklet); | 1885 | &engine->execlists.tasklet.state))) |
1886 | tasklet_kill(&engine->execlists.tasklet); | ||
1870 | 1887 | ||
1871 | dev_priv = engine->i915; | 1888 | dev_priv = engine->i915; |
1872 | 1889 | ||
@@ -1890,7 +1907,10 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine) | |||
1890 | engine->submit_request = execlists_submit_request; | 1907 | engine->submit_request = execlists_submit_request; |
1891 | engine->cancel_requests = execlists_cancel_requests; | 1908 | engine->cancel_requests = execlists_cancel_requests; |
1892 | engine->schedule = execlists_schedule; | 1909 | engine->schedule = execlists_schedule; |
1893 | engine->execlists.irq_tasklet.func = intel_lrc_irq_handler; | 1910 | engine->execlists.tasklet.func = execlists_submission_tasklet; |
1911 | |||
1912 | engine->park = NULL; | ||
1913 | engine->unpark = NULL; | ||
1894 | } | 1914 | } |
1895 | 1915 | ||
1896 | static void | 1916 | static void |
@@ -1949,8 +1969,8 @@ logical_ring_setup(struct intel_engine_cs *engine) | |||
1949 | 1969 | ||
1950 | engine->execlists.fw_domains = fw_domains; | 1970 | engine->execlists.fw_domains = fw_domains; |
1951 | 1971 | ||
1952 | tasklet_init(&engine->execlists.irq_tasklet, | 1972 | tasklet_init(&engine->execlists.tasklet, |
1953 | intel_lrc_irq_handler, (unsigned long)engine); | 1973 | execlists_submission_tasklet, (unsigned long)engine); |
1954 | 1974 | ||
1955 | logical_ring_default_vfuncs(engine); | 1975 | logical_ring_default_vfuncs(engine); |
1956 | logical_ring_default_irqs(engine); | 1976 | logical_ring_default_irqs(engine); |
@@ -1988,8 +2008,8 @@ int logical_render_ring_init(struct intel_engine_cs *engine) | |||
1988 | engine->init_hw = gen8_init_render_ring; | 2008 | engine->init_hw = gen8_init_render_ring; |
1989 | engine->init_context = gen8_init_rcs_context; | 2009 | engine->init_context = gen8_init_rcs_context; |
1990 | engine->emit_flush = gen8_emit_flush_render; | 2010 | engine->emit_flush = gen8_emit_flush_render; |
1991 | engine->emit_breadcrumb = gen8_emit_breadcrumb_render; | 2011 | engine->emit_breadcrumb = gen8_emit_breadcrumb_rcs; |
1992 | engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_render_sz; | 2012 | engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_rcs_sz; |
1993 | 2013 | ||
1994 | ret = intel_engine_create_scratch(engine, PAGE_SIZE); | 2014 | ret = intel_engine_create_scratch(engine, PAGE_SIZE); |
1995 | if (ret) | 2015 | if (ret) |
@@ -2106,7 +2126,6 @@ static void execlists_init_reg_state(u32 *regs, | |||
2106 | 2126 | ||
2107 | CTX_REG(regs, CTX_CONTEXT_CONTROL, RING_CONTEXT_CONTROL(engine), | 2127 | CTX_REG(regs, CTX_CONTEXT_CONTROL, RING_CONTEXT_CONTROL(engine), |
2108 | _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | | 2128 | _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | |
2109 | CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT | | ||
2110 | (HAS_RESOURCE_STREAMER(dev_priv) ? | 2129 | (HAS_RESOURCE_STREAMER(dev_priv) ? |
2111 | CTX_CTRL_RS_CTX_ENABLE : 0))); | 2130 | CTX_CTRL_RS_CTX_ENABLE : 0))); |
2112 | CTX_REG(regs, CTX_RING_HEAD, RING_HEAD(base), 0); | 2131 | CTX_REG(regs, CTX_RING_HEAD, RING_HEAD(base), 0); |
@@ -2183,6 +2202,7 @@ populate_lr_context(struct i915_gem_context *ctx, | |||
2183 | struct intel_ring *ring) | 2202 | struct intel_ring *ring) |
2184 | { | 2203 | { |
2185 | void *vaddr; | 2204 | void *vaddr; |
2205 | u32 *regs; | ||
2186 | int ret; | 2206 | int ret; |
2187 | 2207 | ||
2188 | ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true); | 2208 | ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true); |
@@ -2199,11 +2219,31 @@ populate_lr_context(struct i915_gem_context *ctx, | |||
2199 | } | 2219 | } |
2200 | ctx_obj->mm.dirty = true; | 2220 | ctx_obj->mm.dirty = true; |
2201 | 2221 | ||
2222 | if (engine->default_state) { | ||
2223 | /* | ||
2224 | * We only want to copy over the template context state; | ||
2225 | * skipping over the headers reserved for GuC communication, | ||
2226 | * leaving those as zero. | ||
2227 | */ | ||
2228 | const unsigned long start = LRC_HEADER_PAGES * PAGE_SIZE; | ||
2229 | void *defaults; | ||
2230 | |||
2231 | defaults = i915_gem_object_pin_map(engine->default_state, | ||
2232 | I915_MAP_WB); | ||
2233 | if (IS_ERR(defaults)) | ||
2234 | return PTR_ERR(defaults); | ||
2235 | |||
2236 | memcpy(vaddr + start, defaults + start, engine->context_size); | ||
2237 | i915_gem_object_unpin_map(engine->default_state); | ||
2238 | } | ||
2239 | |||
2202 | /* The second page of the context object contains some fields which must | 2240 | /* The second page of the context object contains some fields which must |
2203 | * be set up prior to the first execution. */ | 2241 | * be set up prior to the first execution. */ |
2204 | 2242 | regs = vaddr + LRC_STATE_PN * PAGE_SIZE; | |
2205 | execlists_init_reg_state(vaddr + LRC_STATE_PN * PAGE_SIZE, | 2243 | execlists_init_reg_state(regs, ctx, engine, ring); |
2206 | ctx, engine, ring); | 2244 | if (!engine->default_state) |
2245 | regs[CTX_CONTEXT_CONTROL + 1] |= | ||
2246 | _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); | ||
2207 | 2247 | ||
2208 | i915_gem_object_unpin_map(ctx_obj); | 2248 | i915_gem_object_unpin_map(ctx_obj); |
2209 | 2249 | ||
@@ -2256,7 +2296,6 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, | |||
2256 | 2296 | ||
2257 | ce->ring = ring; | 2297 | ce->ring = ring; |
2258 | ce->state = vma; | 2298 | ce->state = vma; |
2259 | ce->initialised |= engine->init_context == NULL; | ||
2260 | 2299 | ||
2261 | return 0; | 2300 | return 0; |
2262 | 2301 | ||