aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-11-13 14:18:21 -0500
committerDave Airlie <airlied@redhat.com>2017-11-13 14:18:21 -0500
commit9c117313afbaba6f7613fa2b305b7da5d6058fb1 (patch)
tree4dfd2b8c3003586d107785551c9b5d2d1e37b04e /drivers
parentfee25cb965f9e1360f845a7a3fb16bca1bbadc84 (diff)
parente8c49fa96838101435b9e4884d49b30da7a4e0c6 (diff)
Merge tag 'drm-intel-next-fixes-2017-11-10' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
drm/i915 fixes for v4.15 * tag 'drm-intel-next-fixes-2017-11-10' of git://anongit.freedesktop.org/drm/drm-intel: drm/i915: Reorder context-close to avoid calling i915_vma_close() under RCU drm/i915: Move init_clock_gating() back to where it was drm/i915: Prune the reservation shared fence array drm/i915: Idle the GPU before shinking everything drm/i915: Lock llist_del_first() vs llist_del_all() drm/i915: Calculate ironlake intermediate watermarks correctly, v2. drm/i915: Disable lazy PPGTT page table optimization for vGPU drm/i915/execlists: Remove the priority "optimisation" drm/i915: Filter out spurious execlists context-switch interrupts
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c8
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c12
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_shrinker.c12
-rw-r--r--drivers/gpu/drm/i915/i915_guc_submission.c3
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c6
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c7
-rw-r--r--drivers/gpu/drm/i915/intel_display.c14
-rw-r--r--drivers/gpu/drm/i915/intel_engine_cs.c5
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c29
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c53
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h34
12 files changed, 133 insertions, 52 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 026cb52ece0b..94b23fcbc989 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4603,11 +4603,17 @@ static void __i915_gem_free_work(struct work_struct *work)
4603 * unbound now. 4603 * unbound now.
4604 */ 4604 */
4605 4605
4606 spin_lock(&i915->mm.free_lock);
4606 while ((freed = llist_del_all(&i915->mm.free_list))) { 4607 while ((freed = llist_del_all(&i915->mm.free_list))) {
4608 spin_unlock(&i915->mm.free_lock);
4609
4607 __i915_gem_free_objects(i915, freed); 4610 __i915_gem_free_objects(i915, freed);
4608 if (need_resched()) 4611 if (need_resched())
4609 break; 4612 return;
4613
4614 spin_lock(&i915->mm.free_lock);
4610 } 4615 }
4616 spin_unlock(&i915->mm.free_lock);
4611} 4617}
4612 4618
4613static void __i915_gem_free_object_rcu(struct rcu_head *head) 4619static void __i915_gem_free_object_rcu(struct rcu_head *head)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 5bf96a258509..e304dcbc6042 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -106,14 +106,9 @@ static void lut_close(struct i915_gem_context *ctx)
106 106
107 radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) { 107 radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) {
108 struct i915_vma *vma = rcu_dereference_raw(*slot); 108 struct i915_vma *vma = rcu_dereference_raw(*slot);
109 struct drm_i915_gem_object *obj = vma->obj;
110 109
111 radix_tree_iter_delete(&ctx->handles_vma, &iter, slot); 110 radix_tree_iter_delete(&ctx->handles_vma, &iter, slot);
112 111 __i915_gem_object_release_unless_active(vma->obj);
113 if (!i915_vma_is_ggtt(vma))
114 i915_vma_close(vma);
115
116 __i915_gem_object_release_unless_active(obj);
117 } 112 }
118} 113}
119 114
@@ -198,6 +193,11 @@ static void context_close(struct i915_gem_context *ctx)
198{ 193{
199 i915_gem_context_set_closed(ctx); 194 i915_gem_context_set_closed(ctx);
200 195
196 /*
197 * The LUT uses the VMA as a backpointer to unref the object,
198 * so we need to clear the LUT before we close all the VMA (inside
199 * the ppgtt).
200 */
201 lut_close(ctx); 201 lut_close(ctx);
202 if (ctx->ppgtt) 202 if (ctx->ppgtt)
203 i915_ppgtt_close(&ctx->ppgtt->base); 203 i915_ppgtt_close(&ctx->ppgtt->base);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 527a2d2d6281..5eaa6893daaa 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1341,7 +1341,7 @@ static int gen8_ppgtt_alloc_pd(struct i915_address_space *vm,
1341 if (IS_ERR(pt)) 1341 if (IS_ERR(pt))
1342 goto unwind; 1342 goto unwind;
1343 1343
1344 if (count < GEN8_PTES) 1344 if (count < GEN8_PTES || intel_vgpu_active(vm->i915))
1345 gen8_initialize_pt(vm, pt); 1345 gen8_initialize_pt(vm, pt);
1346 1346
1347 gen8_ppgtt_set_pde(vm, pd, pt, pde); 1347 gen8_ppgtt_set_pde(vm, pd, pt, pde);
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
index eb31f8aa5c21..3770e3323fc8 100644
--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
@@ -162,6 +162,18 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
162 if (!shrinker_lock(dev_priv, &unlock)) 162 if (!shrinker_lock(dev_priv, &unlock))
163 return 0; 163 return 0;
164 164
165 /*
166 * When shrinking the active list, also consider active contexts.
167 * Active contexts are pinned until they are retired, and so can
168 * not be simply unbound to retire and unpin their pages. To shrink
169 * the contexts, we must wait until the gpu is idle.
170 *
171 * We don't care about errors here; if we cannot wait upon the GPU,
172 * we will free as much as we can and hope to get a second chance.
173 */
174 if (flags & I915_SHRINK_ACTIVE)
175 i915_gem_wait_for_idle(dev_priv, I915_WAIT_LOCKED);
176
165 trace_i915_gem_shrink(dev_priv, target, flags); 177 trace_i915_gem_shrink(dev_priv, target, flags);
166 i915_gem_retire_requests(dev_priv); 178 i915_gem_retire_requests(dev_priv);
167 179
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index a2e8114b739d..f84c267728fd 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -610,6 +610,7 @@ done:
610 execlists->first = rb; 610 execlists->first = rb;
611 if (submit) { 611 if (submit) {
612 port_assign(port, last); 612 port_assign(port, last);
613 execlists_set_active(execlists, EXECLISTS_ACTIVE_USER);
613 i915_guc_submit(engine); 614 i915_guc_submit(engine);
614 } 615 }
615 spin_unlock_irq(&engine->timeline->lock); 616 spin_unlock_irq(&engine->timeline->lock);
@@ -633,6 +634,8 @@ static void i915_guc_irq_handler(unsigned long data)
633 634
634 rq = port_request(&port[0]); 635 rq = port_request(&port[0]);
635 } 636 }
637 if (!rq)
638 execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
636 639
637 if (!port_isset(last_port)) 640 if (!port_isset(last_port))
638 i915_guc_dequeue(engine); 641 i915_guc_dequeue(engine);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b1296a55c1e4..f8205841868b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1388,8 +1388,10 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift)
1388 bool tasklet = false; 1388 bool tasklet = false;
1389 1389
1390 if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) { 1390 if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) {
1391 __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); 1391 if (READ_ONCE(engine->execlists.active)) {
1392 tasklet = true; 1392 __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
1393 tasklet = true;
1394 }
1393 } 1395 }
1394 1396
1395 if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) { 1397 if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) {
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index fc77e8191eb5..fbfab2f33023 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -54,6 +54,13 @@ i915_vma_retire(struct i915_gem_active *active,
54 if (--obj->active_count) 54 if (--obj->active_count)
55 return; 55 return;
56 56
57 /* Prune the shared fence arrays iff completely idle (inc. external) */
58 if (reservation_object_trylock(obj->resv)) {
59 if (reservation_object_test_signaled_rcu(obj->resv, true))
60 reservation_object_add_excl_fence(obj->resv, NULL);
61 reservation_object_unlock(obj->resv);
62 }
63
57 /* Bump our place on the bound list to keep it roughly in LRU order 64 /* Bump our place on the bound list to keep it roughly in LRU order
58 * so that we don't steal from recently used but inactive objects 65 * so that we don't steal from recently used but inactive objects
59 * (unless we are forced to ofc!) 66 * (unless we are forced to ofc!)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e2ac976844d8..f4a9a182868f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3676,6 +3676,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
3676 3676
3677 intel_pps_unlock_regs_wa(dev_priv); 3677 intel_pps_unlock_regs_wa(dev_priv);
3678 intel_modeset_init_hw(dev); 3678 intel_modeset_init_hw(dev);
3679 intel_init_clock_gating(dev_priv);
3679 3680
3680 spin_lock_irq(&dev_priv->irq_lock); 3681 spin_lock_irq(&dev_priv->irq_lock);
3681 if (dev_priv->display.hpd_irq_setup) 3682 if (dev_priv->display.hpd_irq_setup)
@@ -14350,8 +14351,6 @@ void intel_modeset_init_hw(struct drm_device *dev)
14350 14351
14351 intel_update_cdclk(dev_priv); 14352 intel_update_cdclk(dev_priv);
14352 dev_priv->cdclk.logical = dev_priv->cdclk.actual = dev_priv->cdclk.hw; 14353 dev_priv->cdclk.logical = dev_priv->cdclk.actual = dev_priv->cdclk.hw;
14353
14354 intel_init_clock_gating(dev_priv);
14355} 14354}
14356 14355
14357/* 14356/*
@@ -15063,6 +15062,15 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
15063 struct intel_encoder *encoder; 15062 struct intel_encoder *encoder;
15064 int i; 15063 int i;
15065 15064
15065 if (IS_HASWELL(dev_priv)) {
15066 /*
15067 * WaRsPkgCStateDisplayPMReq:hsw
15068 * System hang if this isn't done before disabling all planes!
15069 */
15070 I915_WRITE(CHICKEN_PAR1_1,
15071 I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES);
15072 }
15073
15066 intel_modeset_readout_hw_state(dev); 15074 intel_modeset_readout_hw_state(dev);
15067 15075
15068 /* HW state is read out, now we need to sanitize this mess. */ 15076 /* HW state is read out, now we need to sanitize this mess. */
@@ -15160,6 +15168,8 @@ void intel_modeset_gem_init(struct drm_device *dev)
15160 15168
15161 intel_init_gt_powersave(dev_priv); 15169 intel_init_gt_powersave(dev_priv);
15162 15170
15171 intel_init_clock_gating(dev_priv);
15172
15163 intel_setup_overlay(dev_priv); 15173 intel_setup_overlay(dev_priv);
15164} 15174}
15165 15175
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index a47a9c6bea52..ab5bf4e2e28e 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1548,8 +1548,8 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
1548 if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) 1548 if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))
1549 return false; 1549 return false;
1550 1550
1551 /* Both ports drained, no more ELSP submission? */ 1551 /* Waiting to drain ELSP? */
1552 if (port_request(&engine->execlists.port[0])) 1552 if (READ_ONCE(engine->execlists.active))
1553 return false; 1553 return false;
1554 1554
1555 /* ELSP is empty, but there are ready requests? */ 1555 /* ELSP is empty, but there are ready requests? */
@@ -1749,6 +1749,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m)
1749 idx); 1749 idx);
1750 } 1750 }
1751 } 1751 }
1752 drm_printf(m, "\t\tHW active? 0x%x\n", execlists->active);
1752 rcu_read_unlock(); 1753 rcu_read_unlock();
1753 } else if (INTEL_GEN(dev_priv) > 6) { 1754 } else if (INTEL_GEN(dev_priv) > 6) {
1754 drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n", 1755 drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n",
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 7f45dd7dc3e5..d36e25607435 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -575,7 +575,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
575 * the state of the GPU is known (idle). 575 * the state of the GPU is known (idle).
576 */ 576 */
577 inject_preempt_context(engine); 577 inject_preempt_context(engine);
578 execlists->preempt = true; 578 execlists_set_active(execlists,
579 EXECLISTS_ACTIVE_PREEMPT);
579 goto unlock; 580 goto unlock;
580 } else { 581 } else {
581 /* 582 /*
@@ -683,8 +684,10 @@ done:
683unlock: 684unlock:
684 spin_unlock_irq(&engine->timeline->lock); 685 spin_unlock_irq(&engine->timeline->lock);
685 686
686 if (submit) 687 if (submit) {
688 execlists_set_active(execlists, EXECLISTS_ACTIVE_USER);
687 execlists_submit_ports(engine); 689 execlists_submit_ports(engine);
690 }
688} 691}
689 692
690static void 693static void
@@ -696,6 +699,7 @@ execlist_cancel_port_requests(struct intel_engine_execlists *execlists)
696 while (num_ports-- && port_isset(port)) { 699 while (num_ports-- && port_isset(port)) {
697 struct drm_i915_gem_request *rq = port_request(port); 700 struct drm_i915_gem_request *rq = port_request(port);
698 701
702 GEM_BUG_ON(!execlists->active);
699 execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_PREEMPTED); 703 execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_PREEMPTED);
700 i915_gem_request_put(rq); 704 i915_gem_request_put(rq);
701 705
@@ -730,7 +734,6 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
730 734
731 list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) { 735 list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) {
732 INIT_LIST_HEAD(&rq->priotree.link); 736 INIT_LIST_HEAD(&rq->priotree.link);
733 rq->priotree.priority = INT_MAX;
734 737
735 dma_fence_set_error(&rq->fence, -EIO); 738 dma_fence_set_error(&rq->fence, -EIO);
736 __i915_gem_request_submit(rq); 739 __i915_gem_request_submit(rq);
@@ -861,15 +864,21 @@ static void intel_lrc_irq_handler(unsigned long data)
861 unwind_incomplete_requests(engine); 864 unwind_incomplete_requests(engine);
862 spin_unlock_irq(&engine->timeline->lock); 865 spin_unlock_irq(&engine->timeline->lock);
863 866
864 GEM_BUG_ON(!execlists->preempt); 867 GEM_BUG_ON(!execlists_is_active(execlists,
865 execlists->preempt = false; 868 EXECLISTS_ACTIVE_PREEMPT));
869 execlists_clear_active(execlists,
870 EXECLISTS_ACTIVE_PREEMPT);
866 continue; 871 continue;
867 } 872 }
868 873
869 if (status & GEN8_CTX_STATUS_PREEMPTED && 874 if (status & GEN8_CTX_STATUS_PREEMPTED &&
870 execlists->preempt) 875 execlists_is_active(execlists,
876 EXECLISTS_ACTIVE_PREEMPT))
871 continue; 877 continue;
872 878
879 GEM_BUG_ON(!execlists_is_active(execlists,
880 EXECLISTS_ACTIVE_USER));
881
873 /* Check the context/desc id for this event matches */ 882 /* Check the context/desc id for this event matches */
874 GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id); 883 GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id);
875 884
@@ -881,7 +890,6 @@ static void intel_lrc_irq_handler(unsigned long data)
881 execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); 890 execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
882 891
883 trace_i915_gem_request_out(rq); 892 trace_i915_gem_request_out(rq);
884 rq->priotree.priority = INT_MAX;
885 i915_gem_request_put(rq); 893 i915_gem_request_put(rq);
886 894
887 execlists_port_complete(execlists, port); 895 execlists_port_complete(execlists, port);
@@ -892,6 +900,9 @@ static void intel_lrc_irq_handler(unsigned long data)
892 /* After the final element, the hw should be idle */ 900 /* After the final element, the hw should be idle */
893 GEM_BUG_ON(port_count(port) == 0 && 901 GEM_BUG_ON(port_count(port) == 0 &&
894 !(status & GEN8_CTX_STATUS_ACTIVE_IDLE)); 902 !(status & GEN8_CTX_STATUS_ACTIVE_IDLE));
903 if (port_count(port) == 0)
904 execlists_clear_active(execlists,
905 EXECLISTS_ACTIVE_USER);
895 } 906 }
896 907
897 if (head != execlists->csb_head) { 908 if (head != execlists->csb_head) {
@@ -901,7 +912,7 @@ static void intel_lrc_irq_handler(unsigned long data)
901 } 912 }
902 } 913 }
903 914
904 if (!execlists->preempt) 915 if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT))
905 execlists_dequeue(engine); 916 execlists_dequeue(engine);
906 917
907 intel_uncore_forcewake_put(dev_priv, execlists->fw_domains); 918 intel_uncore_forcewake_put(dev_priv, execlists->fw_domains);
@@ -1460,7 +1471,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
1460 GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift); 1471 GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
1461 clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); 1472 clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
1462 execlists->csb_head = -1; 1473 execlists->csb_head = -1;
1463 execlists->preempt = false; 1474 execlists->active = 0;
1464 1475
1465 /* After a GPU reset, we may have requests to replay */ 1476 /* After a GPU reset, we may have requests to replay */
1466 if (!i915_modparams.enable_guc_submission && execlists->first) 1477 if (!i915_modparams.enable_guc_submission && execlists->first)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c42a65a93b3a..aa12a44e9a76 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3133,7 +3133,11 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev,
3133 struct intel_crtc_state *newstate) 3133 struct intel_crtc_state *newstate)
3134{ 3134{
3135 struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate; 3135 struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate;
3136 struct intel_pipe_wm *b = &intel_crtc->wm.active.ilk; 3136 struct intel_atomic_state *intel_state =
3137 to_intel_atomic_state(newstate->base.state);
3138 const struct intel_crtc_state *oldstate =
3139 intel_atomic_get_old_crtc_state(intel_state, intel_crtc);
3140 const struct intel_pipe_wm *b = &oldstate->wm.ilk.optimal;
3137 int level, max_level = ilk_wm_max_level(to_i915(dev)); 3141 int level, max_level = ilk_wm_max_level(to_i915(dev));
3138 3142
3139 /* 3143 /*
@@ -3142,6 +3146,9 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev,
3142 * and after the vblank. 3146 * and after the vblank.
3143 */ 3147 */
3144 *a = newstate->wm.ilk.optimal; 3148 *a = newstate->wm.ilk.optimal;
3149 if (!newstate->base.active || drm_atomic_crtc_needs_modeset(&newstate->base))
3150 return 0;
3151
3145 a->pipe_enabled |= b->pipe_enabled; 3152 a->pipe_enabled |= b->pipe_enabled;
3146 a->sprites_enabled |= b->sprites_enabled; 3153 a->sprites_enabled |= b->sprites_enabled;
3147 a->sprites_scaled |= b->sprites_scaled; 3154 a->sprites_scaled |= b->sprites_scaled;
@@ -5755,12 +5762,30 @@ void vlv_wm_sanitize(struct drm_i915_private *dev_priv)
5755 mutex_unlock(&dev_priv->wm.wm_mutex); 5762 mutex_unlock(&dev_priv->wm.wm_mutex);
5756} 5763}
5757 5764
5765/*
5766 * FIXME should probably kill this and improve
5767 * the real watermark readout/sanitation instead
5768 */
5769static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv)
5770{
5771 I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN);
5772 I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN);
5773 I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN);
5774
5775 /*
5776 * Don't touch WM1S_LP_EN here.
5777 * Doing so could cause underruns.
5778 */
5779}
5780
5758void ilk_wm_get_hw_state(struct drm_device *dev) 5781void ilk_wm_get_hw_state(struct drm_device *dev)
5759{ 5782{
5760 struct drm_i915_private *dev_priv = to_i915(dev); 5783 struct drm_i915_private *dev_priv = to_i915(dev);
5761 struct ilk_wm_values *hw = &dev_priv->wm.hw; 5784 struct ilk_wm_values *hw = &dev_priv->wm.hw;
5762 struct drm_crtc *crtc; 5785 struct drm_crtc *crtc;
5763 5786
5787 ilk_init_lp_watermarks(dev_priv);
5788
5764 for_each_crtc(dev, crtc) 5789 for_each_crtc(dev, crtc)
5765 ilk_pipe_wm_get_hw_state(crtc); 5790 ilk_pipe_wm_get_hw_state(crtc);
5766 5791
@@ -8207,18 +8232,6 @@ static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv)
8207 } 8232 }
8208} 8233}
8209 8234
8210static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv)
8211{
8212 I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN);
8213 I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN);
8214 I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN);
8215
8216 /*
8217 * Don't touch WM1S_LP_EN here.
8218 * Doing so could cause underruns.
8219 */
8220}
8221
8222static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) 8235static void ilk_init_clock_gating(struct drm_i915_private *dev_priv)
8223{ 8236{
8224 uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; 8237 uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
@@ -8252,8 +8265,6 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv)
8252 (I915_READ(DISP_ARB_CTL) | 8265 (I915_READ(DISP_ARB_CTL) |
8253 DISP_FBC_WM_DIS)); 8266 DISP_FBC_WM_DIS));
8254 8267
8255 ilk_init_lp_watermarks(dev_priv);
8256
8257 /* 8268 /*
8258 * Based on the document from hardware guys the following bits 8269 * Based on the document from hardware guys the following bits
8259 * should be set unconditionally in order to enable FBC. 8270 * should be set unconditionally in order to enable FBC.
@@ -8366,8 +8377,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv)
8366 I915_WRITE(GEN6_GT_MODE, 8377 I915_WRITE(GEN6_GT_MODE,
8367 _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); 8378 _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
8368 8379
8369 ilk_init_lp_watermarks(dev_priv);
8370
8371 I915_WRITE(CACHE_MODE_0, 8380 I915_WRITE(CACHE_MODE_0,
8372 _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); 8381 _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB));
8373 8382
@@ -8594,8 +8603,6 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
8594 I915_GTT_PAGE_SIZE_2M); 8603 I915_GTT_PAGE_SIZE_2M);
8595 enum pipe pipe; 8604 enum pipe pipe;
8596 8605
8597 ilk_init_lp_watermarks(dev_priv);
8598
8599 /* WaSwitchSolVfFArbitrationPriority:bdw */ 8606 /* WaSwitchSolVfFArbitrationPriority:bdw */
8600 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); 8607 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
8601 8608
@@ -8646,8 +8653,6 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
8646 8653
8647static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) 8654static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
8648{ 8655{
8649 ilk_init_lp_watermarks(dev_priv);
8650
8651 /* L3 caching of data atomics doesn't work -- disable it. */ 8656 /* L3 caching of data atomics doesn't work -- disable it. */
8652 I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE); 8657 I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);
8653 I915_WRITE(HSW_ROW_CHICKEN3, 8658 I915_WRITE(HSW_ROW_CHICKEN3,
@@ -8691,10 +8696,6 @@ static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
8691 /* WaSwitchSolVfFArbitrationPriority:hsw */ 8696 /* WaSwitchSolVfFArbitrationPriority:hsw */
8692 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); 8697 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
8693 8698
8694 /* WaRsPkgCStateDisplayPMReq:hsw */
8695 I915_WRITE(CHICKEN_PAR1_1,
8696 I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES);
8697
8698 lpt_init_clock_gating(dev_priv); 8699 lpt_init_clock_gating(dev_priv);
8699} 8700}
8700 8701
@@ -8702,8 +8703,6 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
8702{ 8703{
8703 uint32_t snpcr; 8704 uint32_t snpcr;
8704 8705
8705 ilk_init_lp_watermarks(dev_priv);
8706
8707 I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); 8706 I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE);
8708 8707
8709 /* WaDisableEarlyCull:ivb */ 8708 /* WaDisableEarlyCull:ivb */
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 17186f067408..6a42ed618a28 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -241,9 +241,17 @@ struct intel_engine_execlists {
241 } port[EXECLIST_MAX_PORTS]; 241 } port[EXECLIST_MAX_PORTS];
242 242
243 /** 243 /**
244 * @preempt: are we currently handling a preempting context switch? 244 * @active: is the HW active? We consider the HW as active after
245 * submitting any context for execution and until we have seen the
246 * last context completion event. After that, we do not expect any
247 * more events until we submit, and so can park the HW.
248 *
249 * As we have a small number of different sources from which we feed
250 * the HW, we track the state of each inside a single bitfield.
245 */ 251 */
246 bool preempt; 252 unsigned int active;
253#define EXECLISTS_ACTIVE_USER 0
254#define EXECLISTS_ACTIVE_PREEMPT 1
247 255
248 /** 256 /**
249 * @port_mask: number of execlist ports - 1 257 * @port_mask: number of execlist ports - 1
@@ -525,6 +533,27 @@ struct intel_engine_cs {
525 u32 (*get_cmd_length_mask)(u32 cmd_header); 533 u32 (*get_cmd_length_mask)(u32 cmd_header);
526}; 534};
527 535
536static inline void
537execlists_set_active(struct intel_engine_execlists *execlists,
538 unsigned int bit)
539{
540 __set_bit(bit, (unsigned long *)&execlists->active);
541}
542
543static inline void
544execlists_clear_active(struct intel_engine_execlists *execlists,
545 unsigned int bit)
546{
547 __clear_bit(bit, (unsigned long *)&execlists->active);
548}
549
550static inline bool
551execlists_is_active(const struct intel_engine_execlists *execlists,
552 unsigned int bit)
553{
554 return test_bit(bit, (unsigned long *)&execlists->active);
555}
556
528static inline unsigned int 557static inline unsigned int
529execlists_num_ports(const struct intel_engine_execlists * const execlists) 558execlists_num_ports(const struct intel_engine_execlists * const execlists)
530{ 559{
@@ -538,6 +567,7 @@ execlists_port_complete(struct intel_engine_execlists * const execlists,
538 const unsigned int m = execlists->port_mask; 567 const unsigned int m = execlists->port_mask;
539 568
540 GEM_BUG_ON(port_index(port, execlists) != 0); 569 GEM_BUG_ON(port_index(port, execlists) != 0);
570 GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_USER));
541 571
542 memmove(port, port + 1, m * sizeof(struct execlist_port)); 572 memmove(port, port + 1, m * sizeof(struct execlist_port));
543 memset(port + m, 0, sizeof(struct execlist_port)); 573 memset(port + m, 0, sizeof(struct execlist_port));